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