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.managed.BasicManagedRepository;
27 import org.apache.archiva.repository.base.remote.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 <T> ObjectProvider<T> getBeanProvider( Class<T> aClass, boolean b )
440 public <T> ObjectProvider<T> getBeanProvider( ResolvableType resolvableType, boolean b )
446 public String[] getBeanNamesForType( Class type )
448 throw new UnsupportedOperationException( "Not supported yet." );
452 public String[] getBeanNamesForType( Class type, boolean includeNonSingletons, boolean allowEagerInit )
454 throw new UnsupportedOperationException( "Not supported yet." );
458 public <T> T getBean( Class<T> aClass, Object... objects )
459 throws BeansException
461 throw new UnsupportedOperationException( "Not supported yet." );
465 public <T> ObjectProvider<T> getBeanProvider( Class<T> aClass )
471 public <T> ObjectProvider<T> getBeanProvider( ResolvableType resolvableType )
476 @SuppressWarnings( "unchecked" )
478 public <T> Map<String, T> getBeansOfType( Class<T> type )
479 throws BeansException
482 if (type == KnownRepositoryContentConsumer.class) {
483 list = (List<T>) knownRepositoryContentConsumer;
484 } else if (type == InvalidRepositoryContentConsumer.class) {
485 list = (List<T>) invalidRepositoryContentConsumers;
488 return getConversionFunction( type ).apply( list );
490 throw new UnsupportedOperationException( "Should not have been called" );
494 public <T> Map<String, T> getBeansOfType( Class<T> type, boolean includeNonSingletons, boolean allowEagerInit )
495 throws BeansException
497 throw new UnsupportedOperationException( "Not supported yet." );
501 public boolean containsBean( String name )
503 throw new UnsupportedOperationException( "Not supported yet." );
507 public String[] getAliases( String name )
509 throw new UnsupportedOperationException( "Not supported yet." );
513 public Object getBean( String name )
514 throws BeansException
516 throw new UnsupportedOperationException( "Not supported yet." );
520 public <T> T getBean( String name, Class<T> requiredType )
521 throws BeansException
523 throw new UnsupportedOperationException( "Not supported yet." );
527 public Object getBean( String name, Object[] args )
528 throws BeansException
530 throw new UnsupportedOperationException( "Not supported yet." );
534 public Class getType( String name )
535 throws NoSuchBeanDefinitionException
537 throw new UnsupportedOperationException( "Not supported yet." );
541 public Class<?> getType( String s, boolean b ) throws NoSuchBeanDefinitionException
547 public boolean isPrototype( String name )
548 throws NoSuchBeanDefinitionException
550 throw new UnsupportedOperationException( "Not supported yet." );
554 public boolean isSingleton( String name )
555 throws NoSuchBeanDefinitionException
557 throw new UnsupportedOperationException( "Not supported yet." );
561 public boolean isTypeMatch( String name, Class targetType )
562 throws NoSuchBeanDefinitionException
564 throw new UnsupportedOperationException( "Not supported yet." );
568 public boolean containsLocalBean( String name )
570 throw new UnsupportedOperationException( "Not supported yet." );
574 public BeanFactory getParentBeanFactory()
576 throw new UnsupportedOperationException( "Not supported yet." );
580 public String getMessage( String code, Object[] args, String defaultMessage, Locale locale )
582 throw new UnsupportedOperationException( "Not supported yet." );
586 public String getMessage( String code, Object[] args, Locale locale )
587 throws NoSuchMessageException
589 throw new UnsupportedOperationException( "Not supported yet." );
593 public String getMessage( MessageSourceResolvable resolvable, Locale locale )
594 throws NoSuchMessageException
596 throw new UnsupportedOperationException( "Not supported yet." );
600 public void publishEvent( ApplicationEvent event )
602 throw new UnsupportedOperationException( "Not supported yet." );
606 public Resource[] getResources( String locationPattern )
609 throw new UnsupportedOperationException( "Not supported yet." );
613 public ClassLoader getClassLoader()
615 throw new UnsupportedOperationException( "Not supported yet." );
619 public Resource getResource( String location )
621 throw new UnsupportedOperationException( "Not supported yet." );
625 public <T> T getBean( Class<T> tClass )
626 throws BeansException
628 throw new UnsupportedOperationException( "Not supported yet." );
632 public Map<String, Object> getBeansWithAnnotation( Class<? extends Annotation> aClass )
633 throws BeansException
635 throw new UnsupportedOperationException( "Not supported yet." );
639 public <A extends Annotation> A findAnnotationOnBean( String s, Class<A> aClass )
641 throw new UnsupportedOperationException( "Not supported yet." );
645 public Environment getEnvironment()
651 public String[] getBeanNamesForAnnotation( Class<? extends Annotation> aClass )
653 return new String[0];
657 public void publishEvent( Object o )
663 public String[] getBeanNamesForType( ResolvableType resolvableType )
665 return new String[0];
669 public String[] getBeanNamesForType( ResolvableType resolvableType, boolean b, boolean b1 )
671 return new String[0];
675 public boolean isTypeMatch( String s, ResolvableType resolvableType )
676 throws NoSuchBeanDefinitionException