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