1 package org.apache.archiva.repository.scanner;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import junit.framework.TestCase;
23 import org.apache.archiva.configuration.ArchivaConfiguration;
24 import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
25 import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
26 import org.apache.archiva.repository.base.BasicManagedRepository;
27 import org.apache.archiva.repository.base.BasicRemoteRepository;
28 import org.apache.archiva.repository.ManagedRepository;
29 import org.apache.archiva.repository.RemoteRepository;
30 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
31 import org.apache.commons.lang3.SystemUtils;
32 import org.easymock.IMocksControl;
33 import org.junit.Test;
34 import org.junit.runner.RunWith;
35 import org.springframework.beans.BeansException;
36 import org.springframework.beans.factory.BeanFactory;
37 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
38 import org.springframework.beans.factory.ObjectProvider;
39 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
40 import org.springframework.context.ApplicationContext;
41 import org.springframework.context.ApplicationEvent;
42 import org.springframework.context.MessageSourceResolvable;
43 import org.springframework.context.NoSuchMessageException;
44 import org.springframework.core.ResolvableType;
45 import org.springframework.core.env.Environment;
46 import org.springframework.core.io.Resource;
47 import org.springframework.test.context.ContextConfiguration;
49 import javax.inject.Inject;
50 import java.io.IOException;
51 import java.lang.annotation.Annotation;
53 import java.net.URISyntaxException;
54 import java.nio.file.Path;
55 import java.nio.file.Paths;
56 import java.util.Arrays;
57 import java.util.Collections;
58 import java.util.Date;
59 import java.util.HashMap;
60 import java.util.List;
61 import java.util.Locale;
63 import java.util.function.Function;
65 import static org.easymock.EasyMock.*;
68 * RepositoryContentConsumersTest
70 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
71 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } )
72 public class RepositoryContentConsumersTest
77 ApplicationContext applicationContext;
79 protected ManagedRepository createRepository( String id, String name, Path location ) throws IOException {
80 BasicManagedRepository repo = BasicManagedRepository.newFilesystemInstance(id, name, location.getParent().resolve(id));
81 repo.setLocation( location.toAbsolutePath().toUri() );
85 protected RemoteRepository createRemoteRepository( String id, String name, String url ) throws URISyntaxException, IOException {
86 BasicRemoteRepository repo = BasicRemoteRepository.newFilesystemInstance(id, name, Paths.get("remotes"));
87 repo.setLocation( new URI( url ) );
91 private RepositoryContentConsumers lookupRepositoryConsumers()
95 ArchivaConfiguration configuration =
96 applicationContext.getBean( "archivaConfiguration#test-conf", ArchivaConfiguration.class );
98 ArchivaAdministrationStub administrationStub = new ArchivaAdministrationStub( configuration );
100 RepositoryContentConsumers consumerUtilStub = new RepositoryContentConsumersStub( administrationStub );
102 RepositoryContentConsumers consumerUtil =
103 applicationContext.getBean( "repositoryContentConsumers#test", RepositoryContentConsumers.class );
104 ApplicationContext context = new MockApplicationContext( consumerUtil.getAvailableKnownConsumers(), //
105 consumerUtil.getAvailableInvalidConsumers() );
107 consumerUtilStub.setApplicationContext( context );
108 consumerUtilStub.setSelectedInvalidConsumers( consumerUtil.getSelectedInvalidConsumers() );
109 consumerUtilStub.setSelectedKnownConsumers( consumerUtil.getSelectedKnownConsumers() );
110 consumerUtilStub.setArchivaAdministration( administrationStub );
112 assertNotNull( "RepositoryContentConsumers should not be null.", consumerUtilStub );
114 return consumerUtilStub;
118 public void testGetSelectedKnownIds()
121 RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
123 String expectedKnownIds[] =
124 new String[]{ "create-missing-checksums", "validate-checksum", "validate-signature", "index-content",
125 "auto-remove", "auto-rename", "create-archiva-metadata", "duplicate-artifacts" };
126 //update-db-artifact, create-missing-checksums, update-db-repository-metadata,
127 //validate-checksum, validate-signature, index-content, auto-remove, auto-rename,
129 List<String> knownConsumers = consumerutil.getSelectedKnownConsumerIds();
130 assertNotNull( "Known Consumer IDs should not be null", knownConsumers );
131 assertEquals( "Known Consumer IDs.size " + knownConsumers, expectedKnownIds.length, knownConsumers.size() );
133 for ( String expectedId : expectedKnownIds )
135 assertTrue( "Known id [" + expectedId + "] exists.", knownConsumers.contains( expectedId ) );
140 public void testGetSelectedInvalidIds()
143 RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
145 String expectedInvalidIds[] = new String[]{ "update-db-bad-content" };
147 List<String> invalidConsumers = consumerutil.getSelectedInvalidConsumerIds();
148 assertNotNull( "Invalid Consumer IDs should not be null", invalidConsumers );
149 assertEquals( "Invalid Consumer IDs.size", expectedInvalidIds.length, invalidConsumers.size() );
151 for ( String expectedId : expectedInvalidIds )
153 assertTrue( "Invalid id [" + expectedId + "] exists.", invalidConsumers.contains( expectedId ) );
158 public void testGetSelectedKnownConsumerMap()
161 RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
163 String expectedSelectedKnownIds[] =
164 new String[]{ "create-missing-checksums", "validate-checksum", "index-content", "auto-remove",
167 Map<String, KnownRepositoryContentConsumer> knownConsumerMap = consumerutil.getSelectedKnownConsumersMap();
168 assertNotNull( "Known Consumer Map should not be null", knownConsumerMap );
169 assertEquals( "Known Consumer Map.size but " + knownConsumerMap, expectedSelectedKnownIds.length,
170 knownConsumerMap.size() );
172 for ( String expectedId : expectedSelectedKnownIds )
174 KnownRepositoryContentConsumer consumer = knownConsumerMap.get( expectedId );
175 assertNotNull( "Known[" + expectedId + "] should not be null.", consumer );
176 assertEquals( "Known[" + expectedId + "].id", expectedId, consumer.getId() );
181 public void testGetSelectedInvalidConsumerMap()
184 RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
186 String expectedSelectedInvalidIds[] = new String[]{ "update-db-bad-content" };
188 Map<String, InvalidRepositoryContentConsumer> invalidConsumerMap =
189 consumerutil.getSelectedInvalidConsumersMap();
190 assertNotNull( "Invalid Consumer Map should not be null", invalidConsumerMap );
191 assertEquals( "Invalid Consumer Map.size", expectedSelectedInvalidIds.length, invalidConsumerMap.size() );
193 for ( String expectedId : expectedSelectedInvalidIds )
195 InvalidRepositoryContentConsumer consumer = invalidConsumerMap.get( expectedId );
196 assertNotNull( "Known[" + expectedId + "] should not be null.", consumer );
197 assertEquals( "Known[" + expectedId + "].id", expectedId, consumer.getId() );
202 public void testGetAvailableKnownList()
205 RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
207 String expectedKnownIds[] =
208 new String[]{ "update-db-artifact", "create-missing-checksums", "update-db-repository-metadata",
209 "validate-checksum", "index-content", "auto-remove", "auto-rename", "available-but-unselected" };
211 List<KnownRepositoryContentConsumer> knownConsumers = consumerutil.getAvailableKnownConsumers();
212 assertNotNull( "known consumers should not be null.", knownConsumers );
213 assertEquals( "known consumers", expectedKnownIds.length, knownConsumers.size() );
215 List<String> expectedIds = Arrays.asList( expectedKnownIds );
216 for ( KnownRepositoryContentConsumer consumer : knownConsumers )
218 assertTrue( "Consumer [" + consumer.getId() + "] returned by .getAvailableKnownConsumers() is unexpected.",
219 expectedIds.contains( consumer.getId() ) );
224 public void testGetAvailableInvalidList()
227 RepositoryContentConsumers consumerutil = lookupRepositoryConsumers();
229 String expectedInvalidIds[] = new String[]{ "update-db-bad-content", "move-to-trash-then-notify" };
231 List<InvalidRepositoryContentConsumer> invalidConsumers = consumerutil.getAvailableInvalidConsumers();
232 assertNotNull( "invalid consumers should not be null.", invalidConsumers );
233 assertEquals( "invalid consumers", expectedInvalidIds.length, invalidConsumers.size() );
235 List<String> expectedIds = Arrays.asList( expectedInvalidIds );
236 for ( InvalidRepositoryContentConsumer consumer : invalidConsumers )
239 "Consumer [" + consumer.getId() + "] returned by .getAvailableInvalidConsumers() is unexpected.",
240 expectedIds.contains( consumer.getId() ) );
245 public void testExecution()
248 IMocksControl knownControl = createNiceControl();
250 RepositoryContentConsumers consumers = lookupRepositoryConsumers();
251 KnownRepositoryContentConsumer selectedKnownConsumer =
252 knownControl.createMock( KnownRepositoryContentConsumer.class );
254 KnownRepositoryContentConsumer unselectedKnownConsumer =
255 createNiceControl().createMock( KnownRepositoryContentConsumer.class );
257 consumers.setApplicationContext(
258 new MockApplicationContext( Arrays.asList( selectedKnownConsumer, unselectedKnownConsumer ), null ) );
260 consumers.setSelectedKnownConsumers( Collections.singletonList( selectedKnownConsumer ) );
262 IMocksControl invalidControl = createControl();
264 InvalidRepositoryContentConsumer selectedInvalidConsumer =
265 invalidControl.createMock( InvalidRepositoryContentConsumer.class );
267 InvalidRepositoryContentConsumer unselectedInvalidConsumer =
268 createControl().createMock( InvalidRepositoryContentConsumer.class );
270 consumers.setApplicationContext(
271 new MockApplicationContext( null, Arrays.asList( selectedInvalidConsumer, unselectedInvalidConsumer ) ) );
273 consumers.setSelectedInvalidConsumers( Collections.singletonList( selectedInvalidConsumer ) );
275 ManagedRepository repo = createRepository( "id", "name", Paths.get( "target/test-repo" ) );
276 Path testFile = Paths.get( "target/test-repo/path/to/test-file.txt" );
278 Date startTime = new Date( System.currentTimeMillis() );
279 startTime.setTime( 12345678 );
281 selectedKnownConsumer.beginScan( repo, startTime, false );
282 expect( selectedKnownConsumer.getIncludes() ).andReturn( Collections.singletonList( "**/*.txt" ) );
283 selectedKnownConsumer.processFile( _OS( "path/to/test-file.txt" ), false );
285 knownControl.replay();
287 selectedInvalidConsumer.beginScan( repo, startTime, false );
288 invalidControl.replay();
290 consumers.executeConsumers( repo, testFile, true );
292 knownControl.verify();
293 invalidControl.verify();
295 knownControl.reset();
296 invalidControl.reset();
298 Path notIncludedTestFile = Paths.get( "target/test-repo/path/to/test-file.xml" );
300 selectedKnownConsumer.beginScan( repo, startTime, false );
301 expect( selectedKnownConsumer.getExcludes() ).andReturn( Collections.<String>emptyList() );
303 expect( selectedKnownConsumer.getIncludes() ).andReturn( Collections.singletonList( "**/*.txt" ) );
305 knownControl.replay();
307 selectedInvalidConsumer.beginScan( repo, startTime, false );
308 selectedInvalidConsumer.processFile( _OS( "path/to/test-file.xml" ), false );
309 expect( selectedInvalidConsumer.getId() ).andReturn( "invalid" );
310 invalidControl.replay();
312 consumers.executeConsumers( repo, notIncludedTestFile, true );
314 knownControl.verify();
315 invalidControl.verify();
317 knownControl.reset();
318 invalidControl.reset();
320 Path excludedTestFile = Paths.get( "target/test-repo/path/to/test-file.txt" );
322 selectedKnownConsumer.beginScan( repo, startTime, false );
323 expect( selectedKnownConsumer.getExcludes() ).andReturn( Collections.singletonList( "**/test-file.txt" ) );
324 knownControl.replay();
326 selectedInvalidConsumer.beginScan( repo, startTime, false );
327 selectedInvalidConsumer.processFile( _OS( "path/to/test-file.txt" ), false );
328 expect( selectedInvalidConsumer.getId() ).andReturn( "invalid" );
329 invalidControl.replay();
331 consumers.executeConsumers( repo, excludedTestFile, true );
333 knownControl.verify();
334 invalidControl.verify();
338 * Create an OS specific version of the filepath.
339 * Provide path in unix "/" format.
341 private String _OS( String path )
343 if ( SystemUtils.IS_OS_WINDOWS )
345 return path.replace( '/', '\\' );
350 private static <T> Map<String, T> convertToMap( List<T> objects)
352 HashMap<String,T> map = new HashMap<>();
353 for ( T o : objects )
355 map.put( o.toString(), o );
360 private static <T> Function<List<T>,Map<String,T>> getConversionFunction(Class<T> type) {
361 return ts -> convertToMap( ts );
364 public class MockApplicationContext
365 implements ApplicationContext
367 private List<KnownRepositoryContentConsumer> knownRepositoryContentConsumer;
369 private List<InvalidRepositoryContentConsumer> invalidRepositoryContentConsumers;
371 public MockApplicationContext( List<KnownRepositoryContentConsumer> knownRepositoryContentConsumer,
372 List<InvalidRepositoryContentConsumer> invalidRepositoryContentConsumers )
374 this.knownRepositoryContentConsumer = knownRepositoryContentConsumer;
375 this.invalidRepositoryContentConsumers = invalidRepositoryContentConsumers;
379 public String getApplicationName()
385 public AutowireCapableBeanFactory getAutowireCapableBeanFactory()
386 throws IllegalStateException
388 throw new UnsupportedOperationException( "Not supported yet." );
392 public String getDisplayName()
394 throw new UnsupportedOperationException( "Not supported yet." );
398 public String getId()
400 throw new UnsupportedOperationException( "Not supported yet." );
404 public ApplicationContext getParent()
406 throw new UnsupportedOperationException( "Not supported yet." );
410 public long getStartupDate()
412 throw new UnsupportedOperationException( "Not supported yet." );
416 public boolean containsBeanDefinition( String beanName )
418 throw new UnsupportedOperationException( "Not supported yet." );
422 public int getBeanDefinitionCount()
424 throw new UnsupportedOperationException( "Not supported yet." );
428 public String[] getBeanDefinitionNames()
430 throw new UnsupportedOperationException( "Not supported yet." );
434 public String[] getBeanNamesForType( Class type )
436 throw new UnsupportedOperationException( "Not supported yet." );
440 public String[] getBeanNamesForType( Class type, boolean includeNonSingletons, boolean allowEagerInit )
442 throw new UnsupportedOperationException( "Not supported yet." );
446 public <T> T getBean( Class<T> aClass, Object... objects )
447 throws BeansException
449 throw new UnsupportedOperationException( "Not supported yet." );
453 public <T> ObjectProvider<T> getBeanProvider( Class<T> aClass )
459 public <T> ObjectProvider<T> getBeanProvider( ResolvableType resolvableType )
464 @SuppressWarnings( "unchecked" )
466 public <T> Map<String, T> getBeansOfType( Class<T> type )
467 throws BeansException
470 if (type == KnownRepositoryContentConsumer.class) {
471 list = (List<T>) knownRepositoryContentConsumer;
472 } else if (type == InvalidRepositoryContentConsumer.class) {
473 list = (List<T>) invalidRepositoryContentConsumers;
476 return getConversionFunction( type ).apply( list );
478 throw new UnsupportedOperationException( "Should not have been called" );
482 public <T> Map<String, T> getBeansOfType( Class<T> type, boolean includeNonSingletons, boolean allowEagerInit )
483 throws BeansException
485 throw new UnsupportedOperationException( "Not supported yet." );
489 public boolean containsBean( String name )
491 throw new UnsupportedOperationException( "Not supported yet." );
495 public String[] getAliases( String name )
497 throw new UnsupportedOperationException( "Not supported yet." );
501 public Object getBean( String name )
502 throws BeansException
504 throw new UnsupportedOperationException( "Not supported yet." );
508 public <T> T getBean( String name, Class<T> requiredType )
509 throws BeansException
511 throw new UnsupportedOperationException( "Not supported yet." );
515 public Object getBean( String name, Object[] args )
516 throws BeansException
518 throw new UnsupportedOperationException( "Not supported yet." );
522 public Class getType( String name )
523 throws NoSuchBeanDefinitionException
525 throw new UnsupportedOperationException( "Not supported yet." );
529 public Class<?> getType( String s, boolean b ) throws NoSuchBeanDefinitionException
535 public boolean isPrototype( String name )
536 throws NoSuchBeanDefinitionException
538 throw new UnsupportedOperationException( "Not supported yet." );
542 public boolean isSingleton( String name )
543 throws NoSuchBeanDefinitionException
545 throw new UnsupportedOperationException( "Not supported yet." );
549 public boolean isTypeMatch( String name, Class targetType )
550 throws NoSuchBeanDefinitionException
552 throw new UnsupportedOperationException( "Not supported yet." );
556 public boolean containsLocalBean( String name )
558 throw new UnsupportedOperationException( "Not supported yet." );
562 public BeanFactory getParentBeanFactory()
564 throw new UnsupportedOperationException( "Not supported yet." );
568 public String getMessage( String code, Object[] args, String defaultMessage, Locale locale )
570 throw new UnsupportedOperationException( "Not supported yet." );
574 public String getMessage( String code, Object[] args, Locale locale )
575 throws NoSuchMessageException
577 throw new UnsupportedOperationException( "Not supported yet." );
581 public String getMessage( MessageSourceResolvable resolvable, Locale locale )
582 throws NoSuchMessageException
584 throw new UnsupportedOperationException( "Not supported yet." );
588 public void publishEvent( ApplicationEvent event )
590 throw new UnsupportedOperationException( "Not supported yet." );
594 public Resource[] getResources( String locationPattern )
597 throw new UnsupportedOperationException( "Not supported yet." );
601 public ClassLoader getClassLoader()
603 throw new UnsupportedOperationException( "Not supported yet." );
607 public Resource getResource( String location )
609 throw new UnsupportedOperationException( "Not supported yet." );
613 public <T> T getBean( Class<T> tClass )
614 throws BeansException
616 throw new UnsupportedOperationException( "Not supported yet." );
620 public Map<String, Object> getBeansWithAnnotation( Class<? extends Annotation> aClass )
621 throws BeansException
623 throw new UnsupportedOperationException( "Not supported yet." );
627 public <A extends Annotation> A findAnnotationOnBean( String s, Class<A> aClass )
629 throw new UnsupportedOperationException( "Not supported yet." );
633 public Environment getEnvironment()
639 public String[] getBeanNamesForAnnotation( Class<? extends Annotation> aClass )
641 return new String[0];
645 public void publishEvent( Object o )
651 public String[] getBeanNamesForType( ResolvableType resolvableType )
653 return new String[0];
657 public String[] getBeanNamesForType( ResolvableType resolvableType, boolean b, boolean b1 )
659 return new String[0];
663 public boolean isTypeMatch( String s, ResolvableType resolvableType )
664 throws NoSuchBeanDefinitionException