]> source.dussan.org Git - archiva.git/blob
4893bcda8a745eb4b0b20f44bf4938d0f9c915d1
[archiva.git] /
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 Li
16  * cense is distributed on an
17  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18  * KIND, either express or implied.  See the License for the
19  * specific language governing permissions and limitations
20  * under the License.
21  */
22
23 import org.apache.archiva.admin.model.RepositoryAdminException;
24 import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
25 import org.apache.archiva.indexer.ArchivaIndexingContext;
26 import org.apache.archiva.indexer.UnsupportedBaseContextException;
27 import org.apache.archiva.redback.components.taskqueue.Task;
28 import org.apache.archiva.redback.components.taskqueue.execution.TaskExecutionException;
29 import org.apache.archiva.redback.components.taskqueue.execution.TaskExecutor;
30 import org.apache.archiva.repository.ManagedRepository;
31 import org.apache.archiva.repository.features.IndexCreationFeature;
32 import org.apache.maven.index.ArtifactContext;
33 import org.apache.maven.index.ArtifactContextProducer;
34 import org.apache.maven.index.FlatSearchRequest;
35 import org.apache.maven.index.FlatSearchResponse;
36 import org.apache.maven.index.MAVEN;
37 import org.apache.maven.index.NexusIndexer;
38 import org.apache.maven.index.context.IndexingContext;
39 import org.apache.maven.index.expr.SourcedSearchExpression;
40 import org.apache.maven.index.packer.IndexPacker;
41 import org.apache.maven.index.packer.IndexPackingRequest;
42 import org.apache.maven.index_shaded.lucene.search.BooleanClause;
43 import org.apache.maven.index_shaded.lucene.search.BooleanQuery;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.springframework.stereotype.Service;
47
48 import javax.inject.Inject;
49 import java.io.IOException;
50 import java.nio.file.Path;
51
52 /**
53  * ArchivaIndexingTaskExecutor Executes all indexing tasks. Adding, updating and removing artifacts from the index are
54  * all performed by this executor. Add and update artifact in index tasks are added in the indexing task queue by the
55  * NexusIndexerConsumer while remove artifact from index tasks are added by the LuceneCleanupRemoveIndexedConsumer.
56  */
57 @Service( "taskExecutor#indexing" )
58 public class ArchivaIndexingTaskExecutor
59     implements TaskExecutor
60 {
61     private Logger log = LoggerFactory.getLogger( ArchivaIndexingTaskExecutor.class );
62
63     @Inject
64     private IndexPacker indexPacker;
65
66     @Inject
67     private ArtifactContextProducer artifactContextProducer;
68
69     @Inject
70     private ManagedRepositoryAdmin managedRepositoryAdmin;
71
72     @Inject
73     private NexusIndexer nexusIndexer;
74
75
76     /**
77      * depending on current {@link Task} you have.
78      * If {@link org.apache.archiva.scheduler.indexing.ArtifactIndexingTask.Action#FINISH} && isExecuteOnEntireRepo:
79      * repository will be scanned.
80      *
81      * @param task
82      * @throws TaskExecutionException
83      */
84     @Override
85     public void executeTask( Task task )
86         throws TaskExecutionException
87     {
88         ArtifactIndexingTask indexingTask = (ArtifactIndexingTask) task;
89
90         ManagedRepository repository = indexingTask.getRepository( );
91         ArchivaIndexingContext archivaContext = indexingTask.getContext( );
92         IndexingContext context = null;
93         try {
94             context = archivaContext.getBaseContext(IndexingContext.class);
95         } catch (UnsupportedBaseContextException e) {
96             throw new TaskExecutionException("Bad repository type.", e);
97         }
98         if (!nexusIndexer.getIndexingContexts().containsKey(context.getId())) {
99             nexusIndexer.addIndexingContext(context);
100         }
101
102         if ( ArtifactIndexingTask.Action.FINISH.equals( indexingTask.getAction( ) )
103             && indexingTask.isExecuteOnEntireRepo( ) )
104         {
105             try
106             {
107                 long start = System.currentTimeMillis( );
108                 nexusIndexer.scan( context, null, indexingTask.isOnlyUpdate( ) );
109                 long end = System.currentTimeMillis( );
110                 log.info( "indexed maven repository: {}, onlyUpdate: {}, time {} ms", repository.getId( ),
111                     indexingTask.isOnlyUpdate( ), ( end - start ) );
112             }
113             catch ( IOException e )
114             {
115                 throw new TaskExecutionException( "Error scan repository " + repository, e );
116             }
117             log.debug( "Finishing indexing task on repo: {}", repository.getId( ) );
118             finishIndexingTask( indexingTask, repository, context );
119         }
120         else
121         {
122             // create context if not a repo scan request
123             if ( !indexingTask.isExecuteOnEntireRepo( ) )
124             {
125                 try
126                 {
127                     log.debug( "Creating indexing context on resource: {}", //
128                         ( indexingTask.getResourceFile( ) == null
129                             ? "none"
130                             : indexingTask.getResourceFile( ) ) );
131                     archivaContext = repository.getIndexingContext();
132                     context = archivaContext.getBaseContext(IndexingContext.class);
133                 }
134                 catch ( UnsupportedBaseContextException e )
135                 {
136                     log.error( "Error occurred while creating context: {}", e.getMessage( ) );
137                     throw new TaskExecutionException( "Error occurred while creating context: " + e.getMessage( ), e );
138                 }
139             }
140
141             if ( context == null || context.getIndexDirectory( ) == null )
142             {
143                 throw new TaskExecutionException( "Trying to index an artifact but the context is already closed" );
144             }
145
146             try
147             {
148                 Path artifactFile = indexingTask.getResourceFile( );
149                 if ( artifactFile == null )
150                 {
151                     log.debug( "no artifact pass in indexing task so skip it" );
152                 }
153                 else
154                 {
155                     ArtifactContext ac = artifactContextProducer.getArtifactContext( context, artifactFile.toFile( ) );
156
157                     if ( ac != null )
158                     {
159                         // MRM-1779 pom must be indexed too
160                         // TODO make that configurable?
161                         if ( artifactFile.getFileName( ).toString( ).endsWith( ".pom" ) )
162                         {
163                             ac.getArtifactInfo( ).setFileExtension( "pom" );
164                             ac.getArtifactInfo( ).setPackaging( "pom" );
165                             ac.getArtifactInfo( ).setClassifier( "pom" );
166                         }
167                         if ( indexingTask.getAction( ).equals( ArtifactIndexingTask.Action.ADD ) )
168                         {
169                             //IndexSearcher s = context.getIndexSearcher();
170                             //String uinfo = ac.getArtifactInfo().getUinfo();
171                             //TopDocs d = s.search( new TermQuery( new Term( ArtifactInfo.UINFO, uinfo ) ), 1 );
172
173                             BooleanQuery q = new BooleanQuery( );
174                             q.add( nexusIndexer.constructQuery( MAVEN.GROUP_ID, new SourcedSearchExpression(
175                                 ac.getArtifactInfo( ).getGroupId( ) ) ), BooleanClause.Occur.MUST );
176                             q.add( nexusIndexer.constructQuery( MAVEN.ARTIFACT_ID, new SourcedSearchExpression(
177                                 ac.getArtifactInfo( ).getArtifactId( ) ) ), BooleanClause.Occur.MUST );
178                             q.add( nexusIndexer.constructQuery( MAVEN.VERSION, new SourcedSearchExpression(
179                                 ac.getArtifactInfo( ).getVersion( ) ) ), BooleanClause.Occur.MUST );
180                             if ( ac.getArtifactInfo( ).getClassifier( ) != null )
181                             {
182                                 q.add( nexusIndexer.constructQuery( MAVEN.CLASSIFIER, new SourcedSearchExpression(
183                                     ac.getArtifactInfo( ).getClassifier( ) ) ), BooleanClause.Occur.MUST );
184                             }
185                             if ( ac.getArtifactInfo( ).getPackaging( ) != null )
186                             {
187                                 q.add( nexusIndexer.constructQuery( MAVEN.PACKAGING, new SourcedSearchExpression(
188                                     ac.getArtifactInfo( ).getPackaging( ) ) ), BooleanClause.Occur.MUST );
189                             }
190                             FlatSearchRequest flatSearchRequest = new FlatSearchRequest( q, context );
191                             FlatSearchResponse flatSearchResponse = nexusIndexer.searchFlat( flatSearchRequest );
192                             if ( flatSearchResponse.getResults( ).isEmpty( ) )
193                             {
194                                 log.debug( "Adding artifact '{}' to index..", ac.getArtifactInfo( ) );
195                                 nexusIndexer.addArtifactToIndex( ac, context );
196                             }
197                             else
198                             {
199                                 log.debug( "Updating artifact '{}' in index..", ac.getArtifactInfo( ) );
200                                 // TODO check if update exists !!
201                                 nexusIndexer.deleteArtifactFromIndex( ac, context );
202                                 nexusIndexer.addArtifactToIndex( ac, context );
203                             }
204
205                             context.updateTimestamp( );
206                             context.commit( );
207
208
209                         }
210                         else
211                         {
212                             log.debug( "Removing artifact '{}' from index..", ac.getArtifactInfo( ) );
213                             nexusIndexer.deleteArtifactFromIndex( ac, context );
214                         }
215                     }
216                 }
217                 // close the context if not a repo scan request
218                 if ( !indexingTask.isExecuteOnEntireRepo( ) )
219                 {
220                     log.debug( "Finishing indexing task on resource file : {}", indexingTask.getResourceFile( ) != null
221                         ? indexingTask.getResourceFile( )
222                         : " none " );
223                     finishIndexingTask( indexingTask, repository, context );
224                 }
225             }
226             catch ( IOException e )
227             {
228                 log.error( "Error occurred while executing indexing task '{}': {}", indexingTask, e.getMessage( ),
229                     e );
230                 throw new TaskExecutionException( "Error occurred while executing indexing task '" + indexingTask + "'",
231                     e );
232             }
233         }
234
235     }
236
237     private void finishIndexingTask( ArtifactIndexingTask indexingTask, ManagedRepository repository,
238                                      IndexingContext context )
239         throws TaskExecutionException
240     {
241         try
242         {
243
244             context.optimize( );
245
246             if ( repository.supportsFeature( IndexCreationFeature.class ) )
247             {
248                 IndexCreationFeature icf = repository.getFeature( IndexCreationFeature.class ).get( );
249                 if ( !icf.isSkipPackedIndexCreation( ) )
250                 {
251
252                     IndexPackingRequest request = new IndexPackingRequest( context, //
253                         context.acquireIndexSearcher( ).getIndexReader( ),
254                         //
255                         context.getIndexDirectoryFile( ) );
256
257                     indexPacker.packIndex( request );
258                     context.updateTimestamp( true );
259
260                     log.debug( "Index file packaged at '{}'.", context.getIndexDirectoryFile( ) );
261                 } else {
262                     log.debug( "skip packed index creation" );
263                 }
264             }
265             else
266             {
267                 log.debug( "skip packed index creation" );
268             }
269         }
270         catch ( IOException e )
271         {
272             log.error( "Error occurred while executing indexing task '{}': {}", indexingTask, e.getMessage( ) );
273             throw new TaskExecutionException( "Error occurred while executing indexing task '" + indexingTask + "'",
274                 e );
275         }
276     }
277
278     public void setIndexPacker( IndexPacker indexPacker )
279     {
280         this.indexPacker = indexPacker;
281     }
282
283 }