]> source.dussan.org Git - archiva.git/blob
293b73b71c6b8f065b757429008491d229f73ae2
[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.utils.FileUtils;
22 import org.apache.archiva.indexer.ArchivaIndexManager;
23 import org.apache.archiva.indexer.ArchivaIndexingContext;
24 import org.apache.archiva.indexer.IndexCreationFailedException;
25 import org.apache.archiva.indexer.merger.IndexMerger;
26 import org.apache.archiva.indexer.merger.IndexMergerException;
27 import org.apache.archiva.indexer.merger.IndexMergerRequest;
28 import org.apache.archiva.indexer.merger.TemporaryGroupIndex;
29 import org.apache.archiva.repository.Repository;
30 import org.apache.archiva.repository.RepositoryRegistry;
31 import org.apache.commons.lang.time.StopWatch;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
34 import org.springframework.scheduling.annotation.Async;
35 import org.springframework.stereotype.Service;
36
37 import javax.inject.Inject;
38 import java.io.IOException;
39 import java.nio.file.Files;
40 import java.nio.file.Path;
41 import java.util.Collection;
42 import java.util.List;
43 import java.util.Optional;
44 import java.util.concurrent.CopyOnWriteArrayList;
45 import java.util.stream.Collectors;
46
47 /**
48  * @author Olivier Lamy
49  * @since 1.4-M2
50  */
51 @Service("indexMerger#default")
52 public class DefaultIndexMerger
53     implements IndexMerger
54 {
55
56     @Inject
57     RepositoryRegistry repositoryRegistry;
58
59     private Logger log = LoggerFactory.getLogger( getClass() );
60
61     private List<TemporaryGroupIndex> temporaryGroupIndexes = new CopyOnWriteArrayList<>();
62
63     private List<ArchivaIndexingContext>  temporaryContextes = new CopyOnWriteArrayList<>(  );
64
65     private List<String> runningGroups = new CopyOnWriteArrayList<>();
66
67     @Inject
68     public DefaultIndexMerger( )
69     {
70     }
71
72     @Override
73     public ArchivaIndexingContext 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         StopWatch stopWatch = new StopWatch();
86         try {
87             stopWatch.reset();
88             stopWatch.start();
89
90             Path mergedIndexDirectory = indexMergerRequest.getMergedIndexDirectory();
91             Repository destinationRepository = repositoryRegistry.getRepository(indexMergerRequest.getGroupId());
92
93             ArchivaIndexManager idxManager = repositoryRegistry.getIndexManager(destinationRepository.getType());
94             List<ArchivaIndexingContext> sourceContexts = indexMergerRequest.getRepositoriesIds().stream().map(id -> repositoryRegistry.getRepository(id).getIndexingContext()).collect(Collectors.toList());
95             try {
96                 ArchivaIndexingContext result = idxManager.mergeContexts(destinationRepository, sourceContexts, indexMergerRequest.isPackIndex());
97                 if ( indexMergerRequest.isTemporary() )
98                 {
99                     String tempRepoId = destinationRepository.getId()+System.currentTimeMillis();
100                     temporaryGroupIndexes.add( new TemporaryGroupIndex( mergedIndexDirectory, tempRepoId, groupId,
101                             indexMergerRequest.getMergedIndexTtl() ) );
102                     temporaryContextes.add(result);
103                 }
104                 return result;
105             } catch (IndexCreationFailedException e) {
106                 throw new IndexMergerException("Index merging failed " + e.getMessage(), e);
107             }
108
109         } finally {
110             stopWatch.stop();
111             log.info( "merged index for repos {} in {} s", indexMergerRequest.getRepositoriesIds(),
112                     stopWatch.getTime() );
113             runningGroups.remove(groupId);
114         }
115     }
116
117     @Async
118     @Override
119     public void cleanTemporaryGroupIndex( TemporaryGroupIndex temporaryGroupIndex )
120     {
121         if ( temporaryGroupIndex == null )
122         {
123             return;
124         }
125
126         try
127         {
128             Optional<ArchivaIndexingContext> ctxOpt = temporaryContextes.stream( ).filter( ctx -> ctx.getId( ).equals( temporaryGroupIndex.getIndexId( ) ) ).findFirst( );
129             if (ctxOpt.isPresent()) {
130                 ArchivaIndexingContext ctx = ctxOpt.get();
131                 ctx.close(true);
132                 temporaryGroupIndexes.remove( temporaryGroupIndex );
133                 temporaryContextes.remove( ctx );
134                 Path directory = temporaryGroupIndex.getDirectory();
135                 if ( directory != null && Files.exists(directory) )
136                 {
137                     FileUtils.deleteDirectory( directory );
138                 }
139             }
140         }
141         catch ( IOException e )
142         {
143             log.warn( "fail to delete temporary group index {}", temporaryGroupIndex.getIndexId(), e );
144         }
145     }
146
147     @Override
148     public Collection<TemporaryGroupIndex> getTemporaryGroupIndexes()
149     {
150         return this.temporaryGroupIndexes;
151     }
152 }