1 package org.apache.archiva.maven.indexer.search;
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 junit.framework.TestCase;
22 import org.apache.archiva.common.utils.FileUtils;
23 import org.apache.archiva.configuration.ArchivaConfiguration;
24 import org.apache.archiva.configuration.Configuration;
25 import org.apache.archiva.configuration.ConfigurationListener;
26 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
27 import org.apache.archiva.indexer.ArchivaIndexingContext;
28 import org.apache.archiva.indexer.search.SearchResultHit;
29 import org.apache.archiva.indexer.search.SearchResults;
30 import org.apache.archiva.proxy.ProxyRegistry;
31 import org.apache.archiva.repository.Repository;
32 import org.apache.archiva.repository.base.ArchivaRepositoryRegistry;
33 import org.apache.archiva.repository.base.RepositoryHandlerDependencies;
34 import org.apache.archiva.repository.features.IndexCreationFeature;
35 import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
36 import org.apache.commons.lang3.SystemUtils;
37 import org.apache.maven.index.ArtifactContext;
38 import org.apache.maven.index.ArtifactContextProducer;
39 import org.apache.maven.index.ArtifactScanningListener;
40 import org.apache.maven.index.DefaultScannerListener;
41 import org.apache.maven.index.Indexer;
42 import org.apache.maven.index.IndexerEngine;
43 import org.apache.maven.index.QueryCreator;
44 import org.apache.maven.index.Scanner;
45 import org.apache.maven.index.ScanningRequest;
46 import org.apache.maven.index.ScanningResult;
47 import org.apache.maven.index.context.IndexingContext;
48 import org.apache.maven.index_shaded.lucene.index.IndexUpgrader;
49 import org.junit.After;
50 import org.junit.Before;
51 import org.junit.runner.RunWith;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.springframework.test.context.ContextConfiguration;
56 import javax.inject.Inject;
57 import java.io.IOException;
58 import java.nio.file.Files;
59 import java.nio.file.Path;
60 import java.nio.file.Paths;
61 import java.util.List;
62 import java.util.Locale;
64 import static org.apache.archiva.indexer.ArchivaIndexManager.DEFAULT_INDEX_PATH;
65 import static org.mockito.ArgumentMatchers.any;
66 import static org.mockito.ArgumentMatchers.anyString;
67 import static org.mockito.Mockito.*;
70 * @author Olivier Lamy
72 @RunWith( ArchivaSpringJUnit4ClassRunner.class )
73 @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath:/spring-context.xml" } )
74 public abstract class AbstractMavenRepositorySearch
78 protected Logger log = LoggerFactory.getLogger( getClass() );
80 public static String TEST_REPO_1 = "maven-search-test-repo";
82 public static String TEST_REPO_2 = "maven-search-test-repo-2";
85 public static String REPO_RELEASE = "repo-release";
87 MavenRepositorySearch search;
89 ArchivaConfiguration archivaConfig;
92 ArtifactContextProducer artifactContextProducer;
95 ArchivaRepositoryRegistry repositoryRegistry;
97 @SuppressWarnings( "unused" )
99 RepositoryHandlerDependencies repositoryHandlerDependencies;
102 ProxyRegistry proxyRegistry;
105 private IndexerEngine indexerEngine;
107 Configuration config;
116 QueryCreator queryCreator;
125 FileUtils.deleteDirectory( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_1 + "/.indexer" ) );
126 assertFalse( Files.exists(Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_1 + "/.indexer" )) );
127 Files.createDirectories( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_1 + "/.indexer" ) );
129 FileUtils.deleteDirectory( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_2 + "/.indexer" ) );
130 assertFalse( Files.exists(Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_2 + "/.indexer" )) );
131 Files.createDirectories( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_2 + "/.indexer" ) );
133 archivaConfig = mock( ArchivaConfiguration.class );
135 repositoryRegistry.setArchivaConfiguration( archivaConfig );
137 search = new MavenRepositorySearch( indexer, repositoryRegistry, proxyRegistry,
140 assertNotNull( repositoryRegistry );
142 config = new Configuration();
143 config.addManagedRepository( createRepositoryConfig( TEST_REPO_1 ) );
144 config.addManagedRepository( createRepositoryConfig( TEST_REPO_2 ) );
145 config.addManagedRepository( createRepositoryConfig( REPO_RELEASE ) );
147 when( archivaConfig.getDefaultLocale() ).thenReturn( Locale.getDefault( ) );
148 when( archivaConfig.getConfiguration() ).thenReturn(config);
149 archivaConfig.save(any(Configuration.class), anyString());
150 repositoryRegistry.reload();
156 public void tearDown()
159 reset( archivaConfig );
160 when( archivaConfig.getDefaultLocale() ).thenReturn( Locale.getDefault( ) );
161 when( archivaConfig.getConfiguration() ).thenReturn(config);
162 archivaConfig.save(any(Configuration.class), anyString());
163 repositoryRegistry.removeRepository(TEST_REPO_1);
164 repositoryRegistry.removeRepository(TEST_REPO_2);
165 repositoryRegistry.removeRepository(REPO_RELEASE);
166 repositoryRegistry.destroy();
167 FileUtils.deleteDirectory( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_1 ) );
168 assertFalse( Files.exists(Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_1 )) );
170 FileUtils.deleteDirectory( Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_2 ) );
171 assertFalse( Files.exists(Paths.get( org.apache.archiva.common.utils.FileUtils.getBasedir(), "/target/repos/" + TEST_REPO_2 )) );
176 protected ManagedRepositoryConfiguration createRepositoryConfig( String repository )
178 ManagedRepositoryConfiguration repositoryConfig = new ManagedRepositoryConfiguration();
179 repositoryConfig.setId( repository );
180 repositoryConfig.setLocation( org.apache.archiva.common.utils.FileUtils.getBasedir() + "/target/repos/" + repository );
181 Path f = Paths.get( repositoryConfig.getLocation() );
182 if ( !Files.exists(f) )
186 Files.createDirectories( f );
188 catch ( IOException e )
190 log.error("Could not create directories for {}", f);
193 repositoryConfig.setLayout( "default" );
194 repositoryConfig.setName( repository );
195 repositoryConfig.setScanned( true );
196 repositoryConfig.setSnapshots( false );
197 repositoryConfig.setReleases( true );
198 repositoryConfig.setIndexDir(DEFAULT_INDEX_PATH);
200 return repositoryConfig;
203 protected void createIndex( String repository, List<Path> filesToBeIndexed, boolean scan) throws Exception {
204 createIndex(repository, filesToBeIndexed, scan, null, true);
207 protected void createIndex( String repository, List<Path> filesToBeIndexed, boolean scan, Path indexDir, boolean copyFiles)
210 final Repository rRepo = repositoryRegistry.getRepository(repository);
211 IndexCreationFeature icf = rRepo.getFeature(IndexCreationFeature.class).get();
214 ArchivaIndexingContext archivaCtx = rRepo.getIndexingContext();
215 IndexingContext context = archivaCtx.getBaseContext(IndexingContext.class);
217 if ( archivaCtx != null )
219 archivaCtx.close(true);
222 Path repoDir = Paths.get(org.apache.archiva.common.utils.FileUtils.getBasedir()).resolve("target").resolve("repos").resolve(repository);
224 Path indexerDirectory = repoDir.resolve(".indexer" );
226 if ( indexDir == null && Files.exists(indexerDirectory) )
228 FileUtils.deleteDirectory( indexerDirectory );
229 assertFalse( Files.exists(indexerDirectory) );
233 Path lockFile = repoDir.resolve(".indexer/write.lock" );
234 if ( Files.exists(lockFile) )
236 Files.delete(lockFile);
238 assertFalse( Files.exists(lockFile) );
239 if (indexDir==null) {
240 Path indexDirectory =
241 Paths.get(org.apache.archiva.common.utils.FileUtils.getBasedir(), "target/index/test-" + Long.toString(System.currentTimeMillis()));
242 indexDirectory.toFile().deleteOnExit();
243 FileUtils.deleteDirectory(indexDirectory);
244 icf.setIndexPath(indexDirectory.toUri());
245 config.getManagedRepositories( ).stream( ).filter( r -> r.getId( ).equals( rRepo.getId( ) ) ).findFirst( ).ifPresent( r ->
246 r.setIndexDir( indexDirectory.toAbsolutePath( ).toString( ) )
248 // IndexUpgrader.main(new String[]{indexDirectory.toAbsolutePath().toString()});
251 icf.setIndexPath(indexDir.toUri());
252 Files.createDirectories( indexDir );
253 config.getManagedRepositories( ).stream( ).filter( r -> r.getId( ).equals( rRepo.getId( ) ) ).findFirst( ).ifPresent( r ->
254 r.setIndexDir( indexDir.toAbsolutePath( ).toString( ) )
256 IndexUpgrader.main(new String[]{indexDir.toAbsolutePath().toString()});
261 Path repo = Paths.get(org.apache.archiva.common.utils.FileUtils.getBasedir(), "src/test/" + repository);
262 assertTrue(Files.exists(repo));
263 org.apache.commons.io.FileUtils.copyDirectory(repo.toFile(), repoDir.toFile());
267 reset( archivaConfig );
268 when( archivaConfig.getConfiguration() ).thenReturn(config);
269 archivaConfig.save(any(Configuration.class), anyString());
270 repositoryRegistry.reload();
272 Repository rRepo2 = repositoryRegistry.getRepository( repository );
273 icf = rRepo2.getFeature(IndexCreationFeature.class).get();
276 archivaCtx = rRepo2.getIndexingContext();
277 context = archivaCtx.getBaseContext(IndexingContext.class);
280 // minimize datas in memory
281 // context.getIndexWriter().setMaxBufferedDocs( -1 );
282 // context.getIndexWriter().setRAMBufferSizeMB( 1 );
283 for ( Path artifactFile : filesToBeIndexed )
285 assertTrue( "file not exists " + artifactFile, Files.exists(artifactFile) );
286 ArtifactContext ac = artifactContextProducer.getArtifactContext( context, artifactFile.toFile() );
288 if ( artifactFile.toString().endsWith( ".pom" ) )
290 ac.getArtifactInfo().setFileExtension( "pom" );
291 ac.getArtifactInfo().setPackaging( "pom" );
292 ac.getArtifactInfo().setClassifier( "pom" );
294 indexer.addArtifactToIndex( ac, context );
295 context.updateTimestamp( true );
300 DefaultScannerListener listener = new DefaultScannerListener( context, indexerEngine, true, new ArtifactScanListener());
301 ScanningRequest req = new ScanningRequest(context, listener );
307 // context.getIndexWriter().commit();
308 context.setSearchable( true );
312 static class ArtifactScanListener
313 implements ArtifactScanningListener
315 protected Logger log = LoggerFactory.getLogger( getClass() );
318 public void scanningStarted( IndexingContext ctx )
324 public void scanningFinished( IndexingContext ctx, ScanningResult result )
330 public void artifactError( ArtifactContext ac, Exception e )
332 log.debug( "artifactError {}", ac.getArtifact().getPath(), e );
336 public void artifactDiscovered( ArtifactContext ac )
338 log.debug( "artifactDiscovered {}:{}", //
339 ac.getArtifact() == null ? "" : ac.getArtifact().getPath(), //
340 ac.getArtifact() == null ? "" : ac.getArtifactInfo() );
344 public String niceDisplay( SearchResults searchResults )
347 StringBuilder sb = new StringBuilder();
348 for ( SearchResultHit hit : searchResults.getHits() )
350 sb.append( hit.toString() ).append( SystemUtils.LINE_SEPARATOR );
352 return sb.toString();