001package org.apache.archiva.admin.repository.remote; 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.admin.model.AuditInformation; 022import org.apache.archiva.admin.model.RepositoryAdminException; 023import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; 024import org.apache.archiva.admin.repository.AbstractRepositoryAdmin; 025import org.apache.archiva.common.utils.PathUtil; 026import org.apache.archiva.configuration.Configuration; 027import org.apache.archiva.configuration.RemoteRepositoryConfiguration; 028import org.apache.archiva.configuration.RepositoryCheckPath; 029import org.apache.archiva.indexer.UnsupportedBaseContextException; 030import org.apache.archiva.metadata.model.facets.AuditEvent; 031import org.apache.archiva.repository.base.PasswordCredentials; 032import org.apache.archiva.repository.RemoteRepository; 033import org.apache.archiva.repository.RepositoryCredentials; 034import org.apache.archiva.repository.RepositoryException; 035import org.apache.archiva.repository.RepositoryRegistry; 036import org.apache.archiva.repository.features.IndexCreationFeature; 037import org.apache.archiva.repository.features.RemoteIndexFeature; 038import org.apache.commons.lang3.StringUtils; 039import org.apache.maven.index.context.IndexingContext; 040import org.springframework.stereotype.Service; 041 042import javax.annotation.PostConstruct; 043import javax.inject.Inject; 044import java.util.HashMap; 045import java.util.List; 046import java.util.Map; 047import java.util.stream.Collectors; 048 049/** 050 * @author Olivier Lamy 051 * @since 1.4-M1 052 */ 053@Service("remoteRepositoryAdmin#default") 054public class DefaultRemoteRepositoryAdmin 055 extends AbstractRepositoryAdmin 056 implements RemoteRepositoryAdmin 057{ 058 059 @Inject 060 RepositoryRegistry repositoryRegistry; 061 062 063 @PostConstruct 064 private void initialize() 065 throws RepositoryAdminException 066 { 067 for ( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository : getRemoteRepositories() ) 068 { 069 createIndexContext( remoteRepository ); 070 } 071 } 072 073 /* 074 * Conversion between the repository from the registry and the serialized DTO for the admin API 075 */ 076 private org.apache.archiva.admin.model.beans.RemoteRepository convertRepo( RemoteRepository repo ) { 077 if (repo==null) { 078 return null; 079 } 080 org.apache.archiva.admin.model.beans.RemoteRepository adminRepo = new org.apache.archiva.admin.model.beans.RemoteRepository( getArchivaConfiguration().getDefaultLocale() ); 081 setBaseRepoAttributes( adminRepo, repo ); 082 adminRepo.setUrl( convertUriToString( repo.getLocation() )); 083 adminRepo.setCronExpression( repo.getSchedulingDefinition() ); 084 adminRepo.setCheckPath( repo.getCheckPath() ); 085 adminRepo.setExtraHeaders( repo.getExtraHeaders() ); 086 adminRepo.setExtraParameters( repo.getExtraParameters() ); 087 adminRepo.setTimeout( (int) repo.getTimeout().getSeconds() ); 088 RepositoryCredentials creds = repo.getLoginCredentials(); 089 if (creds!=null && creds instanceof PasswordCredentials) { 090 PasswordCredentials pCreds = (PasswordCredentials) creds; 091 adminRepo.setUserName( pCreds.getUsername() ); 092 adminRepo.setPassword( new String(pCreds.getPassword()!=null ? pCreds.getPassword() : new char[0]) ); 093 } 094 if (repo.supportsFeature( RemoteIndexFeature.class )) { 095 RemoteIndexFeature rif = repo.getFeature( RemoteIndexFeature.class ).get(); 096 adminRepo.setRemoteIndexUrl( convertUriToString( rif.getIndexUri() ) ); 097 adminRepo.setDownloadRemoteIndex( rif.isDownloadRemoteIndex() ); 098 adminRepo.setRemoteDownloadNetworkProxyId( rif.getProxyId() ); 099 adminRepo.setDownloadRemoteIndexOnStartup( rif.isDownloadRemoteIndexOnStartup() ); 100 adminRepo.setRemoteDownloadTimeout( (int) rif.getDownloadTimeout().getSeconds() ); 101 } 102 if (repo.supportsFeature(IndexCreationFeature.class)) { 103 IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get(); 104 adminRepo.setIndexDirectory(PathUtil.getPathFromUri(icf.getIndexPath()).toString()); 105 } 106 adminRepo.setDescription(repo.getDescription()); 107 return adminRepo; 108 } 109 110 private RemoteRepositoryConfiguration getRepositoryConfiguration( org.apache.archiva.admin.model.beans.RemoteRepository repo) { 111 RemoteRepositoryConfiguration repoConfig = new RemoteRepositoryConfiguration(); 112 setBaseRepoAttributes( repoConfig, repo ); 113 repoConfig.setUrl( getRepositoryCommonValidator().removeExpressions( repo.getUrl() ) ); 114 repoConfig.setRefreshCronExpression( repo.getCronExpression() ); 115 repoConfig.setCheckPath( repo.getCheckPath() ); 116 repoConfig.setExtraHeaders( repo.getExtraHeaders() ); 117 repoConfig.setExtraParameters( repo.getExtraParameters() ); 118 repoConfig.setUsername( repo.getUserName() ); 119 repoConfig.setPassword( repo.getPassword() ); 120 repoConfig.setTimeout( repo.getTimeout() ); 121 repoConfig.setRemoteIndexUrl( repo.getRemoteIndexUrl() ); 122 repoConfig.setDownloadRemoteIndex( repo.isDownloadRemoteIndex() ); 123 repoConfig.setRemoteDownloadNetworkProxyId( repo.getRemoteDownloadNetworkProxyId() ); 124 repoConfig.setDownloadRemoteIndexOnStartup( repo.isDownloadRemoteIndexOnStartup() ); 125 repoConfig.setRemoteDownloadTimeout( repo.getRemoteDownloadTimeout() ); 126 repoConfig.setDescription(repo.getDescription()); 127 repoConfig.setIndexDir(repo.getIndexDirectory()); 128 return repoConfig; 129 } 130 131 @Override 132 public List<org.apache.archiva.admin.model.beans.RemoteRepository> getRemoteRepositories() 133 throws RepositoryAdminException 134 { 135 136 return repositoryRegistry.getRemoteRepositories().stream().map( repo -> convertRepo( repo ) ).collect( Collectors.toList()); 137 } 138 139 @Override 140 public org.apache.archiva.admin.model.beans.RemoteRepository getRemoteRepository( String repositoryId ) 141 throws RepositoryAdminException 142 { 143 return convertRepo( repositoryRegistry.getRemoteRepository( repositoryId )); 144 } 145 146 @Override 147 public Boolean addRemoteRepository( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository, AuditInformation auditInformation ) 148 throws RepositoryAdminException 149 { 150 triggerAuditEvent( remoteRepository.getId(), null, AuditEvent.ADD_REMOTE_REPO, auditInformation ); 151 getRepositoryCommonValidator().basicValidation( remoteRepository, false ); 152 153 //TODO we can validate it's a good uri/url 154 if ( StringUtils.isEmpty( remoteRepository.getUrl() ) ) 155 { 156 throw new RepositoryAdminException( "url cannot be null" ); 157 } 158 159 //MRM-752 - url needs trimming 160 //MRM-1940 - URL should not end with a slash 161 remoteRepository.setUrl( StringUtils.stripEnd(StringUtils.trim( remoteRepository.getUrl() ), "/")); 162 163 if (StringUtils.isEmpty(remoteRepository.getCheckPath())) { 164 String checkUrl = remoteRepository.getUrl().toLowerCase(); 165 for (RepositoryCheckPath path : getArchivaConfiguration ().getConfiguration().getArchivaDefaultConfiguration().getDefaultCheckPaths()) { 166 log.debug("Checking path for urls: {} <-> {}", checkUrl, path.getUrl()); 167 if (checkUrl.startsWith(path.getUrl())) { 168 remoteRepository.setCheckPath(path.getPath()); 169 break; 170 } 171 } 172 } 173 174 Configuration configuration = getArchivaConfiguration().getConfiguration(); 175 RemoteRepositoryConfiguration remoteRepositoryConfiguration = 176 getRepositoryConfiguration( remoteRepository ); 177 log.debug("Adding remote repo {}", remoteRepositoryConfiguration); 178 179 try 180 { 181 repositoryRegistry.putRepository( remoteRepositoryConfiguration, configuration ); 182 } 183 catch ( RepositoryException e ) 184 { 185 log.error("Could not add remote repository {}: {}", remoteRepositoryConfiguration.getId(), e.getMessage(), e); 186 throw new RepositoryAdminException( "Adding of remote repository failed"+(e.getMessage()==null?"":": "+e.getMessage()) ); 187 188 } 189 190 saveConfiguration( configuration ); 191 192 return Boolean.TRUE; 193 } 194 195 @Override 196 public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation ) 197 throws RepositoryAdminException 198 { 199 200 triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_REMOTE_REPO, auditInformation ); 201 202 Configuration configuration = getArchivaConfiguration().getConfiguration(); 203 204 RemoteRepository repo = repositoryRegistry.getRemoteRepository( repositoryId ); 205 if (repo==null) { 206 throw new RepositoryAdminException( "Could not delete repository "+repositoryId+". The repository does not exist." ); 207 } 208 try 209 { 210 repositoryRegistry.removeRepository( repo, configuration ); 211 } 212 catch ( RepositoryException e ) 213 { 214 log.error("Deletion of remote repository failed {}: {}", repo.getId(), e.getMessage(), e); 215 throw new RepositoryAdminException( "Could not delete remote repository"+(e.getMessage()==null?"":": "+e.getMessage()) ); 216 } 217 218 saveConfiguration( configuration ); 219 220 return Boolean.TRUE; 221 } 222 223 @Override 224 public Boolean updateRemoteRepository( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository, AuditInformation auditInformation ) 225 throws RepositoryAdminException 226 { 227 228 String repositoryId = remoteRepository.getId(); 229 230 triggerAuditEvent( repositoryId, null, AuditEvent.MODIFY_REMOTE_REPO, auditInformation ); 231 232 // update means : remove and add 233 234 Configuration configuration = getArchivaConfiguration().getConfiguration(); 235 236 RemoteRepositoryConfiguration remoteRepositoryConfiguration = getRepositoryConfiguration( remoteRepository ); 237 try 238 { 239 repositoryRegistry.putRepository( remoteRepositoryConfiguration, configuration ); 240 } 241 catch ( RepositoryException e ) 242 { 243 log.error("Could not update remote repository {}: {}", remoteRepositoryConfiguration.getId(), e.getMessage(), e); 244 throw new RepositoryAdminException( "Update of remote repository failed"+(e.getMessage()==null?"":": "+e.getMessage()) ); 245 } 246 saveConfiguration( configuration ); 247 return Boolean.TRUE; 248 } 249 250 @Override 251 public Map<String, org.apache.archiva.admin.model.beans.RemoteRepository> getRemoteRepositoriesAsMap() 252 throws RepositoryAdminException 253 { 254 java.util.Map<String, org.apache.archiva.admin.model.beans.RemoteRepository> map = new HashMap<>(); 255 256 for ( org.apache.archiva.admin.model.beans.RemoteRepository repo : getRemoteRepositories() ) 257 { 258 map.put( repo.getId(), repo ); 259 } 260 261 return map; 262 } 263 264 @Override 265 public IndexingContext createIndexContext( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository ) 266 throws RepositoryAdminException 267 { 268 try 269 { 270 RemoteRepository repo = repositoryRegistry.getRemoteRepository(remoteRepository.getId()); 271 return repo.getIndexingContext().getBaseContext(IndexingContext.class); 272 } catch (UnsupportedBaseContextException e) { 273 throw new RepositoryAdminException( e.getMessage(), e); 274 } 275 276 } 277 278 279 280 281}