]> source.dussan.org Git - archiva.git/blob
bc39b8da4056bf294076e91f489e8daa2d6d2bba
[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 com.google.common.io.Files;
22
23 import org.apache.archiva.admin.model.RepositoryAdminException;
24 import org.apache.archiva.admin.model.beans.RepositoryGroup;
25 import org.apache.archiva.admin.model.group.RepositoryGroupAdmin;
26 import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
27 import org.apache.archiva.common.plexusbridge.MavenIndexerUtils;
28 import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
29 import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
30 import org.apache.commons.io.FileUtils;
31 import org.apache.commons.lang.StringUtils;
32 import org.apache.commons.lang.time.StopWatch;
33 import org.apache.maven.index.NexusIndexer;
34 import org.apache.maven.index.context.IndexingContext;
35 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
36 import org.apache.maven.index.packer.IndexPacker;
37 import org.apache.maven.index.packer.IndexPackingRequest;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40 import org.springframework.scheduling.annotation.Async;
41 import org.springframework.stereotype.Service;
42
43 import javax.inject.Inject;
44 import java.io.File;
45 import java.io.IOException;
46 import java.util.Collection;
47 import java.util.List;
48 import java.util.concurrent.CopyOnWriteArrayList;
49
50 /**
51  * @author Olivier Lamy
52  * @since 1.4-M2
53  */
54 @Service("indexMerger#default")
55 public class DefaultIndexMerger
56     implements IndexMerger
57 {
58
59     private Logger log = LoggerFactory.getLogger( getClass() );
60
61     private MavenIndexerUtils mavenIndexerUtils;
62
63     private NexusIndexer indexer;
64
65     private IndexPacker indexPacker;
66
67     private List<TemporaryGroupIndex> temporaryGroupIndexes = new CopyOnWriteArrayList<TemporaryGroupIndex>();
68
69     private List<String> runningGroups = new CopyOnWriteArrayList<String>();
70
71     @Inject
72     public DefaultIndexMerger( PlexusSisuBridge plexusSisuBridge, MavenIndexerUtils mavenIndexerUtils )
73         throws PlexusSisuBridgeException
74     {
75         this.indexer = plexusSisuBridge.lookup( NexusIndexer.class );
76         this.mavenIndexerUtils = mavenIndexerUtils;
77         indexPacker = plexusSisuBridge.lookup( IndexPacker.class, "default" );
78     }
79
80     public IndexingContext buildMergedIndex( IndexMergerRequest indexMergerRequest )
81         throws IndexMergerException
82     {
83         String groupId = indexMergerRequest.getGroupId();
84
85         if ( runningGroups.contains( groupId ) )
86         {
87             log.info( "skip build merge remote indexes for id: '{}' as already running", groupId );
88             return null;
89         }
90
91         runningGroups.add( groupId );
92
93         StopWatch stopWatch = new StopWatch();
94         stopWatch.reset();
95         stopWatch.start();
96
97         File mergedIndexDirectory = indexMergerRequest.getMergedIndexDirectory();
98
99         String tempRepoId = mergedIndexDirectory.getName();
100
101         try
102         {
103             File indexLocation = new File( mergedIndexDirectory, indexMergerRequest.getMergedIndexPath() );
104             IndexingContext indexingContext =
105                 indexer.addIndexingContext( tempRepoId, tempRepoId, mergedIndexDirectory, indexLocation, null, null,
106                                             mavenIndexerUtils.getAllIndexCreators() );
107
108             for ( String repoId : indexMergerRequest.getRepositoriesIds() )
109             {
110                 IndexingContext idxToMerge = indexer.getIndexingContexts().get( repoId );
111                 if ( idxToMerge != null )
112                 {
113                     indexingContext.merge( idxToMerge.getIndexDirectory() );
114                 }
115             }
116
117             indexingContext.optimize();
118
119             if ( indexMergerRequest.isPackIndex() )
120             {
121                 IndexPackingRequest request = new IndexPackingRequest( indexingContext, indexLocation );
122                 indexPacker.packIndex( request );
123             }
124
125             if ( indexMergerRequest.isTemporary() )
126             {
127                 temporaryGroupIndexes.add( new TemporaryGroupIndex( mergedIndexDirectory, tempRepoId, groupId,
128                                                                     indexMergerRequest.getMergedIndexTtl() ) );
129             }
130             stopWatch.stop();
131             log.info( "merged index for repos {} in {} s", indexMergerRequest.getRepositoriesIds(),
132                       stopWatch.getTime() );
133             return indexingContext;
134         }
135         catch ( IOException e )
136         {
137             throw new IndexMergerException( e.getMessage(), e );
138         }
139         catch ( UnsupportedExistingLuceneIndexException e )
140         {
141             throw new IndexMergerException( e.getMessage(), e );
142         }
143         finally
144         {
145             runningGroups.remove( groupId );
146         }
147     }
148
149     @Async
150     public void cleanTemporaryGroupIndex( TemporaryGroupIndex temporaryGroupIndex )
151     {
152         if ( temporaryGroupIndex == null )
153         {
154             return;
155         }
156
157         try
158         {
159             IndexingContext indexingContext = indexer.getIndexingContexts().get( temporaryGroupIndex.getIndexId() );
160             if ( indexingContext != null )
161             {
162                 indexer.removeIndexingContext( indexingContext, true );
163             }
164             File directory = temporaryGroupIndex.getDirectory();
165             if ( directory != null && directory.exists() )
166             {
167                 FileUtils.deleteDirectory( directory );
168             }
169             temporaryGroupIndexes.remove( temporaryGroupIndex );
170         }
171         catch ( IOException e )
172         {
173             log.warn( "fail to delete temporary group index {}", temporaryGroupIndex.getIndexId(), e );
174         }
175     }
176
177     public Collection<TemporaryGroupIndex> getTemporaryGroupIndexes()
178     {
179         return this.temporaryGroupIndexes;
180     }
181 }