View Javadoc
1   package org.apache.archiva.scheduler.indexing;
2   
3   /*
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
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
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
19   * under the License.
20   */
21  
22  import junit.framework.TestCase;
23  import org.apache.archiva.admin.model.beans.ManagedRepository;
24  import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
25  import org.apache.archiva.common.plexusbridge.MavenIndexerUtils;
26  import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
27  import org.apache.archiva.test.utils.ArchivaSpringJUnit4ClassRunner;
28  import org.apache.lucene.search.BooleanClause.Occur;
29  import org.apache.lucene.search.BooleanQuery;
30  import org.apache.lucene.search.IndexSearcher;
31  import org.apache.lucene.search.TopDocs;
32  import org.apache.maven.index.ArtifactInfo;
33  import org.apache.maven.index.FlatSearchRequest;
34  import org.apache.maven.index.FlatSearchResponse;
35  import org.apache.maven.index.MAVEN;
36  import org.apache.maven.index.NexusIndexer;
37  import org.apache.maven.index.context.IndexingContext;
38  import org.apache.maven.index.expr.SourcedSearchExpression;
39  import org.apache.maven.index.expr.StringSearchExpression;
40  import org.junit.After;
41  import org.junit.Before;
42  import org.junit.Test;
43  import org.junit.runner.RunWith;
44  import org.springframework.test.context.ContextConfiguration;
45  
46  import javax.inject.Inject;
47  import java.io.BufferedInputStream;
48  import java.io.BufferedOutputStream;
49  import java.io.File;
50  import java.io.FilenameFilter;
51  import java.io.IOException;
52  import java.io.InputStream;
53  import java.io.OutputStream;
54  import java.nio.file.Files;
55  import java.nio.file.Paths;
56  import java.util.Set;
57  import java.util.zip.ZipEntry;
58  import java.util.zip.ZipInputStream;
59  
60  /**
61   * ArchivaIndexingTaskExecutorTest
62   */
63  @RunWith( ArchivaSpringJUnit4ClassRunner.class )
64  @ContextConfiguration( locations = { "classpath*:/META-INF/spring-context.xml", "classpath*:/spring-context.xml" } )
65  public class ArchivaIndexingTaskExecutorTest
66      extends TestCase
67  {
68      @Inject
69      private ArchivaIndexingTaskExecutor indexingExecutor;
70  
71      private ManagedRepository repositoryConfig;
72  
73      private NexusIndexer indexer;
74  
75      @Inject
76      PlexusSisuBridge plexusSisuBridge;
77  
78      @Inject
79      MavenIndexerUtils mavenIndexerUtils;
80  
81      @Inject
82      ManagedRepositoryAdmin managedRepositoryAdmin;
83  
84      @Before
85      @Override
86      public void setUp()
87          throws Exception
88      {
89          super.setUp();
90  
91          repositoryConfig = new ManagedRepository();
92          repositoryConfig.setId( "test-repo" );
93          repositoryConfig.setLocation(
94              new File( System.getProperty( "basedir" ), "target/test-classes/test-repo" ).getAbsolutePath() );
95          repositoryConfig.setLayout( "default" );
96          repositoryConfig.setName( "Test Repository" );
97          repositoryConfig.setScanned( true );
98          repositoryConfig.setSnapshots( false );
99          repositoryConfig.setReleases( true );
100 
101         indexer = plexusSisuBridge.lookup( NexusIndexer.class );
102 
103         managedRepositoryAdmin.createIndexContext( repositoryConfig );
104     }
105 
106     @After
107     @Override
108     public void tearDown()
109         throws Exception
110     {
111 
112         for ( IndexingContext indexingContext : indexer.getIndexingContexts().values() )
113         {
114             indexer.removeIndexingContext( indexingContext, true );
115         }
116         /*
117         removeIndexingContext with true cleanup files.
118         // delete created index in the repository
119         File indexDir = new File( repositoryConfig.getLocation(), ".indexer" );
120         FileUtils.deleteDirectory( indexDir );
121         assertFalse( indexDir.exists() );
122 
123         indexDir = new File( repositoryConfig.getLocation(), ".index" );
124         FileUtils.deleteDirectory( indexDir );
125         assertFalse( indexDir.exists() );
126         */
127         super.tearDown();
128     }
129 
130     protected IndexingContext getIndexingContext()
131     {
132         return indexer.getIndexingContexts().get( repositoryConfig.getId() );
133     }
134 
135     @Test
136     public void testAddArtifactToIndex()
137         throws Exception
138     {
139         File artifactFile = new File( repositoryConfig.getLocation(),
140                                       "org/apache/archiva/archiva-index-methods-jar-test/1.0/archiva-index-methods-jar-test-1.0.jar" );
141 
142         ArtifactIndexingTask task =
143             new ArtifactIndexingTask( repositoryConfig, artifactFile, ArtifactIndexingTask.Action.ADD,
144                                       getIndexingContext() );
145 
146         indexingExecutor.executeTask( task );
147 
148         BooleanQuery q = new BooleanQuery();
149         q.add( indexer.constructQuery( MAVEN.GROUP_ID, new StringSearchExpression( "org.apache.archiva" ) ),
150                Occur.SHOULD );
151         q.add(
152             indexer.constructQuery( MAVEN.ARTIFACT_ID, new StringSearchExpression( "archiva-index-methods-jar-test" ) ),
153             Occur.SHOULD );
154 
155         if ( !indexer.getIndexingContexts().containsKey( repositoryConfig.getId() ) )
156         {
157             IndexingContext context = indexer.addIndexingContext( repositoryConfig.getId(), repositoryConfig.getId(),
158                                                                   new File( repositoryConfig.getLocation() ),
159                                                                   new File( repositoryConfig.getLocation(),
160                                                                             ".indexer" ), null, null,
161                                                                   mavenIndexerUtils.getAllIndexCreators()
162             );
163             context.setSearchable( true );
164         }
165 
166         FlatSearchRequest request = new FlatSearchRequest( q );
167         FlatSearchResponse response = indexer.searchFlat( request );
168 
169         assertTrue( new File( repositoryConfig.getLocation(), ".indexer" ).exists() );
170         assertFalse( new File( repositoryConfig.getLocation(), ".index" ).exists() );
171         assertEquals( 1, response.getTotalHits() );
172 
173         Set<ArtifactInfo> results = response.getResults();
174 
175         ArtifactInfo artifactInfo = results.iterator().next();
176         assertEquals( "org.apache.archiva", artifactInfo.groupId );
177         assertEquals( "archiva-index-methods-jar-test", artifactInfo.artifactId );
178         assertEquals( "test-repo", artifactInfo.repository );
179 
180     }
181 
182     @Test
183     public void testUpdateArtifactInIndex()
184         throws Exception
185     {
186         File artifactFile = new File( repositoryConfig.getLocation(),
187                                       "org/apache/archiva/archiva-index-methods-jar-test/1.0/archiva-index-methods-jar-test-1.0.jar" );
188 
189         ArtifactIndexingTask task =
190             new ArtifactIndexingTask( repositoryConfig, artifactFile, ArtifactIndexingTask.Action.ADD,
191                                       getIndexingContext() );
192 
193         indexingExecutor.executeTask( task );
194         indexingExecutor.executeTask( task );
195 
196         BooleanQuery q = new BooleanQuery();
197         q.add( indexer.constructQuery( MAVEN.GROUP_ID, new StringSearchExpression( "org.apache.archiva" ) ),
198                Occur.SHOULD );
199         q.add(
200             indexer.constructQuery( MAVEN.ARTIFACT_ID, new StringSearchExpression( "archiva-index-methods-jar-test" ) ),
201             Occur.SHOULD );
202 
203         IndexingContext ctx = indexer.getIndexingContexts().get( repositoryConfig.getId() );
204 
205         IndexSearcher searcher = ctx.acquireIndexSearcher();
206         TopDocs topDocs = searcher.search( q, null, 10 );
207 
208         //searcher.close();
209         ctx.releaseIndexSearcher( searcher );
210 
211         assertTrue( new File( repositoryConfig.getLocation(), ".indexer" ).exists() );
212         assertFalse( new File( repositoryConfig.getLocation(), ".index" ).exists() );
213 
214         // should only return 1 hit!
215         assertEquals( 1, topDocs.totalHits );
216     }
217 
218     @Test
219     public void testRemoveArtifactFromIndex()
220         throws Exception
221     {
222         File artifactFile = new File( repositoryConfig.getLocation(),
223                                       "org/apache/archiva/archiva-index-methods-jar-test/1.0/archiva-index-methods-jar-test-1.0.jar" );
224 
225         ArtifactIndexingTask task =
226             new ArtifactIndexingTask( repositoryConfig, artifactFile, ArtifactIndexingTask.Action.ADD,
227                                       getIndexingContext() );
228 
229         // add artifact to index
230         indexingExecutor.executeTask( task );
231 
232         BooleanQuery q = new BooleanQuery();
233         q.add( indexer.constructQuery( MAVEN.GROUP_ID, new SourcedSearchExpression( "org.apache.archiva" ) ),
234                Occur.SHOULD );
235         //q.add(
236         //    indexer.constructQuery( MAVEN.ARTIFACT_ID, new SourcedSearchExpression( "archiva-index-methods-jar-test" ) ),
237         //    Occur.SHOULD );
238 
239         FlatSearchRequest flatSearchRequest =
240             new FlatSearchRequest( q, indexer.getIndexingContexts().get( repositoryConfig.getId() ) );
241 
242         FlatSearchResponse response = indexer.searchFlat( flatSearchRequest );
243 
244         assertTrue( new File( repositoryConfig.getLocation(), ".indexer" ).exists() );
245         assertFalse( new File( repositoryConfig.getLocation(), ".index" ).exists() );
246 
247         // should return 1 hit
248         assertEquals( 1, response.getTotalHitsCount() );
249 
250         // remove added artifact from index
251         task = new ArtifactIndexingTask( repositoryConfig, artifactFile, ArtifactIndexingTask.Action.DELETE,
252                                          getIndexingContext() );
253         indexingExecutor.executeTask( task );
254 
255         task = new ArtifactIndexingTask( repositoryConfig, artifactFile, ArtifactIndexingTask.Action.FINISH,
256                                          getIndexingContext() );
257         indexingExecutor.executeTask( task );
258 
259         q = new BooleanQuery();
260         q.add( indexer.constructQuery( MAVEN.GROUP_ID, new SourcedSearchExpression( "org.apache.archiva" ) ),
261                Occur.SHOULD );
262         q.add( indexer.constructQuery( MAVEN.ARTIFACT_ID,
263                                        new SourcedSearchExpression( "archiva-index-methods-jar-test" ) ), Occur.SHOULD
264         );
265 
266         assertTrue( new File( repositoryConfig.getLocation(), ".indexer" ).exists() );
267         assertFalse( new File( repositoryConfig.getLocation(), ".index" ).exists() );
268 
269         flatSearchRequest = new FlatSearchRequest( q, getIndexingContext() );
270 
271         response = indexer.searchFlat( flatSearchRequest );
272         // artifact should have been removed from the index!
273         assertEquals( 0, response.getTotalHitsCount() );//.totalHits );
274 
275         // TODO: test it was removed from the packaged index also
276     }
277 
278     @Test
279     public void testPackagedIndex()
280         throws Exception
281     {
282 
283         File indexerDirectory = new File( repositoryConfig.getLocation(), ".indexer" );
284 
285         indexerDirectory.listFiles( new FilenameFilter()
286         {
287             @Override
288             public boolean accept( File file, String s )
289             {
290                 if ( s.startsWith( "nexus-maven-repository-index" ) )
291                 {
292                     new File( file, s ).delete();
293                 }
294                 return false;
295             }
296         } );
297 
298         File artifactFile = new File( repositoryConfig.getLocation(),
299                                       "org/apache/archiva/archiva-index-methods-jar-test/1.0/archiva-index-methods-jar-test-1.0.jar" );
300 
301         ArtifactIndexingTask task =
302             new ArtifactIndexingTask( repositoryConfig, artifactFile, ArtifactIndexingTask.Action.ADD,
303                                       getIndexingContext() );
304         task.setExecuteOnEntireRepo( false );
305 
306         indexingExecutor.executeTask( task );
307 
308         task = new ArtifactIndexingTask( repositoryConfig, null, ArtifactIndexingTask.Action.FINISH,
309                                          getIndexingContext() );
310 
311         task.setExecuteOnEntireRepo( false );
312 
313         indexingExecutor.executeTask( task );
314 
315         assertTrue( indexerDirectory.exists() );
316 
317         // test packed index file creation
318         assertTrue( new File( indexerDirectory, "nexus-maven-repository-index.zip" ).exists() );
319         assertTrue( new File( indexerDirectory, "nexus-maven-repository-index.properties" ).exists() );
320         assertTrue( new File( indexerDirectory, "nexus-maven-repository-index.gz" ).exists() );
321 
322         // unpack .zip index
323         File destDir = new File( repositoryConfig.getLocation(), ".indexer/tmp" );
324         unzipIndex( indexerDirectory.getPath(), destDir.getPath() );
325 
326         BooleanQuery q = new BooleanQuery();
327         q.add( indexer.constructQuery( MAVEN.GROUP_ID, new StringSearchExpression( "org.apache.archiva" ) ),
328                Occur.SHOULD );
329         q.add(
330             indexer.constructQuery( MAVEN.ARTIFACT_ID, new StringSearchExpression( "archiva-index-methods-jar-test" ) ),
331             Occur.SHOULD );
332 
333         FlatSearchRequest request = new FlatSearchRequest( q, getIndexingContext() );
334         FlatSearchResponse response = indexer.searchFlat( request );
335 
336         Set<ArtifactInfo> results = response.getResults();
337 
338         ArtifactInfo artifactInfo = results.iterator().next();
339         assertEquals( "org.apache.archiva", artifactInfo.groupId );
340         assertEquals( "archiva-index-methods-jar-test", artifactInfo.artifactId );
341         assertEquals( "test-repo", artifactInfo.repository );
342 
343         assertEquals( 1, response.getTotalHits() );
344     }
345 
346     private void unzipIndex( String indexDir, String destDir )
347         throws IOException
348     {
349         final int buff = 2048;
350 
351         Files.createDirectories( Paths.get( destDir ) );
352 
353         try (InputStream fin = Files.newInputStream( Paths.get( indexDir, "nexus-maven-repository-index.zip" ) ))
354         {
355             ZipInputStream in = new ZipInputStream( new BufferedInputStream( fin ) );
356             ZipEntry entry;
357 
358             while ( ( entry = in.getNextEntry() ) != null )
359             {
360                 int count;
361                 byte data[] = new byte[buff];
362                 try (OutputStream fout = Files.newOutputStream( Paths.get( destDir, entry.getName() ) ))
363                 {
364                     try (BufferedOutputStream out = new BufferedOutputStream( fout, buff ))
365                     {
366 
367                         while ( ( count = in.read( data, 0, buff ) ) != -1 )
368                         {
369                             out.write( data, 0, count );
370                         }
371                     }
372                 }
373             }
374 
375         }
376     }
377 }