This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.consumers.lucene;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.archiva.admin.model.RepositoryAdminException;
023import org.apache.archiva.admin.model.beans.ManagedRepository;
024import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
025import org.apache.archiva.common.plexusbridge.MavenIndexerUtils;
026import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
027import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
028import org.apache.archiva.configuration.ArchivaConfiguration;
029import org.apache.archiva.configuration.ConfigurationNames;
030import org.apache.archiva.configuration.FileTypes;
031import org.apache.archiva.consumers.AbstractMonitoredConsumer;
032import org.apache.archiva.consumers.ConsumerException;
033import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
034import org.apache.archiva.redback.components.registry.Registry;
035import org.apache.archiva.scheduler.ArchivaTaskScheduler;
036import org.apache.archiva.scheduler.indexing.ArtifactIndexingTask;
037import org.apache.maven.index.NexusIndexer;
038import org.apache.maven.index.context.IndexCreator;
039import org.apache.maven.index.context.IndexingContext;
040import org.apache.archiva.redback.components.registry.RegistryListener;
041import org.apache.archiva.redback.components.taskqueue.TaskQueueException;
042import org.slf4j.Logger;
043import org.slf4j.LoggerFactory;
044import org.springframework.context.annotation.Scope;
045import org.springframework.stereotype.Service;
046
047import javax.annotation.PostConstruct;
048import javax.inject.Inject;
049import javax.inject.Named;
050import java.io.File;
051import java.util.ArrayList;
052import java.util.Collections;
053import java.util.Date;
054import java.util.List;
055
056/**
057 * Consumer for indexing the repository to provide search and IDE integration features.
058 */
059@Service( "knownRepositoryContentConsumer#index-content" )
060@Scope( "prototype" )
061public class NexusIndexerConsumer
062    extends AbstractMonitoredConsumer
063    implements KnownRepositoryContentConsumer, RegistryListener
064{
065    private Logger log = LoggerFactory.getLogger( getClass() );
066
067    private ArchivaConfiguration configuration;
068
069    private FileTypes filetypes;
070
071    private File managedRepository;
072
073    private ArchivaTaskScheduler<ArtifactIndexingTask> scheduler;
074
075    private IndexingContext indexingContext;
076
077    private NexusIndexer nexusIndexer;
078
079    private List<String> includes = new ArrayList<>( 0 );
080
081    private ManagedRepository repository;
082
083    private List<? extends IndexCreator> allIndexCreators;
084
085    private ManagedRepositoryAdmin managedRepositoryAdmin;
086
087    @Inject
088    public NexusIndexerConsumer(
089        @Named( value = "archivaTaskScheduler#indexing" ) ArchivaTaskScheduler<ArtifactIndexingTask> scheduler,
090        @Named( value = "archivaConfiguration" ) ArchivaConfiguration configuration, FileTypes filetypes,
091        PlexusSisuBridge plexusSisuBridge, MavenIndexerUtils mavenIndexerUtils,
092        ManagedRepositoryAdmin managedRepositoryAdmin )
093        throws PlexusSisuBridgeException
094    {
095        this.configuration = configuration;
096        this.filetypes = filetypes;
097        this.scheduler = scheduler;
098        this.nexusIndexer = plexusSisuBridge.lookup( NexusIndexer.class );
099        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}