001 package 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 021 import org.apache.archiva.admin.model.AuditInformation; 022 import org.apache.archiva.admin.model.RepositoryAdminException; 023 import org.apache.archiva.admin.model.beans.RemoteRepository; 024 import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin; 025 import org.apache.archiva.admin.repository.AbstractRepositoryAdmin; 026 import org.apache.archiva.audit.AuditEvent; 027 import org.apache.archiva.common.plexusbridge.MavenIndexerUtils; 028 import org.apache.archiva.common.plexusbridge.PlexusSisuBridge; 029 import org.apache.archiva.common.plexusbridge.PlexusSisuBridgeException; 030 import org.apache.archiva.configuration.Configuration; 031 import org.apache.archiva.configuration.ProxyConnectorConfiguration; 032 import org.apache.archiva.configuration.RemoteRepositoryConfiguration; 033 import org.apache.commons.lang.StringUtils; 034 import org.apache.maven.index.NexusIndexer; 035 import org.apache.maven.index.context.IndexCreator; 036 import org.apache.maven.index.context.IndexingContext; 037 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException; 038 import org.springframework.stereotype.Service; 039 040 import javax.annotation.PostConstruct; 041 import javax.annotation.PreDestroy; 042 import javax.inject.Inject; 043 import java.io.File; 044 import java.io.IOException; 045 import java.net.MalformedURLException; 046 import java.util.ArrayList; 047 import java.util.HashMap; 048 import java.util.List; 049 import java.util.Map; 050 051 /** 052 * @author Olivier Lamy 053 * @since 1.4-M1 054 */ 055 @Service ( "remoteRepositoryAdmin#default" ) 056 public class DefaultRemoteRepositoryAdmin 057 extends AbstractRepositoryAdmin 058 implements RemoteRepositoryAdmin 059 { 060 061 @Inject 062 private PlexusSisuBridge plexusSisuBridge; 063 064 @Inject 065 private MavenIndexerUtils mavenIndexerUtils; 066 067 // fields 068 List<? extends IndexCreator> indexCreators; 069 070 NexusIndexer indexer; 071 072 @PostConstruct 073 private void initialize() 074 throws RepositoryAdminException 075 { 076 try 077 { 078 indexCreators = mavenIndexerUtils.getAllIndexCreators(); 079 indexer = plexusSisuBridge.lookup( NexusIndexer.class ); 080 } 081 catch ( PlexusSisuBridgeException e ) 082 { 083 throw new RepositoryAdminException( e.getMessage(), e ); 084 } 085 for ( RemoteRepository remoteRepository : getRemoteRepositories() ) 086 { 087 createIndexContext( remoteRepository ); 088 } 089 } 090 091 @PreDestroy 092 private void shutdown() 093 throws RepositoryAdminException 094 { 095 try 096 { 097 List<RemoteRepository> remoteRepositories = getRemoteRepositories(); 098 // close index on shutdown 099 for ( RemoteRepository remoteRepository : remoteRepositories ) 100 { 101 IndexingContext context = indexer.getIndexingContexts().get( remoteRepository.getId() ); 102 if ( context != null ) 103 { 104 indexer.removeIndexingContext( context, false ); 105 } 106 } 107 } 108 catch ( IOException e ) 109 { 110 throw new RepositoryAdminException( e.getMessage(), e ); 111 } 112 } 113 114 115 public List<RemoteRepository> getRemoteRepositories() 116 throws RepositoryAdminException 117 { 118 List<RemoteRepository> remoteRepositories = new ArrayList<RemoteRepository>( 119 getArchivaConfiguration().getConfiguration().getRemoteRepositories().size() ); 120 for ( RemoteRepositoryConfiguration repositoryConfiguration : getArchivaConfiguration().getConfiguration().getRemoteRepositories() ) 121 { 122 RemoteRepository remoteRepository = 123 new RemoteRepository( repositoryConfiguration.getId(), repositoryConfiguration.getName(), 124 repositoryConfiguration.getUrl(), repositoryConfiguration.getLayout(), 125 repositoryConfiguration.getUsername(), repositoryConfiguration.getPassword(), 126 repositoryConfiguration.getTimeout() ); 127 remoteRepository.setDownloadRemoteIndex( repositoryConfiguration.isDownloadRemoteIndex() ); 128 remoteRepository.setRemoteIndexUrl( repositoryConfiguration.getRemoteIndexUrl() ); 129 remoteRepository.setCronExpression( repositoryConfiguration.getRefreshCronExpression() ); 130 remoteRepository.setIndexDirectory( repositoryConfiguration.getIndexDir() ); 131 remoteRepository.setRemoteDownloadNetworkProxyId( 132 repositoryConfiguration.getRemoteDownloadNetworkProxyId() ); 133 remoteRepository.setRemoteDownloadTimeout( repositoryConfiguration.getRemoteDownloadTimeout() ); 134 remoteRepository.setDownloadRemoteIndexOnStartup( 135 repositoryConfiguration.isDownloadRemoteIndexOnStartup() ); 136 remoteRepository.setDescription( repositoryConfiguration.getDescription() ); 137 remoteRepository.setExtraHeaders( repositoryConfiguration.getExtraHeaders() ); 138 remoteRepository.setExtraParameters( repositoryConfiguration.getExtraParameters() ); 139 remoteRepositories.add( remoteRepository ); 140 } 141 return remoteRepositories; 142 } 143 144 public RemoteRepository getRemoteRepository( String repositoryId ) 145 throws RepositoryAdminException 146 { 147 for ( RemoteRepository remoteRepository : getRemoteRepositories() ) 148 { 149 if ( StringUtils.equals( repositoryId, remoteRepository.getId() ) ) 150 { 151 return remoteRepository; 152 } 153 } 154 return null; 155 } 156 157 public Boolean addRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation ) 158 throws RepositoryAdminException 159 { 160 triggerAuditEvent( remoteRepository.getId(), null, AuditEvent.ADD_REMOTE_REPO, auditInformation ); 161 getRepositoryCommonValidator().basicValidation( remoteRepository, false ); 162 163 //TODO we can validate it's a good uri/url 164 if ( StringUtils.isEmpty( remoteRepository.getUrl() ) ) 165 { 166 throw new RepositoryAdminException( "url cannot be null" ); 167 } 168 169 //MRM-752 - url needs trimming 170 remoteRepository.setUrl( StringUtils.trim( remoteRepository.getUrl() ) ); 171 172 RemoteRepositoryConfiguration remoteRepositoryConfiguration = 173 getRemoteRepositoryConfiguration( remoteRepository ); 174 175 Configuration configuration = getArchivaConfiguration().getConfiguration(); 176 configuration.addRemoteRepository( remoteRepositoryConfiguration ); 177 saveConfiguration( configuration ); 178 179 return Boolean.TRUE; 180 } 181 182 public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation ) 183 throws RepositoryAdminException 184 { 185 186 triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_REMOTE_REPO, auditInformation ); 187 188 Configuration configuration = getArchivaConfiguration().getConfiguration(); 189 190 RemoteRepositoryConfiguration remoteRepositoryConfiguration = 191 configuration.getRemoteRepositoriesAsMap().get( repositoryId ); 192 if ( remoteRepositoryConfiguration == null ) 193 { 194 throw new RepositoryAdminException( 195 "remoteRepository with id " + repositoryId + " not exist cannot remove it" ); 196 } 197 198 configuration.removeRemoteRepository( remoteRepositoryConfiguration ); 199 200 // TODO use ProxyConnectorAdmin interface ? 201 // [MRM-520] Proxy Connectors are not deleted with the deletion of a Repository. 202 List<ProxyConnectorConfiguration> proxyConnectors = 203 new ArrayList<ProxyConnectorConfiguration>( configuration.getProxyConnectors() ); 204 for ( ProxyConnectorConfiguration proxyConnector : proxyConnectors ) 205 { 206 if ( StringUtils.equals( proxyConnector.getTargetRepoId(), repositoryId ) ) 207 { 208 configuration.removeProxyConnector( proxyConnector ); 209 } 210 } 211 212 saveConfiguration( configuration ); 213 214 return Boolean.TRUE; 215 } 216 217 public Boolean updateRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation ) 218 throws RepositoryAdminException 219 { 220 221 String repositoryId = remoteRepository.getId(); 222 223 triggerAuditEvent( repositoryId, null, AuditEvent.MODIFY_REMOTE_REPO, auditInformation ); 224 225 // update means : remove and add 226 227 Configuration configuration = getArchivaConfiguration().getConfiguration(); 228 229 RemoteRepositoryConfiguration remoteRepositoryConfiguration = 230 configuration.getRemoteRepositoriesAsMap().get( repositoryId ); 231 if ( remoteRepositoryConfiguration == null ) 232 { 233 throw new RepositoryAdminException( 234 "remoteRepository with id " + repositoryId + " not exist cannot remove it" ); 235 } 236 237 configuration.removeRemoteRepository( remoteRepositoryConfiguration ); 238 239 remoteRepositoryConfiguration = getRemoteRepositoryConfiguration( remoteRepository ); 240 configuration.addRemoteRepository( remoteRepositoryConfiguration ); 241 saveConfiguration( configuration ); 242 243 return Boolean.TRUE; 244 } 245 246 public Map<String, RemoteRepository> getRemoteRepositoriesAsMap() 247 throws RepositoryAdminException 248 { 249 java.util.Map<String, RemoteRepository> map = new HashMap<String, RemoteRepository>(); 250 251 for ( RemoteRepository repo : getRemoteRepositories() ) 252 { 253 map.put( repo.getId(), repo ); 254 } 255 256 return map; 257 } 258 259 public IndexingContext createIndexContext( RemoteRepository remoteRepository ) 260 throws RepositoryAdminException 261 { 262 try 263 { 264 String appServerBase = getRegistry().getString( "appserver.base" ); 265 266 String contextKey = "remote-" + remoteRepository.getId(); 267 IndexingContext indexingContext = indexer.getIndexingContexts().get( contextKey ); 268 if ( indexingContext != null ) 269 { 270 return indexingContext; 271 } 272 // create remote repository path 273 File repoDir = new File( appServerBase, "data/remotes/" + remoteRepository.getId() ); 274 if ( !repoDir.exists() ) 275 { 276 repoDir.mkdirs(); 277 } 278 279 File indexDirectory = null; 280 281 // is there configured indexDirectory ? 282 String indexDirectoryPath = remoteRepository.getIndexDirectory(); 283 284 if ( StringUtils.isNotBlank( indexDirectoryPath ) ) 285 { 286 if ( new File( indexDirectoryPath ).isAbsolute() ) 287 { 288 indexDirectory = new File( indexDirectoryPath ); 289 } 290 else 291 { 292 indexDirectory = new File( repoDir, indexDirectoryPath ); 293 } 294 } 295 // if not configured use a default value 296 if ( indexDirectory == null ) 297 { 298 indexDirectory = new File( repoDir, ".index" ); 299 } 300 if ( !indexDirectory.exists() ) 301 { 302 indexDirectory.mkdirs(); 303 } 304 return indexer.addIndexingContext( contextKey, remoteRepository.getId(), repoDir, indexDirectory, 305 remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ), 306 mavenIndexerUtils.getAllIndexCreators() ); 307 } 308 catch ( MalformedURLException e ) 309 { 310 throw new RepositoryAdminException( e.getMessage(), e ); 311 } 312 catch ( IOException e ) 313 { 314 throw new RepositoryAdminException( e.getMessage(), e ); 315 } 316 catch ( UnsupportedExistingLuceneIndexException e ) 317 { 318 throw new RepositoryAdminException( e.getMessage(), e ); 319 } 320 321 } 322 323 protected String calculateIndexRemoteUrl( RemoteRepository remoteRepository ) 324 { 325 if ( StringUtils.startsWith( remoteRepository.getRemoteIndexUrl(), "http" ) ) 326 { 327 String baseUrl = remoteRepository.getRemoteIndexUrl(); 328 return baseUrl.endsWith( "/" ) ? StringUtils.substringBeforeLast( baseUrl, "/" ) : baseUrl; 329 } 330 String baseUrl = StringUtils.endsWith( remoteRepository.getUrl(), "/" ) ? StringUtils.substringBeforeLast( 331 remoteRepository.getUrl(), "/" ) : remoteRepository.getUrl(); 332 333 baseUrl = StringUtils.isEmpty( remoteRepository.getRemoteIndexUrl() ) 334 ? baseUrl + "/.index" 335 : baseUrl + "/" + remoteRepository.getRemoteIndexUrl(); 336 return baseUrl; 337 338 } 339 340 private RemoteRepositoryConfiguration getRemoteRepositoryConfiguration( RemoteRepository remoteRepository ) 341 { 342 RemoteRepositoryConfiguration remoteRepositoryConfiguration = new RemoteRepositoryConfiguration(); 343 remoteRepositoryConfiguration.setId( remoteRepository.getId() ); 344 remoteRepositoryConfiguration.setPassword( remoteRepository.getPassword() ); 345 remoteRepositoryConfiguration.setTimeout( remoteRepository.getTimeout() ); 346 remoteRepositoryConfiguration.setUrl( remoteRepository.getUrl() ); 347 remoteRepositoryConfiguration.setUsername( remoteRepository.getUserName() ); 348 remoteRepositoryConfiguration.setLayout( remoteRepository.getLayout() ); 349 remoteRepositoryConfiguration.setName( remoteRepository.getName() ); 350 remoteRepositoryConfiguration.setDownloadRemoteIndex( remoteRepository.isDownloadRemoteIndex() ); 351 remoteRepositoryConfiguration.setRemoteIndexUrl( remoteRepository.getRemoteIndexUrl() ); 352 remoteRepositoryConfiguration.setRefreshCronExpression( remoteRepository.getCronExpression() ); 353 remoteRepositoryConfiguration.setIndexDir( remoteRepository.getIndexDirectory() ); 354 remoteRepositoryConfiguration.setRemoteDownloadNetworkProxyId( 355 remoteRepository.getRemoteDownloadNetworkProxyId() ); 356 remoteRepositoryConfiguration.setRemoteDownloadTimeout( remoteRepository.getRemoteDownloadTimeout() ); 357 remoteRepositoryConfiguration.setDownloadRemoteIndexOnStartup( 358 remoteRepository.isDownloadRemoteIndexOnStartup() ); 359 remoteRepositoryConfiguration.setDescription( remoteRepository.getDescription() ); 360 remoteRepositoryConfiguration.setExtraHeaders( remoteRepository.getExtraHeaders() ); 361 remoteRepositoryConfiguration.setExtraParameters( remoteRepository.getExtraParameters() ); 362 return remoteRepositoryConfiguration; 363 } 364 365 }