]> source.dussan.org Git - archiva.git/blob
80172e294985c6386b72f95695c00fc5be277d8c
[archiva.git] /
1 package org.apache.archiva.rest.services;
2 /*
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
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
18  * under the License.
19  */
20
21
22 import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
23 import org.apache.archiva.admin.model.beans.ManagedRepository;
24 import org.apache.archiva.redback.rest.api.services.RedbackServiceException;
25 import org.apache.archiva.redback.rest.services.AbstractRestServicesTest;
26 import org.apache.archiva.rest.api.services.ArchivaAdministrationService;
27 import org.apache.archiva.rest.api.services.ArchivaRestServiceException;
28 import org.apache.archiva.rest.api.services.BrowseService;
29 import org.apache.archiva.rest.api.services.CommonServices;
30 import org.apache.archiva.rest.api.services.ManagedRepositoriesService;
31 import org.apache.archiva.rest.api.services.MergeRepositoriesService;
32 import org.apache.archiva.rest.api.services.NetworkProxyService;
33 import org.apache.archiva.rest.api.services.PingService;
34 import org.apache.archiva.rest.api.services.PluginsService;
35 import org.apache.archiva.rest.api.services.ProxyConnectorRuleService;
36 import org.apache.archiva.rest.api.services.ProxyConnectorService;
37 import org.apache.archiva.rest.api.services.RedbackRuntimeConfigurationService;
38 import org.apache.archiva.rest.api.services.RemoteRepositoriesService;
39 import org.apache.archiva.rest.api.services.RepositoriesService;
40 import org.apache.archiva.rest.api.services.RepositoryGroupService;
41 import org.apache.archiva.rest.api.services.SearchService;
42 import org.apache.archiva.security.common.ArchivaRoleConstants;
43 import org.apache.archiva.test.utils.ArchivaBlockJUnit4ClassRunner;
44 import org.apache.commons.io.FileUtils;
45 import org.apache.commons.lang3.StringUtils;
46 import org.apache.cxf.jaxrs.client.JAXRSClientFactory;
47 import org.apache.cxf.jaxrs.client.WebClient;
48 import org.junit.After;
49 import org.junit.Assume;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.runner.RunWith;
53 import org.slf4j.LoggerFactory;
54
55 import javax.ws.rs.core.MediaType;
56 import java.io.IOException;
57 import java.nio.file.Files;
58 import java.nio.file.Path;
59 import java.nio.file.Paths;
60 import java.time.LocalTime;
61 import java.util.Collections;
62 import java.util.Date;
63 import java.util.Locale;
64 import java.util.concurrent.atomic.AtomicReference;
65 import java.util.function.Function;
66
67 /**
68  * @author Olivier Lamy
69  */
70 @RunWith(ArchivaBlockJUnit4ClassRunner.class)
71 public abstract class AbstractArchivaRestTest
72     extends AbstractRestServicesTest
73 {
74     private AtomicReference<Path> projectDir = new AtomicReference<>();
75     private AtomicReference<Path> appServerBase = new AtomicReference<>( );
76     private AtomicReference<Path> basePath = new AtomicReference<>( );
77
78     private boolean reuseServer = true;
79
80
81     protected void setReuseServer(boolean value) {
82         this.reuseServer = value;
83     }
84
85     protected boolean isReuseServer() {
86         return this.reuseServer;
87     }
88
89     /*
90      * Used by tryAssert to allow to throw exceptions in the lambda expression.
91      */
92     @FunctionalInterface
93     protected interface AssertFunction
94     {
95         void accept( ) throws Exception;
96     }
97
98     protected void tryAssert( AssertFunction func ) throws Exception
99     {
100         tryAssert( func, 10, 500 );
101     }
102
103     /*
104      * Runs the assert method until the assert is successful or the number of retries
105      * is reached. This is needed because the JCR Oak index update is asynchronous, so updates
106      * may not be visible immediately after the modification.
107      */
108     private void tryAssert( AssertFunction func, int retries, int sleepMillis ) throws Exception
109     {
110         Throwable t = null;
111         int retry = retries;
112         while ( retry-- > 0 )
113         {
114             try
115             {
116                 func.accept( );
117                 return;
118             }
119             catch ( Exception | AssertionError e )
120             {
121                 t = e;
122                 Thread.currentThread( ).sleep( sleepMillis );
123                 log.warn( "Retrying assert {}: {}", retry, e.getMessage( ) );
124             }
125         }
126         log.warn( "Retries: {}, Exception: {}", retry, t.getMessage( ) );
127         if ( retry <= 0 && t != null )
128         {
129             if ( t instanceof RuntimeException )
130             {
131                 throw (RuntimeException) t;
132             }
133             else if ( t instanceof Exception )
134             {
135                 throw (Exception) t;
136             }
137             else if ( t instanceof Error )
138             {
139                 throw (Error) t;
140             }
141         }
142     }
143
144     // START SNIPPET: authz-header
145     // guest with an empty password
146     public static String guestAuthzHeader =
147         "Basic " + org.apache.cxf.common.util.Base64Utility.encode( ( "guest" + ":" ).getBytes() );
148
149     // with an other login/password
150     //public String authzHeader =
151     //    "Basic " + org.apache.cxf.common.util.Base64Utility.encode( ( "login" + ":password" ).getBytes() );
152
153     // END SNIPPET: authz-header
154
155     Path getAppserverBase() {
156         if (appServerBase.get()==null) {
157             String basePath = System.getProperty( "appserver.base" );
158             final Path appserverPath;
159             if (StringUtils.isNotEmpty( basePath )) {
160                 appserverPath = Paths.get( basePath ).toAbsolutePath( );
161             } else {
162                 appserverPath = getBasedir( ).resolve( "target" ).resolve( "appserver-base-" + LocalTime.now( ).toSecondOfDay( ) );
163             }
164             appServerBase.compareAndSet( null, appserverPath );
165         }
166         return appServerBase.get();
167     }
168
169     @BeforeClass
170     public static void checkRepo()
171     {
172         Assume.assumeFalse("Test is ignored, because path to appserver contains whitespace characters!", System.getProperty( "appserver.base" ).contains( " " ) );
173         // skygo: was not possible to fix path in this particular module
174         // Skip test if not in proper folder , otherwise test are not fair coz repository
175         // cannot have space in their name.
176     }
177
178     @Override
179     @Before
180     public void startServer()
181         throws Exception
182     {
183         if ( (!isReuseServer()) || (isReuseServer() && !isServerRunning())) {
184             log.info("Starting new server reuse={}, running={}, instance={}, server={}", isReuseServer(), isServerRunning(), this.hashCode(), getServer()==null ? "" : getServer().hashCode());
185             Path appServerBase = getAppserverBase( );
186
187             removeAppsubFolder(appServerBase, "jcr");
188             removeAppsubFolder(appServerBase, "conf");
189             removeAppsubFolder(appServerBase, "data");
190             super.startServer();
191         } else {
192             log.info("Reusing running server instance reuse={}, running={}", isReuseServer(), isServerRunning());
193         }
194     }
195
196     @Override
197     @After
198     public void stopServer()
199             throws Exception
200     {
201         if ( !isReuseServer() )
202         {
203             log.info("Stopping server reuse={}, running={}, instance={}, server={}", isReuseServer(), isServerRunning(), this.hashCode(), getServer()==null ? "" : getServer().hashCode());
204             super.stopServer();
205         } else {
206             log.info("Server not stopping reuse={}, running={}", isReuseServer(), isServerRunning());
207         }
208     }
209
210
211     private void removeAppsubFolder( Path appServerBase, String folder )
212         throws Exception
213     {
214         Path directory = appServerBase.resolve( folder );
215         if ( Files.exists(directory) )
216         {
217             org.apache.archiva.common.utils.FileUtils.deleteDirectory( directory );
218         }
219     }
220
221     @Override
222     protected String getSpringConfigLocation()
223     {
224         return "classpath*:META-INF/spring-context.xml,classpath:META-INF/spring-context-test.xml";
225     }
226
227     @Override
228     protected String getRestServicesPath()
229     {
230         return "restServices";
231     }
232
233     protected RepositoriesService getRepositoriesService()
234     {
235         return getRepositoriesService( null );
236     }
237
238     protected <T> T getService( Class<T> clazz, String authzHeader )
239     {
240         T service = JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/", clazz,
241                                                Collections.singletonList( new JacksonJaxbJsonProvider() ) );
242
243         if ( authzHeader != null )
244         {
245             WebClient.client( service ).header( "Authorization", authzHeader );
246         }
247         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
248         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 100000000 );
249         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
250         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
251         return service;
252     }
253
254     protected ProxyConnectorRuleService getProxyConnectorRuleService( String authzHeader )
255     {
256         return getService( ProxyConnectorRuleService.class, authzHeader );
257     }
258
259     protected MergeRepositoriesService getMergeRepositoriesService( String authzHeader )
260     {
261         return getService( MergeRepositoriesService.class, authzHeader );
262     }
263
264     protected RepositoriesService getRepositoriesService( String authzHeader )
265     {
266         return getService( RepositoriesService.class, authzHeader );
267
268     }
269
270     protected ManagedRepositoriesService getManagedRepositoriesService( String authzHeader )
271     {
272         return getService( ManagedRepositoriesService.class, authzHeader );
273     }
274
275     protected PingService getPingService()
276     {
277         return getService( PingService.class, null );
278     }
279     
280     protected PluginsService getPluginsService()
281     {
282         PluginsService service = getService( PluginsService.class, null );
283         WebClient.client( service ).accept( MediaType.TEXT_PLAIN );
284         WebClient.client( service ).type( MediaType.TEXT_PLAIN );
285         return service;
286     }
287
288     protected RemoteRepositoriesService getRemoteRepositoriesService()
289     {
290         return getService( RemoteRepositoriesService.class, null );
291
292
293     }
294
295     protected RepositoryGroupService getRepositoryGroupService()
296     {
297         return JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
298                                           RepositoryGroupService.class,
299                                           Collections.singletonList( new JacksonJaxbJsonProvider() ) );
300     }
301
302     protected ProxyConnectorService getProxyConnectorService()
303     {
304         ProxyConnectorService service =
305             JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
306                                        ProxyConnectorService.class,
307                                        Collections.singletonList( new JacksonJaxbJsonProvider() ) );
308
309         WebClient.client( service ).header( "Authorization", authorizationHeader );
310         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
311         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 300000 );
312         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
313         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
314         return service;
315     }
316
317     protected NetworkProxyService getNetworkProxyService()
318     {
319         NetworkProxyService service =
320             JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
321                                        NetworkProxyService.class,
322                                        Collections.singletonList( new JacksonJaxbJsonProvider() ) );
323
324         WebClient.client( service ).header( "Authorization", authorizationHeader );
325         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
326         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 300000 );
327         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
328         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
329         return service;
330     }
331
332     protected ArchivaAdministrationService getArchivaAdministrationService()
333     {
334         ArchivaAdministrationService service =
335             JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
336                                        ArchivaAdministrationService.class,
337                                        Collections.singletonList( new JacksonJaxbJsonProvider() ) );
338
339         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
340         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
341
342         WebClient.client( service ).header( "Authorization", authorizationHeader );
343         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
344
345         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 300000 );
346         return service;
347     }
348
349     protected RedbackRuntimeConfigurationService getRedbackRuntimeConfigurationService()
350     {
351         RedbackRuntimeConfigurationService service =
352             JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
353                                        RedbackRuntimeConfigurationService.class,
354                                        Collections.singletonList( new JacksonJaxbJsonProvider() ) );
355
356         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
357         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
358
359         WebClient.client( service ).header( "Authorization", authorizationHeader );
360         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
361         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 300000 );
362         return service;
363     }
364
365     protected BrowseService getBrowseService( String authzHeader, boolean useXml )
366     {
367         // START SNIPPET: cxf-browseservice-creation
368         BrowseService service =
369             JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
370                                        BrowseService.class,
371                                        Collections.singletonList( new JacksonJaxbJsonProvider() ) );
372         // to add authentification
373         if ( authzHeader != null )
374         {
375             WebClient.client( service ).header( "Authorization", authzHeader );
376         }
377         // Set the Referer header to your archiva server url
378         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
379
380         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 100000000 );
381         if ( useXml )
382         {
383             WebClient.client( service ).accept( MediaType.APPLICATION_XML_TYPE );
384             WebClient.client( service ).type( MediaType.APPLICATION_XML_TYPE );
385         }
386         else
387         {
388             WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
389             WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
390         }
391         return service;
392         // END SNIPPET: cxf-browseservice-creation
393
394     }
395
396     protected SearchService getSearchService( String authzHeader )
397     {
398         // START SNIPPET: cxf-searchservice-creation        
399         SearchService service =
400             JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
401                                        SearchService.class,
402                                        Collections.singletonList( new JacksonJaxbJsonProvider() ) );
403         // to add authentification
404         if ( authzHeader != null )
405         {
406             WebClient.client( service ).header( "Authorization", authzHeader );
407         }
408         // Set the Referer header to your archiva server url
409         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
410         // to configure read timeout
411         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 100000000 );
412         // if you want to use json as exchange format xml is supported too
413         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
414         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
415         return service;
416         // END SNIPPET: cxf-searchservice-creation
417
418     }
419
420     protected CommonServices getCommonServices( String authzHeader )
421     {
422         CommonServices service =
423             JAXRSClientFactory.create( getBaseUrl() + "/" + getRestServicesPath() + "/archivaServices/",
424                                        CommonServices.class,
425                                        Collections.singletonList( new JacksonJaxbJsonProvider() ) );
426
427         if ( authzHeader != null )
428         {
429             WebClient.client( service ).header( "Authorization", authzHeader );
430         }
431         WebClient.client(service).header("Referer","http://localhost:"+getServerPort());
432         WebClient.getConfig( service ).getHttpConduit().getClient().setReceiveTimeout( 100000000 );
433         WebClient.client( service ).accept( MediaType.APPLICATION_JSON_TYPE );
434         WebClient.client( service ).type( MediaType.APPLICATION_JSON_TYPE );
435         return service;
436     }
437
438     protected ManagedRepository getTestManagedRepository()
439     {
440         String location = getAppserverBase().resolve( "data/repositories/test-repo" ).toAbsolutePath().toString();
441         return new ManagedRepository( Locale.getDefault(),  "TEST", "test", location, "default", true, true, false, "2 * * * * ?", null,
442                                       false, 2, 3, true, false, "my nice repo", false );
443
444     }
445
446     protected String getBaseUrl()
447     {
448         String baseUrlSysProps = System.getProperty( "archiva.baseRestUrl" );
449         return StringUtils.isBlank( baseUrlSysProps ) ? "http://localhost:" + getServerPort() : baseUrlSysProps;
450     }
451
452     protected Path getProjectDirectory() {
453         if ( projectDir.get()==null) {
454             String propVal = System.getProperty("mvn.project.base.dir");
455             Path newVal;
456             if (StringUtils.isEmpty(propVal)) {
457                 newVal = Paths.get("").toAbsolutePath();
458             } else {
459                 newVal = Paths.get(propVal).toAbsolutePath();
460             }
461             projectDir.compareAndSet(null, newVal);
462         }
463         return projectDir.get();
464     }
465
466     //-----------------------------------------------------
467     // utilities to create repos for testing
468     //-----------------------------------------------------
469
470     static final String TARGET_REPO_ID = "test-copy-target";
471
472     static final String SOURCE_REPO_ID = "test-origin-repo";
473
474     protected void initSourceTargetRepo()
475         throws Exception
476     {
477         Path targetRepo = getAppserverBase().resolve("data/repositories/test-repo-copy" );
478         if ( Files.exists(targetRepo) )
479         {
480             org.apache.archiva.common.utils.FileUtils.deleteDirectory( targetRepo );
481         }
482         assertFalse( Files.exists(targetRepo) );
483         Files.createDirectories( targetRepo );
484
485         if ( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( TARGET_REPO_ID ) != null )
486         {
487             getManagedRepositoriesService( authorizationHeader ).deleteManagedRepository( TARGET_REPO_ID, true );
488             assertNull( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( TARGET_REPO_ID ) );
489         }
490         ManagedRepository managedRepository = getTestManagedRepository();
491         managedRepository.setId( TARGET_REPO_ID );
492         managedRepository.setLocation( targetRepo.toAbsolutePath().toString() );
493         managedRepository.setCronExpression( "* * * * * ?" );
494         getManagedRepositoriesService( authorizationHeader ).addManagedRepository( managedRepository );
495         assertNotNull( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( TARGET_REPO_ID ) );
496
497         Path originRepo = getAppserverBase().resolve( "data/repositories/test-origin-repo" );
498         if ( Files.exists(originRepo) )
499         {
500             org.apache.archiva.common.utils.FileUtils.deleteDirectory( originRepo );
501         }
502         assertFalse( Files.exists(originRepo) );
503         FileUtils.copyDirectory( getProjectDirectory().resolve("src/test/repo-with-osgi" ).toAbsolutePath().toFile(), originRepo.toAbsolutePath().toFile() );
504
505         if ( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( SOURCE_REPO_ID ) != null )
506         {
507             getManagedRepositoriesService( authorizationHeader ).deleteManagedRepository( SOURCE_REPO_ID, true );
508             assertNull( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( SOURCE_REPO_ID ) );
509         }
510
511         managedRepository = getTestManagedRepository();
512         managedRepository.setId( SOURCE_REPO_ID );
513         managedRepository.setLocation( originRepo.toAbsolutePath().toString() );
514
515         getManagedRepositoriesService( authorizationHeader ).addManagedRepository( managedRepository );
516         assertNotNull( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( SOURCE_REPO_ID ) );
517
518         getArchivaAdministrationService().enabledKnownContentConsumer( "create-missing-checksums" );
519         getArchivaAdministrationService().enabledKnownContentConsumer( "metadata-updater" );
520
521     }
522
523     protected void cleanRepos()
524         throws Exception
525     {
526
527         if ( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( TARGET_REPO_ID ) != null )
528         {
529             try
530             {
531                 getManagedRepositoriesService( authorizationHeader ).deleteManagedRepository( TARGET_REPO_ID, true );
532                 assertNull(
533                     getManagedRepositoriesService( authorizationHeader ).getManagedRepository( TARGET_REPO_ID ) );
534             }
535             catch ( Exception e )
536             {
537                 log.warn( "skip issue while cleaning test repository: this can cause test failure", e );
538             }
539         }
540         if ( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( SOURCE_REPO_ID ) != null )
541         {
542             try
543             {
544                 getManagedRepositoriesService( authorizationHeader ).deleteManagedRepository( SOURCE_REPO_ID, true );
545                 assertNull(
546                     getManagedRepositoriesService( authorizationHeader ).getManagedRepository( SOURCE_REPO_ID ) );
547             }
548             catch ( Exception e )
549             {
550                 log.warn( "skip issue while cleaning test repository: this can cause test failure", e );
551             }
552         }
553
554     }
555
556     protected void createAndIndexRepo( String testRepoId, Path srcRepoPath, Path stagedSrcRepoPath, boolean stageNeeded )
557         throws ArchivaRestServiceException, IOException, RedbackServiceException
558     {
559         if ( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( testRepoId ) != null )
560         {
561             getManagedRepositoriesService( authorizationHeader ).deleteManagedRepository( testRepoId, false );
562         }
563
564         ManagedRepository managedRepository = new ManagedRepository(Locale.getDefault());
565         managedRepository.setId( testRepoId );
566         managedRepository.setName( "test repo" );
567
568         Path badContent = srcRepoPath.resolve( "target" );
569         if ( Files.exists(badContent) )
570         {
571             org.apache.archiva.common.utils.FileUtils.deleteDirectory( badContent );
572         }
573
574         Path repoPath = getAppserverBase().resolve( "data" ).resolve( "repositories" ).resolve( testRepoId);
575         Path stagedRepoPath = getAppserverBase().resolve( "data" ).resolve( "repositories" ).resolve( testRepoId + "-stage");
576
577         FileUtils.deleteQuietly(repoPath.toFile());
578         FileUtils.copyDirectory(srcRepoPath.toFile(), repoPath.toFile());
579
580         if (stagedSrcRepoPath!=null) {
581             FileUtils.deleteQuietly(stagedRepoPath.toFile());
582             FileUtils.copyDirectory(stagedSrcRepoPath.toFile(), stagedRepoPath.toFile());
583
584         }
585
586         managedRepository.setLocation( repoPath.toAbsolutePath().toString() );
587         String suffix = Long.toString( new Date().getTime() );
588         Path baseDir = Files.createTempDirectory( "archiva-test-index" ).toAbsolutePath();
589         managedRepository.setIndexDirectory(
590             baseDir.resolve( ".indexer-" + suffix ).toString());
591         managedRepository.setPackedIndexDirectory(baseDir.resolve(".index-" + suffix).toString());
592
593         managedRepository.setStageRepoNeeded( stageNeeded );
594         managedRepository.setSnapshots( true );
595
596         //managedRepository.setScanned( scanned );
597
598         ManagedRepositoriesService service = getManagedRepositoriesService( authorizationHeader );
599         service.addManagedRepository( managedRepository );
600
601         getRoleManagementService( authorizationHeader ).assignTemplatedRole(
602             ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, testRepoId, "admin" );
603
604         getRoleManagementService( authorizationHeader ).assignTemplatedRole(
605             ArchivaRoleConstants.TEMPLATE_REPOSITORY_OBSERVER, testRepoId, "guest" );
606     }
607
608     protected void scanRepo( String testRepoId )
609         throws ArchivaRestServiceException
610     {
611         getRepositoriesService( authorizationHeader ).scanRepositoryNow( testRepoId, true );
612     }
613
614     protected void createAndIndexRepo( String testRepoId, Path srcRepoPath )
615         throws Exception
616     {
617         createAndIndexRepo( testRepoId, srcRepoPath, null, false );
618         scanRepo( testRepoId );
619     }
620
621     protected void createStagedNeededRepo( String testRepoId, Path srcRepoPath, Path stagedSrcRepoPath, boolean scan )
622         throws Exception
623     {
624         createAndIndexRepo( testRepoId, srcRepoPath, stagedSrcRepoPath, true );
625         if ( scan )
626         {
627             scanRepo( testRepoId );
628         }
629
630         RepositoriesService repositoriesService = getRepositoriesService( authorizationHeader );
631         repositoriesService.scanRepositoryDirectoriesNow( testRepoId );
632         if ( scan )
633         {
634             repositoriesService.scanRepositoryNow( testRepoId + "-stage", true );
635             repositoriesService.scanRepositoryDirectoriesNow( testRepoId + "-stage" );
636         }
637     }
638
639
640     protected void deleteTestRepo( String id )
641         throws Exception
642     {
643         if ( getManagedRepositoriesService( authorizationHeader ).getManagedRepository( id ) != null )
644         {
645             getManagedRepositoriesService( authorizationHeader ).deleteManagedRepository( id, false );
646         }
647     }
648
649     public Path getBasedir()
650     {
651         if (basePath.get()==null) {
652             String baseDir = System.getProperty( "basedir" );
653             final Path baseDirPath;
654             if (StringUtils.isNotEmpty( baseDir ))  {
655                 baseDirPath = Paths.get( baseDir );
656             } else {
657                 baseDirPath = getProjectDirectory( );
658             }
659             basePath.compareAndSet( null, baseDirPath );
660         }
661         return basePath.get( );
662     }
663
664     protected void waitForScanToComplete( String repoId )
665         throws ArchivaRestServiceException, InterruptedException
666     {
667         while ( getRepositoriesService( authorizationHeader ).alreadyScanning( repoId ) ) {
668             // Would be better to cancel, if we had that capacity
669             Thread.sleep( 100 );
670         }
671     }
672 }