]> source.dussan.org Git - archiva.git/blob
e97de6ff8d3173ff70d76af4bd7a189c7d9ebbd4
[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 import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
23 import org.apache.archiva.common.plexusbridge.MavenIndexerUtils;
24 import org.apache.archiva.common.plexusbridge.PlexusSisuBridge;
25 import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException;
26 import org.apache.commons.io.FileUtils;
27 import org.apache.commons.lang.time.StopWatch;
28 import org.apache.maven.index.NexusIndexer;
29 import org.apache.maven.index.context.IndexingContext;
30 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
31 import org.apache.maven.index.packer.IndexPacker;
32 import org.apache.maven.index.packer.IndexPackingRequest;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.springframework.scheduling.annotation.Async;
36 import org.springframework.stereotype.Service;
37
38 import javax.annotation.PostConstruct;
39 import javax.inject.Inject;
40 import java.io.File;
41 import java.io.IOException;
42 import java.util.Collection;
43 import java.util.List;
44 import java.util.concurrent.CopyOnWriteArrayList;
45
46 /**
47  * @author Olivier Lamy
48  * @since 1.4-M2
49  */
50 @Service("indexMerger#default")
51 public class DefaultIndexMerger
52     implements IndexMerger
53 {
54
55     /**
56      * default tmp created group index ttl in minutes
57      */
58     static final int DEFAULT_GROUP_INDEX_TTL = 30;
59
60     private Logger log = LoggerFactory.getLogger( getClass() );
61
62     @Inject
63     private ManagedRepositoryAdmin managedRepositoryAdmin;
64
65     private MavenIndexerUtils mavenIndexerUtils;
66
67     private NexusIndexer indexer;
68
69     private IndexPacker indexPacker;
70
71     private List<TemporaryGroupIndex> temporaryGroupIndexes = new CopyOnWriteArrayList<TemporaryGroupIndex>();
72
73     private int groupMergedIndexTtl;
74
75     @Inject
76     public DefaultIndexMerger( PlexusSisuBridge plexusSisuBridge, MavenIndexerUtils mavenIndexerUtils )
77         throws PlexusSisuBridgeException
78     {
79         this.indexer = plexusSisuBridge.lookup( NexusIndexer.class );
80         this.mavenIndexerUtils = mavenIndexerUtils;
81         indexPacker = plexusSisuBridge.lookup( IndexPacker.class, "default" );
82     }
83
84     @PostConstruct
85     public void intialize()
86     {
87         this.groupMergedIndexTtl = Integer.getInteger( IndexMerger.TMP_GROUP_INDEX_SYS_KEY, DEFAULT_GROUP_INDEX_TTL );
88     }
89
90     public IndexingContext buildMergedIndex( IndexMergerRequest indexMergerRequest )
91         throws IndexMergerException
92     {
93         StopWatch stopWatch = new StopWatch();
94         stopWatch.reset();
95         stopWatch.start();
96         File tempRepoFile = Files.createTempDir();
97         tempRepoFile.deleteOnExit();
98
99         String tempRepoId = tempRepoFile.getName();
100
101         try
102         {
103             File indexLocation = new File( tempRepoFile, indexMergerRequest.getMergedIndexPath() );
104             IndexingContext indexingContext =
105                 indexer.addIndexingContext( tempRepoId, tempRepoId, tempRepoFile, 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             temporaryGroupIndexes.add(
125                 new TemporaryGroupIndex( tempRepoFile, tempRepoId, indexMergerRequest.getGroupId(), indexMergerRequest.getMergedIndexTtl() ) );
126             stopWatch.stop();
127             log.info( "merged index for repos {} in {} s", indexMergerRequest.getRepositoriesIds(),
128                       stopWatch.getTime() );
129             return indexingContext;
130         }
131         catch ( IOException e )
132         {
133             throw new IndexMergerException( e.getMessage(), e );
134         }
135         catch ( UnsupportedExistingLuceneIndexException e )
136         {
137             throw new IndexMergerException( e.getMessage(), e );
138         }
139     }
140
141     @Async
142     public void cleanTemporaryGroupIndex( TemporaryGroupIndex temporaryGroupIndex )
143     {
144         if ( temporaryGroupIndex == null )
145         {
146             return;
147         }
148
149         try
150         {
151             IndexingContext indexingContext = indexer.getIndexingContexts().get( temporaryGroupIndex.getIndexId() );
152             if ( indexingContext != null )
153             {
154                 indexer.removeIndexingContext( indexingContext, true );
155             }
156             File directory = temporaryGroupIndex.getDirectory();
157             if ( directory != null && directory.exists() )
158             {
159                 FileUtils.deleteDirectory( directory );
160             }
161             temporaryGroupIndexes.remove( temporaryGroupIndex );
162         }
163         catch ( IOException e )
164         {
165             log.warn( "fail to delete temporary group index {}", temporaryGroupIndex.getIndexId(), e );
166         }
167     }
168
169     public Collection<TemporaryGroupIndex> getTemporaryGroupIndexes()
170     {
171         return this.temporaryGroupIndexes;
172     }
173
174     public int getGroupMergedIndexTtl()
175     {
176         return this.groupMergedIndexTtl;
177     }
178 }