This project has retired. For details please refer to its
Attic page.
DefaultIndexMerger xref
1 package org.apache.archiva.indexer.maven.merger;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import org.apache.archiva.common.utils.FileUtils;
22 import org.apache.archiva.indexer.UnsupportedBaseContextException;
23 import org.apache.archiva.indexer.merger.IndexMerger;
24 import org.apache.archiva.indexer.merger.IndexMergerException;
25 import org.apache.archiva.indexer.merger.IndexMergerRequest;
26 import org.apache.archiva.indexer.merger.TemporaryGroupIndex;
27 import org.apache.archiva.repository.RepositoryRegistry;
28 import org.apache.archiva.repository.RepositoryType;
29 import org.apache.commons.lang.time.StopWatch;
30 import org.apache.maven.index.Indexer;
31 import org.apache.maven.index.context.ContextMemberProvider;
32 import org.apache.maven.index.context.IndexCreator;
33 import org.apache.maven.index.context.IndexingContext;
34 import org.apache.maven.index.context.StaticContextMemberProvider;
35 import org.apache.maven.index.packer.IndexPacker;
36 import org.apache.maven.index.packer.IndexPackingRequest;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39 import org.springframework.scheduling.annotation.Async;
40 import org.springframework.stereotype.Service;
41
42 import javax.inject.Inject;
43 import java.io.IOException;
44 import java.nio.file.Files;
45 import java.nio.file.Path;
46 import java.util.Collection;
47 import java.util.List;
48 import java.util.Objects;
49 import java.util.Optional;
50 import java.util.concurrent.CopyOnWriteArrayList;
51 import java.util.stream.Collectors;
52
53
54
55
56
57 @Service("indexMerger#default")
58 public class DefaultIndexMerger
59 implements IndexMerger
60 {
61
62 @Inject
63 RepositoryRegistry repositoryRegistry;
64
65 private Logger log = LoggerFactory.getLogger( getClass() );
66
67
68 private final IndexPacker indexPacker;
69
70 private Indexer indexer;
71
72 private final List<IndexCreator> indexCreators;
73
74 private List<TemporaryGroupIndex> temporaryGroupIndexes = new CopyOnWriteArrayList<>();
75
76 private List<IndexingContext> temporaryContextes = new CopyOnWriteArrayList<>( );
77
78 private List<String> runningGroups = new CopyOnWriteArrayList<>();
79
80 @Inject
81 public DefaultIndexMerger( Indexer indexer, IndexPacker indexPacker, List<IndexCreator> indexCreators )
82 {
83 this.indexer = indexer;
84 this.indexPacker = indexPacker;
85 this.indexCreators = indexCreators;
86 }
87
88 @Override
89 public IndexingContext buildMergedIndex( IndexMergerRequest indexMergerRequest )
90 throws IndexMergerException
91 {
92 String groupId = indexMergerRequest.getGroupId();
93
94 if ( runningGroups.contains( groupId ) )
95 {
96 log.info( "skip build merge remote indexes for id: '{}' as already running", groupId );
97 return null;
98 }
99
100 runningGroups.add( groupId );
101
102 StopWatch stopWatch = new StopWatch();
103 stopWatch.reset();
104 stopWatch.start();
105
106 Path mergedIndexDirectory = indexMergerRequest.getMergedIndexDirectory();
107
108 String tempRepoId = mergedIndexDirectory.getFileName().toString();
109
110 try
111 {
112 Path indexLocation = mergedIndexDirectory.resolve( indexMergerRequest.getMergedIndexPath() );
113
114 List<IndexingContext> members = indexMergerRequest.getRepositoriesIds( ).stream( ).map( id ->
115 repositoryRegistry.getRepository( id ) ).filter( repo -> repo.getType().equals( RepositoryType.MAVEN ) )
116 .map( repo -> {
117 try
118 {
119 return repo.getIndexingContext().getBaseContext( IndexingContext.class );
120 }
121 catch ( UnsupportedBaseContextException e )
122 {
123 return null;
124
125 }
126 } ).filter( Objects::nonNull ).collect( Collectors.toList() );
127 ContextMemberProvider memberProvider = new StaticContextMemberProvider(members);
128 IndexingContext mergedCtx = indexer.createMergedIndexingContext( tempRepoId, tempRepoId, mergedIndexDirectory.toFile(),
129 indexLocation.toFile(), true, memberProvider);
130 mergedCtx.optimize();
131
132 if ( indexMergerRequest.isPackIndex() )
133 {
134 IndexPackingRequest request = new IndexPackingRequest( mergedCtx,
135 mergedCtx.acquireIndexSearcher().getIndexReader(),
136 indexLocation.toFile() );
137 indexPacker.packIndex( request );
138 }
139
140 if ( indexMergerRequest.isTemporary() )
141 {
142 temporaryGroupIndexes.add( new TemporaryGroupIndex( mergedIndexDirectory, tempRepoId, groupId,
143 indexMergerRequest.getMergedIndexTtl() ) );
144 temporaryContextes.add(mergedCtx);
145 }
146 stopWatch.stop();
147 log.info( "merged index for repos {} in {} s", indexMergerRequest.getRepositoriesIds(),
148 stopWatch.getTime() );
149 return mergedCtx;
150 }
151 catch ( IOException e)
152 {
153 throw new IndexMergerException( e.getMessage(), e );
154 }
155 finally
156 {
157 runningGroups.remove( groupId );
158 }
159 }
160
161 @Async
162 @Override
163 public void cleanTemporaryGroupIndex( TemporaryGroupIndex temporaryGroupIndex )
164 {
165 if ( temporaryGroupIndex == null )
166 {
167 return;
168 }
169
170 try
171 {
172
173 Optional<IndexingContext> ctxOpt = temporaryContextes.stream( ).filter( ctx -> ctx.getId( ).equals( temporaryGroupIndex.getIndexId( ) ) ).findFirst( );
174 if (ctxOpt.isPresent()) {
175 IndexingContext ctx = ctxOpt.get();
176 indexer.closeIndexingContext( ctx, true );
177 temporaryGroupIndexes.remove( temporaryGroupIndex );
178 temporaryContextes.remove( ctx );
179 Path directory = temporaryGroupIndex.getDirectory();
180 if ( directory != null && Files.exists(directory) )
181 {
182 FileUtils.deleteDirectory( directory );
183 }
184 }
185 }
186 catch ( IOException e )
187 {
188 log.warn( "fail to delete temporary group index {}", temporaryGroupIndex.getIndexId(), e );
189 }
190 }
191
192 @Override
193 public Collection<TemporaryGroupIndex> getTemporaryGroupIndexes()
194 {
195 return this.temporaryGroupIndexes;
196 }
197 }