1 package org.apache.archiva.repository.base.group;
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
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
21 import org.apache.archiva.common.filelock.DefaultFileLockManager;
22 import org.apache.archiva.common.filelock.FileLockManager;
23 import org.apache.archiva.common.utils.FileUtils;
24 import org.apache.archiva.common.utils.PathUtil;
25 import org.apache.archiva.components.registry.RegistryException;
26 import org.apache.archiva.configuration.ArchivaConfiguration;
27 import org.apache.archiva.configuration.Configuration;
28 import org.apache.archiva.configuration.IndeterminateConfigurationException;
29 import org.apache.archiva.configuration.RepositoryGroupConfiguration;
30 import org.apache.archiva.indexer.merger.MergedRemoteIndexesScheduler;
31 import org.apache.archiva.repository.EditableRepositoryGroup;
32 import org.apache.archiva.repository.Repository;
33 import org.apache.archiva.repository.RepositoryException;
34 import org.apache.archiva.repository.RepositoryGroup;
35 import org.apache.archiva.repository.RepositoryState;
36 import org.apache.archiva.repository.RepositoryType;
37 import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
38 import org.apache.archiva.repository.base.ConfigurationHandler;
39 import org.apache.archiva.repository.storage.fs.FilesystemStorage;
40 import org.apache.archiva.repository.validation.CheckedResult;
41 import org.apache.archiva.repository.validation.RepositoryValidator;
42 import org.apache.archiva.repository.validation.ValidationError;
43 import org.junit.jupiter.api.BeforeAll;
44 import org.junit.jupiter.api.Test;
45 import org.junit.jupiter.api.extension.ExtendWith;
46 import org.mockito.Mock;
47 import org.mockito.junit.jupiter.MockitoExtension;
48 import org.springframework.test.context.ContextConfiguration;
49 import org.springframework.test.context.junit.jupiter.SpringExtension;
51 import javax.inject.Inject;
52 import javax.inject.Named;
53 import java.io.IOException;
54 import java.nio.file.Files;
55 import java.nio.file.Path;
56 import java.nio.file.Paths;
57 import java.util.ArrayList;
58 import java.util.Iterator;
59 import java.util.List;
62 import static org.apache.archiva.repository.validation.ErrorKeys.ISEMPTY;
63 import static org.junit.jupiter.api.Assertions.*;
64 import static org.mockito.ArgumentMatchers.any;
65 import static org.mockito.ArgumentMatchers.eq;
66 import static org.mockito.Mockito.verify;
69 * @author Martin Stockhammer <martin_s@apache.org>
71 @ExtendWith( {MockitoExtension.class, SpringExtension.class} )
72 @ContextConfiguration( locations = {"classpath*:/META-INF/spring-context.xml", "classpath:/spring-context-group.xml"} )
73 class RepositoryGroupHandlerTest
80 @Named( "repositoryRegistry" )
81 ArchivaRepositoryRegistry repositoryRegistry;
84 ConfigurationHandler configurationHandler;
87 // @Named( "mergedRemoteIndexesScheduler#default" )
88 MergedRemoteIndexesScheduler mergedRemoteIndexesScheduler;
91 List<RepositoryValidator<? extends Repository>> repositoryValidatorList;
94 ArchivaConfiguration archivaConfiguration;
99 private static void initialize() {
100 Path baseDir = Paths.get( FileUtils.getBasedir( ) );
101 Path config = baseDir.resolve( "src/test/resources/archiva-group.xml" );
102 if ( Files.exists( config ) )
104 Path destConfig = baseDir.resolve( "target/test-classes/archiva-group.xml" );
107 Files.copy( config, destConfig );
109 catch ( IOException e )
111 System.err.println( "Could not copy file: " + e.getMessage( ) );
116 // Helper method that removes a group from the configuration
117 private void removeGroupFromConfig(String groupId) {
118 Configuration configuration = configurationHandler.getBaseConfiguration( );
119 Iterator<RepositoryGroupConfiguration> groupIter = configuration.getRepositoryGroups().iterator();
120 while(groupIter.hasNext()) {
121 RepositoryGroupConfiguration group = groupIter.next( );
122 if (groupId.equals(group.getId())) {
129 configurationHandler.save( configuration );
131 catch ( Throwable e )
133 System.err.println( "Could not remove repo group from config "+groupId );
137 private boolean hasGroupInConfig(String groupId) {
138 assertNotNull( configurationHandler.getBaseConfiguration( ).getRepositoryGroups( ) );
139 return configurationHandler.getBaseConfiguration( ).getRepositoryGroups( ).stream( ).anyMatch( g -> g != null && groupId.equals( g.getId( ) ) ) ;
143 private RepositoryGroupHandler createHandler( )
145 RepositoryGroupHandler groupHandler = new RepositoryGroupHandler( repositoryRegistry, configurationHandler, mergedRemoteIndexesScheduler, repositoryValidatorList );
146 groupHandler.init( );
150 private Path getRepoBaseDir() throws IOException
152 if (repoBaseDir==null) {
153 this.repoBaseDir = archivaConfiguration.getRepositoryBaseDir( ).resolve( "group" );
154 Files.createDirectories( this.repoBaseDir );
161 protected EditableRepositoryGroup createRepository( String id, String name, Path location ) throws IOException
163 FileLockManager lockManager = new DefaultFileLockManager();
164 FilesystemStorage storage = new FilesystemStorage(location.toAbsolutePath(), lockManager);
165 BasicRepositoryGroup repo = new BasicRepositoryGroup(id, name, storage);
166 repo.setLocation( location.toAbsolutePath().toUri());
170 protected EditableRepositoryGroup createRepository( String id, String name) throws IOException
172 Path dir = getRepoBaseDir( ).resolve( id );
173 Files.createDirectories( dir );
174 return createRepository( id, name, dir );
179 void initializeFromConfig( )
181 RepositoryGroupHandler groupHandler = createHandler( );
182 groupHandler.initializeFromConfig( );
183 assertEquals( 1, groupHandler.getAll( ).size( ) );
184 assertNotNull( groupHandler.get( "test-group-01" ).getRepositories( ) );
185 assertEquals( "internal", groupHandler.get( "test-group-01" ).getRepositories( ).get( 0 ).getId( ) );
189 void activateRepository( ) throws RepositoryException
191 String id = "test-group-02";
192 RepositoryGroupHandler groupHandler = createHandler( );
193 RepositoryGroup repo = groupHandler.newInstance( RepositoryType.MAVEN, id );
194 groupHandler.activateRepository( repo );
195 verify( mergedRemoteIndexesScheduler ).schedule( eq( repo ), any( ) );
196 assertEquals( RepositoryState.INITIALIZED, repo.getLastState( ) );
197 assertFalse(hasGroupInConfig( id ));
201 void newInstancesFromConfig( )
203 RepositoryGroupHandler groupHandler = new RepositoryGroupHandler( repositoryRegistry, configurationHandler, mergedRemoteIndexesScheduler, repositoryValidatorList );
204 Map<String, RepositoryGroup> instances = groupHandler.newInstancesFromConfig( );
205 assertFalse( groupHandler.hasRepository( "test-group-01" ) );
206 assertTrue( instances.containsKey( "test-group-01" ) );
207 assertEquals( RepositoryState.REFERENCES_SET, instances.get( "test-group-01" ).getLastState( ) );
211 void newInstance( ) throws RepositoryException
213 String id = "test-group-03";
214 RepositoryGroupHandler groupHandler = createHandler( );
215 RepositoryGroup instance = groupHandler.newInstance( RepositoryType.MAVEN, id );
216 assertNotNull( instance );
217 assertEquals( id, instance.getId( ) );
218 assertFalse( groupHandler.hasRepository( id ) );
219 assertEquals( RepositoryState.REFERENCES_SET, instance.getLastState( ) );
220 assertFalse( hasGroupInConfig( id ) );
225 void put( ) throws IOException, RepositoryException
227 final String id = "test-group-04";
230 RepositoryGroupHandler groupHandler = createHandler( );
231 EditableRepositoryGroup repositoryGroup = createRepository( id, "n-"+id );
232 groupHandler.put( repositoryGroup );
233 RepositoryGroup storedGroup = groupHandler.get( id );
234 assertNotNull( storedGroup );
235 assertEquals( id, storedGroup.getId( ) );
236 assertEquals( "n-"+id, storedGroup.getName( ) );
238 EditableRepositoryGroup repositoryGroup2 = createRepository( id, "n2-"+id );
239 groupHandler.put( repositoryGroup2 );
240 storedGroup = groupHandler.get( id );
241 assertNotNull( storedGroup );
242 assertEquals( id, storedGroup.getId( ) );
243 assertEquals( "n2-"+id, storedGroup.getName( ) );
245 assertTrue( hasGroupInConfig( id ));
247 removeGroupFromConfig( id );
252 void putWithConfiguration( ) throws RepositoryException
254 String id = "test-group-05";
258 RepositoryGroupHandler groupHandler = createHandler( );
259 RepositoryGroupConfiguration configuration = new RepositoryGroupConfiguration( );
260 configuration.setId( id );
261 configuration.setName( "n-" + id );
262 ArrayList<String> repos = new ArrayList<>( );
263 repos.add( "internal" );
264 configuration.setRepositories( repos );
265 groupHandler.put( configuration );
267 RepositoryGroup repo = groupHandler.get( id );
268 assertNotNull( repo );
269 assertEquals( id, repo.getId( ) );
270 assertEquals( "n-" + id, repo.getName( ) );
272 assertNotNull( repo.getRepositories( ) );
273 assertEquals( 1, repo.getRepositories( ).size( ) );
274 assertEquals( "internal", repo.getRepositories( ).get( 0 ).getId( ) );
275 assertTrue( hasGroupInConfig( id ) );
279 removeGroupFromConfig( id );
284 void testPutWithoutRegister( ) throws RepositoryException
286 RepositoryGroupHandler groupHandler = createHandler( );
287 Configuration aCfg = new Configuration( );
288 RepositoryGroupConfiguration configuration = new RepositoryGroupConfiguration( );
289 final String id = "test-group-06";
290 configuration.setId( id );
291 configuration.setName( "n-"+id );
292 ArrayList<String> repos = new ArrayList<>( );
293 repos.add( "internal" );
294 configuration.setRepositories( repos );
295 groupHandler.put( configuration, aCfg );
297 RepositoryGroup repo = groupHandler.get( id );
299 assertFalse( hasGroupInConfig( id ) );
300 assertTrue( aCfg.getRepositoryGroups( ).stream( ).anyMatch( g -> g!=null && id.equals( g.getId( ) ) ) );
305 void putWithCheck_invalid( ) throws RepositoryException
307 final String id = "test-group-07";
308 final String name = "n-"+id;
311 RepositoryGroupHandler groupHandler = createHandler( );
312 BasicRepositoryGroupValidator checker = new BasicRepositoryGroupValidator( configurationHandler );
313 RepositoryGroupConfiguration configuration = new RepositoryGroupConfiguration( );
314 configuration.setId( "" );
315 configuration.setName( name );
316 ArrayList<String> repos = new ArrayList<>( );
317 repos.add( "internal" );
318 configuration.setRepositories( repos );
319 CheckedResult<RepositoryGroup, Map<String, List<ValidationError>>> result = groupHandler.putWithCheck( configuration, checker );
320 assertNull( groupHandler.get( id ) );
321 assertNotNull( result.getResult( ) );
322 assertNotNull( result.getResult( ).get( "id" ) );
323 assertEquals( 1, result.getResult( ).get( "id" ).size( ) );
324 assertEquals( ISEMPTY, result.getResult( ).get( "id" ).get( 0 ).getType( ) );
325 assertFalse( hasGroupInConfig( id ) );
326 assertFalse( hasGroupInConfig( "" ) );
329 removeGroupFromConfig( id );
334 void remove( ) throws RepositoryException
336 RepositoryGroupHandler groupHandler = createHandler( );
337 RepositoryGroupConfiguration configuration = new RepositoryGroupConfiguration( );
338 final String id = "test-group-08";
339 configuration.setId( id );
340 configuration.setName( "n-"+id );
341 groupHandler.put( configuration );
342 assertTrue( hasGroupInConfig( id ) );
343 assertNotNull( groupHandler.get( id ) );
344 groupHandler.remove( id );
345 assertNull( groupHandler.get( id ) );
346 assertFalse( hasGroupInConfig( id ) );
350 void removeWithoutSave( ) throws RepositoryException
352 RepositoryGroupHandler groupHandler = createHandler( );
353 Configuration aCfg = new Configuration( );
354 RepositoryGroupConfiguration configuration = new RepositoryGroupConfiguration( );
355 final String id = "test-group-09";
356 configuration.setId( id );
357 configuration.setName( "n-"+id );
358 ArrayList<String> repos = new ArrayList<>( );
359 repos.add( "internal" );
360 configuration.setRepositories( repos );
361 groupHandler.put( configuration, aCfg );
362 assertTrue( aCfg.getRepositoryGroups( ).stream( ).anyMatch( g -> g != null && id.equals( g.getId( ) ) ) );
363 groupHandler.remove( id, aCfg );
364 assertNull( groupHandler.get( id ) );
365 assertTrue( aCfg.getRepositoryGroups( ).stream( ).noneMatch( g -> g != null && id.equals( g.getId( ) ) ) );
366 assertNull( groupHandler.get( id ) );
372 void validateRepository( ) throws IOException
374 RepositoryGroupHandler groupHandler = createHandler( );
375 final String id = "test-group-10";
376 EditableRepositoryGroup repositoryGroup = createRepository( id, "n-"+id );
377 repositoryGroup.setMergedIndexTTL( 5 );
378 CheckedResult<RepositoryGroup, Map<String, List<ValidationError>>> result = groupHandler.validateRepository( repositoryGroup );
379 assertNotNull( result );
380 assertEquals( 0, result.getResult( ).size( ) );
382 repositoryGroup = createRepository( id, "n-test-group-10###" );
383 result = groupHandler.validateRepository( repositoryGroup );
384 assertNotNull( result );
385 assertEquals( 2, result.getResult( ).size( ) );
386 assertNotNull( result.getResult().get( "merged_index_ttl" ) );
387 assertNotNull( result.getResult().get( "name" ) );
392 void validateRepositoryIfExisting( ) throws IOException, RepositoryException
394 final String id = "test-group-11";
397 RepositoryGroupHandler groupHandler = createHandler( );
398 EditableRepositoryGroup repositoryGroup = createRepository( id, "n-" + id );
399 repositoryGroup.setMergedIndexTTL( 5 );
400 groupHandler.put( repositoryGroup );
401 CheckedResult<RepositoryGroup, Map<String, List<ValidationError>>> result = groupHandler.validateRepository( repositoryGroup );
402 assertNotNull( result );
403 assertEquals( 1, result.getResult( ).size( ) );
406 removeGroupFromConfig( id );
412 void validateRepositoryForUpdate( ) throws IOException, RepositoryException
414 final String id = "test-group-12";
417 RepositoryGroupHandler groupHandler = createHandler( );
418 EditableRepositoryGroup repositoryGroup = createRepository( id, "n-" + id );
419 repositoryGroup.setMergedIndexTTL( 5 );
420 groupHandler.put( repositoryGroup );
421 CheckedResult<RepositoryGroup, Map<String, List<ValidationError>>> result = groupHandler.validateRepositoryForUpdate( repositoryGroup );
422 assertNotNull( result );
423 assertEquals( 0, result.getResult( ).size( ) );
426 removeGroupFromConfig( id );
431 void has( ) throws IOException, RepositoryException
433 final String id = "test-group-13";
436 RepositoryGroupHandler groupHandler = createHandler( );
437 EditableRepositoryGroup repositoryGroup = createRepository( id, "n-" + id );
438 repositoryGroup.setMergedIndexTTL( 5 );
439 assertFalse( groupHandler.hasRepository( id ) );
440 groupHandler.put( repositoryGroup );
441 assertTrue( groupHandler.hasRepository( id ) );
444 removeGroupFromConfig( id );