001package org.apache.archiva.rest.services; 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.common.utils.VersionUtil; 022import org.apache.archiva.maven2.model.Artifact; 023import org.apache.archiva.metadata.model.ArtifactMetadata; 024import org.apache.archiva.metadata.model.facets.AuditEvent; 025import org.apache.archiva.metadata.repository.MetadataRepository; 026import org.apache.archiva.metadata.repository.MetadataRepositoryException; 027import org.apache.archiva.metadata.repository.RepositorySession; 028import org.apache.archiva.filter.Filter; 029import org.apache.archiva.filter.IncludesFilter; 030import org.apache.archiva.repository.ReleaseScheme; 031import org.apache.archiva.repository.Repository; 032import org.apache.archiva.repository.RepositoryNotFoundException; 033import org.apache.archiva.repository.RepositoryRegistry; 034import org.apache.archiva.rest.api.services.ArchivaRestServiceException; 035import org.apache.archiva.rest.api.services.MergeRepositoriesService; 036import org.apache.archiva.stagerepository.merge.RepositoryMerger; 037import org.apache.archiva.stagerepository.merge.RepositoryMergerException; 038import org.springframework.stereotype.Service; 039 040import javax.inject.Inject; 041import java.util.ArrayList; 042import java.util.List; 043 044/** 045 * @author Olivier Lamy 046 * @since 1.4-M3 047 */ 048@Service ( "mergeRepositoriesService#rest" ) 049public class DefaultMergeRepositoriesService 050 extends AbstractRestService 051 implements MergeRepositoriesService 052{ 053 054 // FIXME check archiva-merge-repository to sourceRepoId 055 056 @Inject 057 private List<RepositoryMerger> repositoryMerger; 058 059 @Inject 060 private RepositoryRegistry repositoryRegistry; 061 062 063 @Override 064 public List<Artifact> getMergeConflictedArtifacts( String sourceRepositoryId, String targetRepositoryId ) 065 throws ArchivaRestServiceException 066 { 067 RepositorySession repositorySession = null; 068 try 069 { 070 repositorySession = repositorySessionFactory.createSession(); 071 } 072 catch ( MetadataRepositoryException e ) 073 { 074 log.error( "Error while creating repository session {}", e.getMessage( ), e ); 075 } 076 try 077 { 078 RepositoryMerger merger = findMerger( sourceRepositoryId ); 079 List<ArtifactMetadata> artifactMetadatas = 080 merger.getConflictingArtifacts( repositorySession.getRepository(), sourceRepositoryId, 081 targetRepositoryId ); 082 083 return buildArtifacts( artifactMetadatas, sourceRepositoryId ); 084 } 085 catch ( RepositoryMergerException | RepositoryNotFoundException e ) 086 { 087 throw new ArchivaRestServiceException( e.getMessage(), e ); 088 } 089 finally 090 { 091 repositorySession.close(); 092 } 093 } 094 095 RepositoryMerger findMerger(String repositoryId) throws RepositoryNotFoundException 096 { 097 Repository repo = repositoryRegistry.getRepository( repositoryId ); 098 if (repo==null) { 099 throw new RepositoryNotFoundException( repositoryId ); 100 } else { 101 return repositoryMerger.stream( ).filter( m -> m.supportsRepository( repo.getType( ) ) ).findFirst().get(); 102 } 103 } 104 105 @Override 106 public void mergeRepositories( String sourceRepositoryId, String targetRepositoryId, boolean skipConflicts ) 107 throws ArchivaRestServiceException 108 { 109 try 110 { 111 RepositoryMerger merger = findMerger( sourceRepositoryId ); 112 113 if ( skipConflicts ) 114 { 115 mergeBySkippingConflicts( merger, sourceRepositoryId, targetRepositoryId ); 116 } 117 else 118 { 119 doMerge( merger, sourceRepositoryId, targetRepositoryId ); 120 } 121 122 } 123 catch ( RepositoryMergerException | RepositoryNotFoundException e ) 124 { 125 throw new ArchivaRestServiceException( e.getMessage(), e ); 126 } 127 128 } 129 130 131 protected void doMerge( RepositoryMerger merger, String sourceRepositoryId, String targetRepositoryId ) 132 throws RepositoryMergerException, ArchivaRestServiceException 133 { 134 RepositorySession repositorySession = null; 135 try 136 { 137 repositorySession = repositorySessionFactory.createSession(); 138 } 139 catch ( MetadataRepositoryException e ) 140 { 141 e.printStackTrace( ); 142 } 143 144 try 145 { 146 org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(targetRepositoryId); 147 MetadataRepository metadataRepository = repositorySession.getRepository(); 148 List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts(repositorySession , sourceRepositoryId ); 149 150 if ( managedRepo.getActiveReleaseSchemes().contains(ReleaseScheme.RELEASE) && !managedRepo.getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT) ) 151 { 152 mergeWithOutSnapshots(merger, metadataRepository, sourceArtifacts, sourceRepositoryId, targetRepositoryId ); 153 } 154 else 155 { 156 merger.merge( metadataRepository, sourceRepositoryId, targetRepositoryId ); 157 158 for ( ArtifactMetadata metadata : sourceArtifacts ) 159 { 160 triggerAuditEvent( targetRepositoryId, metadata.getId(), AuditEvent.MERGING_REPOSITORIES ); 161 } 162 } 163 164 doScanRepository( targetRepositoryId, false ); 165 } 166 catch ( MetadataRepositoryException e ) 167 { 168 throw new ArchivaRestServiceException( e.getMessage(), e ); 169 } finally 170 { 171 repositorySession.close(); 172 } 173 } 174 175 private void mergeBySkippingConflicts( RepositoryMerger merger, String sourceRepositoryId, String targetRepositoryId ) 176 throws RepositoryMergerException, ArchivaRestServiceException 177 { 178 179 RepositorySession repositorySession = null; 180 try 181 { 182 repositorySession = repositorySessionFactory.createSession(); 183 } 184 catch ( MetadataRepositoryException e ) 185 { 186 e.printStackTrace( ); 187 } 188 try 189 { 190 List<ArtifactMetadata> conflictSourceArtifacts = 191 merger.getConflictingArtifacts( repositorySession.getRepository(), sourceRepositoryId, 192 targetRepositoryId ); 193 MetadataRepository metadataRepository = repositorySession.getRepository(); 194 List<ArtifactMetadata> sourceArtifacts = metadataRepository.getArtifacts(repositorySession , sourceRepositoryId ); 195 sourceArtifacts.removeAll( conflictSourceArtifacts ); 196 197 org.apache.archiva.repository.ManagedRepository managedRepo = repositoryRegistry.getManagedRepository(targetRepositoryId); 198 199 if ( managedRepo.getActiveReleaseSchemes().contains(ReleaseScheme.RELEASE) && !managedRepo.getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT)) 200 { 201 mergeWithOutSnapshots( merger, metadataRepository, sourceArtifacts, sourceRepositoryId, targetRepositoryId ); 202 } 203 else 204 { 205 206 Filter<ArtifactMetadata> artifactsWithOutConflicts = 207 new IncludesFilter<ArtifactMetadata>( sourceArtifacts ); 208 merger.merge( metadataRepository, sourceRepositoryId, targetRepositoryId, 209 artifactsWithOutConflicts ); 210 for ( ArtifactMetadata metadata : sourceArtifacts ) 211 { 212 triggerAuditEvent( targetRepositoryId, metadata.getId(), AuditEvent.MERGING_REPOSITORIES ); 213 } 214 } 215 216 doScanRepository( targetRepositoryId, false ); 217 } 218 catch ( MetadataRepositoryException e ) 219 { 220 throw new ArchivaRestServiceException( e.getMessage(), e ); 221 } finally 222 { 223 repositorySession.close(); 224 } 225 } 226 227 private void mergeWithOutSnapshots( RepositoryMerger merger, MetadataRepository metadataRepository, List<ArtifactMetadata> sourceArtifacts, 228 String sourceRepoId, String repoid ) 229 throws RepositoryMergerException 230 { 231 List<ArtifactMetadata> artifactsWithOutSnapshots = new ArrayList<>(); 232 for ( ArtifactMetadata metadata : sourceArtifacts ) 233 { 234 if ( VersionUtil.isSnapshot( metadata.getProjectVersion() ) ) 235 //if ( metadata.getProjectVersion().contains( VersionUtil.SNAPSHOT ) ) 236 { 237 artifactsWithOutSnapshots.add( metadata ); 238 } 239 else 240 { 241 triggerAuditEvent( repoid, metadata.getId(), AuditEvent.MERGING_REPOSITORIES ); 242 } 243 244 } 245 sourceArtifacts.removeAll( artifactsWithOutSnapshots ); 246 247 Filter<ArtifactMetadata> artifactListWithOutSnapShots = new IncludesFilter<ArtifactMetadata>( sourceArtifacts ); 248 merger.merge( metadataRepository, sourceRepoId, repoid, artifactListWithOutSnapShots ); 249 } 250}