This project has retired. For details please refer to its Attic page.
Source code
001package org.apache.archiva.indexer.merger.base;
002/*
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *   http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied.  See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 */
020
021import org.apache.archiva.indexer.ArchivaIndexManager;
022import org.apache.archiva.indexer.ArchivaIndexingContext;
023import org.apache.archiva.indexer.IndexCreationFailedException;
024import org.apache.archiva.indexer.merger.IndexMerger;
025import org.apache.archiva.indexer.merger.IndexMergerException;
026import org.apache.archiva.indexer.merger.IndexMergerRequest;
027import org.apache.archiva.indexer.merger.TemporaryGroupIndex;
028import org.apache.archiva.repository.Repository;
029import org.apache.archiva.repository.RepositoryRegistry;
030import org.apache.archiva.repository.storage.StorageAsset;
031import org.apache.archiva.repository.storage.StorageUtil;
032import org.apache.commons.lang3.time.StopWatch;
033import org.slf4j.Logger;
034import org.slf4j.LoggerFactory;
035import org.springframework.scheduling.annotation.Async;
036import org.springframework.stereotype.Service;
037
038import javax.inject.Inject;
039import java.io.IOException;
040import java.util.Collection;
041import java.util.List;
042import java.util.Optional;
043import java.util.concurrent.CopyOnWriteArrayList;
044import java.util.stream.Collectors;
045
046/**
047 * @author Olivier Lamy
048 * @since 1.4-M2
049 */
050@Service("indexMerger#default")
051public class DefaultIndexMerger
052    implements IndexMerger
053{
054
055    @Inject
056    RepositoryRegistry repositoryRegistry;
057
058    private Logger log = LoggerFactory.getLogger( getClass() );
059
060    private List<TemporaryGroupIndex> temporaryGroupIndexes = new CopyOnWriteArrayList<>();
061
062    private List<ArchivaIndexingContext>  temporaryContextes = new CopyOnWriteArrayList<>(  );
063
064    private List<String> runningGroups = new CopyOnWriteArrayList<>();
065
066    @Inject
067    public DefaultIndexMerger( )
068    {
069    }
070
071    @Override
072    public ArchivaIndexingContext buildMergedIndex(IndexMergerRequest indexMergerRequest )
073        throws IndexMergerException
074    {
075        String groupId = indexMergerRequest.getGroupId();
076
077        if ( runningGroups.contains( groupId ) )
078        {
079            log.info( "skip build merge remote indexes for id: '{}' as already running", groupId );
080            return null;
081        }
082
083        runningGroups.add( groupId );
084        StopWatch stopWatch = new StopWatch();
085        try {
086            stopWatch.reset();
087            stopWatch.start();
088
089            StorageAsset mergedIndexDirectory = indexMergerRequest.getMergedIndexDirectory();
090            Repository destinationRepository = repositoryRegistry.getRepository(indexMergerRequest.getGroupId());
091
092            ArchivaIndexManager idxManager = repositoryRegistry.getIndexManager(destinationRepository.getType());
093            List<ArchivaIndexingContext> sourceContexts = indexMergerRequest.getRepositoriesIds().stream().map(id -> repositoryRegistry.getRepository(id).getIndexingContext()).collect(Collectors.toList());
094            try {
095                ArchivaIndexingContext result = idxManager.mergeContexts(destinationRepository, sourceContexts, indexMergerRequest.isPackIndex());
096                if ( indexMergerRequest.isTemporary() )
097                {
098                    String tempRepoId = destinationRepository.getId()+System.currentTimeMillis();
099                    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}