This project has retired. For details please refer to its Attic page.
DefaultIndexMerger xref
View Javadoc
1   package org.apache.archiva.indexer.merger.base;
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.indexer.ArchivaIndexManager;
22  import org.apache.archiva.indexer.ArchivaIndexingContext;
23  import org.apache.archiva.indexer.IndexCreationFailedException;
24  import org.apache.archiva.indexer.merger.IndexMerger;
25  import org.apache.archiva.indexer.merger.IndexMergerException;
26  import org.apache.archiva.indexer.merger.IndexMergerRequest;
27  import org.apache.archiva.indexer.merger.TemporaryGroupIndex;
28  import org.apache.archiva.repository.Repository;
29  import org.apache.archiva.repository.RepositoryRegistry;
30  import org.apache.archiva.repository.storage.StorageAsset;
31  import org.apache.archiva.repository.storage.StorageUtil;
32  import org.apache.commons.lang3.time.StopWatch;
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.inject.Inject;
39  import java.io.IOException;
40  import java.util.Collection;
41  import java.util.List;
42  import java.util.Optional;
43  import java.util.concurrent.CopyOnWriteArrayList;
44  import java.util.stream.Collectors;
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      @Inject
56      RepositoryRegistry repositoryRegistry;
57  
58      private Logger log = LoggerFactory.getLogger( getClass() );
59  
60      private List<TemporaryGroupIndex> temporaryGroupIndexes = new CopyOnWriteArrayList<>();
61  
62      private List<ArchivaIndexingContext>  temporaryContextes = new CopyOnWriteArrayList<>(  );
63  
64      private List<String> runningGroups = new CopyOnWriteArrayList<>();
65  
66      @Inject
67      public DefaultIndexMerger( )
68      {
69      }
70  
71      @Override
72      public ArchivaIndexingContext buildMergedIndex(IndexMergerRequest indexMergerRequest )
73          throws IndexMergerException
74      {
75          String groupId = indexMergerRequest.getGroupId();
76  
77          if ( runningGroups.contains( groupId ) )
78          {
79              log.info( "skip build merge remote indexes for id: '{}' as already running", groupId );
80              return null;
81          }
82  
83          runningGroups.add( groupId );
84          StopWatch stopWatch = new StopWatch();
85          try {
86              stopWatch.reset();
87              stopWatch.start();
88  
89              StorageAsset mergedIndexDirectory = indexMergerRequest.getMergedIndexDirectory();
90              Repository destinationRepository = repositoryRegistry.getRepository(indexMergerRequest.getGroupId());
91  
92              ArchivaIndexManager idxManager = repositoryRegistry.getIndexManager(destinationRepository.getType());
93              List<ArchivaIndexingContext> sourceContexts = indexMergerRequest.getRepositoriesIds().stream().map(id -> repositoryRegistry.getRepository(id).getIndexingContext()).collect(Collectors.toList());
94              try {
95                  ArchivaIndexingContext result = idxManager.mergeContexts(destinationRepository, sourceContexts, indexMergerRequest.isPackIndex());
96                  if ( indexMergerRequest.isTemporary() )
97                  {
98                      String tempRepoId = destinationRepository.getId()+System.currentTimeMillis();
99                      temporaryGroupIndexes.add( new TemporaryGroupIndex( mergedIndexDirectory, tempRepoId, groupId,
100                             indexMergerRequest.getMergedIndexTtl() ) );
101                     temporaryContextes.add(result);
102                 }
103                 return result;
104             } catch (IndexCreationFailedException e) {
105                 throw new IndexMergerException("Index merging failed " + e.getMessage(), e);
106             }
107 
108         } finally {
109             stopWatch.stop();
110             log.info( "merged index for repos {} in {} s", indexMergerRequest.getRepositoriesIds(),
111                     stopWatch.getTime() );
112             runningGroups.remove(groupId);
113         }
114     }
115 
116     @Async
117     @Override
118     public void cleanTemporaryGroupIndex( TemporaryGroupIndex temporaryGroupIndex )
119     {
120         if ( temporaryGroupIndex == null )
121         {
122             return;
123         }
124 
125         try
126         {
127             Optional<ArchivaIndexingContext> ctxOpt = temporaryContextes.stream( ).filter( ctx -> ctx.getId( ).equals( temporaryGroupIndex.getIndexId( ) ) ).findFirst( );
128             if (ctxOpt.isPresent()) {
129                 ArchivaIndexingContext ctx = ctxOpt.get();
130                 ctx.close(true);
131                 temporaryGroupIndexes.remove( temporaryGroupIndex );
132                 temporaryContextes.remove( ctx );
133                 StorageAsset directory = temporaryGroupIndex.getDirectory();
134                 if ( directory != null && directory.exists() )
135                 {
136                     StorageUtil.deleteRecursively( directory );
137                 }
138             }
139         }
140         catch ( IOException e )
141         {
142             log.warn( "fail to delete temporary group index {}", temporaryGroupIndex.getIndexId(), e );
143         }
144     }
145 
146     @Override
147     public Collection<TemporaryGroupIndex> getTemporaryGroupIndexes()
148     {
149         return this.temporaryGroupIndexes;
150     }
151 }