]> source.dussan.org Git - archiva.git/blob
663f0b63abef0adae9f4873b11728d6ed80713cc
[archiva.git] /
1 package org.apache.archiva.indexer.merger;
2 /*
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  */
20
21 import org.apache.archiva.common.plexusbridge.MavenIndexerUtils;
22 import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
23 import org.apache.commons.io.FileUtils;
24 import org.apache.commons.lang.time.StopWatch;
25 import org.apache.maven.index.NexusIndexer;
26 import org.apache.maven.index.context.IndexingContext;
27 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
28 import org.apache.maven.index.packer.IndexPacker;
29 import org.apache.maven.index.packer.IndexPackingRequest;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32 import org.springframework.scheduling.annotation.Async;
33 import org.springframework.stereotype.Service;
34
35 import javax.inject.Inject;
36 import java.io.File;
37 import java.io.IOException;
38 import java.util.Collection;
39 import java.util.List;
40 import java.util.concurrent.CopyOnWriteArrayList;
41
42 /**
43  * @author Olivier Lamy
44  * @since 1.4-M2
45  */
46 @Service("indexMerger#default")
47 public class DefaultIndexMerger
48     implements IndexMerger
49 {
50
51     private Logger log = LoggerFactory.getLogger( getClass() );
52
53     private MavenIndexerUtils mavenIndexerUtils;
54
55     private NexusIndexer indexer;
56
57     private IndexPacker indexPacker;
58
59     private List<TemporaryGroupIndex> temporaryGroupIndexes = new CopyOnWriteArrayList<>();
60
61     private List<String> runningGroups = new CopyOnWriteArrayList<String>();
62
63     @Inject
64     public DefaultIndexMerger( NexusIndexer nexusIndexer, IndexPacker indexPacker, MavenIndexerUtils mavenIndexerUtils )
65         throws PlexusSisuBridgeException
66     {
67         this.indexer = nexusIndexer;
68         this.mavenIndexerUtils = mavenIndexerUtils;
69         this.indexPacker = indexPacker;
70     }
71
72     @Override
73     public IndexingContext buildMergedIndex( IndexMergerRequest indexMergerRequest )
74         throws IndexMergerException
75     {
76         String groupId = indexMergerRequest.getGroupId();
77
78         if ( runningGroups.contains( groupId ) )
79         {
80             log.info( "skip build merge remote indexes for id: '{}' as already running", groupId );
81             return null;
82         }
83
84         runningGroups.add( groupId );
85
86         StopWatch stopWatch = new StopWatch();
87         stopWatch.reset();
88         stopWatch.start();
89
90         File mergedIndexDirectory = indexMergerRequest.getMergedIndexDirectory();
91
92         String tempRepoId = mergedIndexDirectory.getName();
93
94         try
95         {
96             File indexLocation = new File( mergedIndexDirectory, indexMergerRequest.getMergedIndexPath() );
97             IndexingContext indexingContext =
98                 indexer.addIndexingContext( tempRepoId, tempRepoId, mergedIndexDirectory, indexLocation, null, null,
99                                             mavenIndexerUtils.getAllIndexCreators() );
100
101             for ( String repoId : indexMergerRequest.getRepositoriesIds() )
102             {
103                 IndexingContext idxToMerge = indexer.getIndexingContexts().get( repoId );
104                 if ( idxToMerge != null )
105                 {
106                     indexingContext.merge( idxToMerge.getIndexDirectory() );
107                 }
108             }
109
110             indexingContext.optimize();
111
112             if ( indexMergerRequest.isPackIndex() )
113             {
114                 IndexPackingRequest request = new IndexPackingRequest( indexingContext, //
115                                                                        indexingContext.acquireIndexSearcher().getIndexReader(), //
116                                                                        indexLocation );
117                 indexPacker.packIndex( request );
118             }
119
120             if ( indexMergerRequest.isTemporary() )
121             {
122                 temporaryGroupIndexes.add( new TemporaryGroupIndex( mergedIndexDirectory, tempRepoId, groupId,
123                                                                     indexMergerRequest.getMergedIndexTtl() ) );
124             }
125             stopWatch.stop();
126             log.info( "merged index for repos {} in {} s", indexMergerRequest.getRepositoriesIds(),
127                       stopWatch.getTime() );
128             return indexingContext;
129         }
130         catch ( IOException e )
131         {
132             throw new IndexMergerException( e.getMessage(), e );
133         }
134         catch ( UnsupportedExistingLuceneIndexException e )
135         {
136             throw new IndexMergerException( e.getMessage(), e );
137         }
138         finally
139         {
140             runningGroups.remove( groupId );
141         }
142     }
143
144     @Async
145     @Override
146     public void cleanTemporaryGroupIndex( TemporaryGroupIndex temporaryGroupIndex )
147     {
148         if ( temporaryGroupIndex == null )
149         {
150             return;
151         }
152
153         try
154         {
155             IndexingContext indexingContext = indexer.getIndexingContexts().get( temporaryGroupIndex.getIndexId() );
156             if ( indexingContext != null )
157             {
158                 indexer.removeIndexingContext( indexingContext, true );
159             }
160             File directory = temporaryGroupIndex.getDirectory();
161             if ( directory != null && directory.exists() )
162             {
163                 FileUtils.deleteDirectory( directory );
164             }
165             temporaryGroupIndexes.remove( temporaryGroupIndex );
166         }
167         catch ( IOException e )
168         {
169             log.warn( "fail to delete temporary group index {}", temporaryGroupIndex.getIndexId(), e );
170         }
171     }
172
173     @Override
174     public Collection<TemporaryGroupIndex> getTemporaryGroupIndexes()
175     {
176         return this.temporaryGroupIndexes;
177     }
178 }