]> source.dussan.org Git - archiva.git/blob
aa999bd6fa8b14807c172772ed76a243d048b9bb
[archiva.git] /
1 package org.apache.archiva.consumers.lucene;
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 org.apache.archiva.admin.model.RepositoryAdminException;
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.common.plexusbridge.PlexusSisuBridgeException;
28 import org.apache.archiva.configuration.ArchivaConfiguration;
29 import org.apache.archiva.configuration.ConfigurationNames;
30 import org.apache.archiva.configuration.FileTypes;
31 import org.apache.archiva.consumers.AbstractMonitoredConsumer;
32 import org.apache.archiva.consumers.ConsumerException;
33 import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
34 import org.apache.archiva.redback.components.registry.Registry;
35 import org.apache.archiva.scheduler.ArchivaTaskScheduler;
36 import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
37 import org.apache.maven.index.NexusIndexer;
38 import org.apache.maven.index.context.IndexCreator;
39 import org.apache.maven.index.context.IndexingContext;
40 import org.apache.archiva.redback.components.registry.RegistryListener;
41 import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.context.annotation.Scope;
45 import org.springframework.stereotype.Service;
46
47 import javax.annotation.PostConstruct;
48 import javax.inject.Inject;
49 import javax.inject.Named;
50 import java.io.File;
51 import java.util.ArrayList;
52 import java.util.Collections;
53 import java.util.Date;
54 import java.util.List;
55
56 /**
57  * Consumer for indexing the repository to provide search and IDE integration features.
58  */
59 @Service( "knownRepositoryContentConsumer#index-content" )
60 @Scope( "prototype" )
61 public class NexusIndexerConsumer
62     extends AbstractMonitoredConsumer
63     implements KnownRepositoryContentConsumer, RegistryListener
64 {
65     private Logger log = LoggerFactory.getLogger( getClass() );
66
67     private ArchivaConfiguration configuration;
68
69     private FileTypes filetypes;
70
71     private File managedRepository;
72
73     private ArchivaTaskScheduler<ArtifactIndexingTask> scheduler;
74
75     private IndexingContext indexingContext;
76
77     private NexusIndexer nexusIndexer;
78
79     private List<String> includes = new ArrayList<>( 0 );
80
81     private ManagedRepository repository;
82
83     private List<? extends IndexCreator> allIndexCreators;
84
85     private ManagedRepositoryAdmin managedRepositoryAdmin;
86
87     @Inject
88     public NexusIndexerConsumer(
89         @Named( value = "archivaTaskScheduler#indexing" ) ArchivaTaskScheduler<ArtifactIndexingTask> scheduler,
90         @Named( value = "archivaConfiguration" ) ArchivaConfiguration configuration, FileTypes filetypes,
91         PlexusSisuBridge plexusSisuBridge, MavenIndexerUtils mavenIndexerUtils,
92         ManagedRepositoryAdmin managedRepositoryAdmin )
93         throws PlexusSisuBridgeException
94     {
95         this.configuration = configuration;
96         this.filetypes = filetypes;
97         this.scheduler = scheduler;
98         this.nexusIndexer = plexusSisuBridge.lookup( NexusIndexer.class );
99         this.allIndexCreators = mavenIndexerUtils.getAllIndexCreators();
100         this.managedRepositoryAdmin = managedRepositoryAdmin;
101     }
102
103     @Override
104     public String getDescription()
105     {
106         return "Indexes the repository to provide search and IDE integration features";
107     }
108
109     @Override
110     public String getId()
111     {
112         return "index-content";
113     }
114
115     @Override
116     public void beginScan( ManagedRepository repository, Date whenGathered )
117         throws ConsumerException
118     {
119         this.repository = repository;
120         managedRepository = new File( repository.getLocation() );
121
122         try
123         {
124             log.info( "Creating indexing context for repo : {}", repository.getId() );
125             indexingContext = managedRepositoryAdmin.createIndexContext( repository );
126         }
127         catch ( RepositoryAdminException e )
128         {
129             throw new ConsumerException( e.getMessage(), e );
130         }
131     }
132
133     @Override
134     public void beginScan( ManagedRepository repository, Date whenGathered, boolean executeOnEntireRepo )
135         throws ConsumerException
136     {
137         if ( executeOnEntireRepo )
138         {
139             beginScan( repository, whenGathered );
140         }
141         else
142         {
143             this.repository = repository;
144             managedRepository = new File( repository.getLocation() );
145         }
146     }
147
148     @Override
149     public void processFile( String path )
150         throws ConsumerException
151     {
152         File artifactFile = new File( managedRepository, path );
153
154         ArtifactIndexingTask task =
155             new ArtifactIndexingTask( repository, artifactFile, ArtifactIndexingTask.Action.ADD, getIndexingContext() );
156         try
157         {
158             log.debug( "Queueing indexing task '{}' to add or update the artifact in the index.", task );
159             scheduler.queueTask( task );
160         }
161         catch ( TaskQueueException e )
162         {
163             throw new ConsumerException( e.getMessage(), e );
164         }
165     }
166
167     @Override
168     public void processFile( String path, boolean executeOnEntireRepo )
169         throws Exception
170     {
171         if ( executeOnEntireRepo )
172         {
173             processFile( path );
174         }
175         else
176         {
177             File artifactFile = new File( managedRepository, path );
178
179             // specify in indexing task that this is not a repo scan request!
180             ArtifactIndexingTask task =
181                 new ArtifactIndexingTask( repository, artifactFile, ArtifactIndexingTask.Action.ADD,
182                                           getIndexingContext(), false );
183             // only update index we don't need to scan the full repo here
184             task.setOnlyUpdate( true );
185             try
186             {
187                 log.debug( "Queueing indexing task '{}' to add or update the artifact in the index.", task );
188                 scheduler.queueTask( task );
189             }
190             catch ( TaskQueueException e )
191             {
192                 throw new ConsumerException( e.getMessage(), e );
193             }
194         }
195     }
196
197     @Override
198     public void completeScan()
199     {
200         IndexingContext context = this.indexingContext;
201         if ( context == null )
202         {
203             try
204             {
205                 context = getIndexingContext();
206             }
207             catch ( ConsumerException e )
208             {
209                 log.warn( "failed to get an IndexingContext:{}", e.getMessage() );
210                 return;
211             }
212         }
213         ArtifactIndexingTask task =
214             new ArtifactIndexingTask( repository, null, ArtifactIndexingTask.Action.FINISH, context );
215         try
216         {
217             log.debug( "Queueing indexing task '{}' to finish indexing.", task );
218             scheduler.queueTask( task );
219         }
220         catch ( TaskQueueException e )
221         {
222             log.error( "Error queueing task: " + task + ": " + e.getMessage(), e );
223         }
224     }
225
226     @Override
227     public void completeScan( boolean executeOnEntireRepo )
228     {
229         if ( executeOnEntireRepo )
230         {
231             completeScan();
232         }
233
234         // else, do nothing as the context will be closed when indexing task is executed if not a repo scan request!
235     }
236
237     @Override
238     public List<String> getExcludes()
239     {
240         return Collections.emptyList();
241     }
242
243     @Override
244     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
245     {
246         if ( ConfigurationNames.isRepositoryScanning( propertyName ) )
247         {
248             initIncludes();
249         }
250     }
251
252     @Override
253     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
254     {
255         /* do nothing */
256     }
257
258     private void initIncludes()
259     {
260         List<String> indexable = filetypes.getFileTypePatterns( FileTypes.INDEXABLE_CONTENT );
261         List<String> artifacts = filetypes.getFileTypePatterns( FileTypes.ARTIFACTS );
262
263         includes = new ArrayList<>( indexable.size() + artifacts.size() );
264
265         includes.addAll( indexable );
266
267         includes.addAll( artifacts );
268     }
269
270     @PostConstruct
271     public void initialize()
272     {
273         configuration.addChangeListener( this );
274
275         initIncludes();
276     }
277
278     @Override
279     public List<String> getIncludes()
280     {
281         return includes;
282     }
283
284
285     private IndexingContext getIndexingContext()
286         throws ConsumerException
287     {
288
289         if ( this.indexingContext == null )
290         {
291             try
292             {
293                 indexingContext = managedRepositoryAdmin.createIndexContext( repository );
294             }
295             catch ( RepositoryAdminException e )
296             {
297                 throw new ConsumerException( e.getMessage(), e );
298             }
299         }
300         return indexingContext;
301     }
302 }