1 package org.apache.archiva.admin.repository.remote;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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
21 import org.apache.archiva.admin.model.AuditInformation;
22 import org.apache.archiva.admin.model.RepositoryAdminException;
23 import org.apache.archiva.admin.model.beans.RemoteRepository;
24 import org.apache.archiva.admin.model.remote.RemoteRepositoryAdmin;
25 import org.apache.archiva.admin.repository.AbstractRepositoryAdmin;
26 import org.apache.archiva.configuration.Configuration;
27 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
28 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
29 import org.apache.archiva.configuration.RepositoryCheckPath;
30 import org.apache.archiva.metadata.model.facets.AuditEvent;
31 import org.apache.commons.io.FileUtils;
32 import org.apache.commons.lang.StringUtils;
33 import org.apache.maven.index.NexusIndexer;
34 import org.apache.maven.index.context.IndexCreator;
35 import org.apache.maven.index.context.IndexingContext;
36 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
37 import org.apache.maven.index_shaded.lucene.index.IndexFormatTooOldException;
38 import org.springframework.stereotype.Service;
40 import javax.annotation.PostConstruct;
41 import javax.annotation.PreDestroy;
42 import javax.inject.Inject;
44 import java.io.IOException;
45 import java.util.ArrayList;
46 import java.util.HashMap;
47 import java.util.List;
51 * @author Olivier Lamy
54 @Service("remoteRepositoryAdmin#default")
55 public class DefaultRemoteRepositoryAdmin
56 extends AbstractRepositoryAdmin
57 implements RemoteRepositoryAdmin
61 private List<? extends IndexCreator> indexCreators;
64 private NexusIndexer indexer;
67 private void initialize()
68 throws RepositoryAdminException
70 for ( RemoteRepository remoteRepository : getRemoteRepositories() )
72 createIndexContext( remoteRepository );
77 private void shutdown()
78 throws RepositoryAdminException
82 List<RemoteRepository> remoteRepositories = getRemoteRepositories();
83 // close index on shutdown
84 for ( RemoteRepository remoteRepository : remoteRepositories )
86 IndexingContext context = indexer.getIndexingContexts().get( remoteRepository.getId() );
87 if ( context != null )
89 indexer.removeIndexingContext( context, false );
93 catch ( IOException e )
95 throw new RepositoryAdminException( e.getMessage(), e );
101 public List<RemoteRepository> getRemoteRepositories()
102 throws RepositoryAdminException
104 List<RemoteRepository> remoteRepositories =
105 new ArrayList<>( getArchivaConfiguration().getConfiguration().getRemoteRepositories().size() );
106 for ( RemoteRepositoryConfiguration repositoryConfiguration : getArchivaConfiguration().getConfiguration().getRemoteRepositories() )
108 RemoteRepository remoteRepository =
109 new RemoteRepository( repositoryConfiguration.getId(), repositoryConfiguration.getName(),
110 repositoryConfiguration.getUrl(), repositoryConfiguration.getLayout(),
111 repositoryConfiguration.getUsername(), repositoryConfiguration.getPassword(),
112 repositoryConfiguration.getTimeout() );
113 remoteRepository.setDownloadRemoteIndex( repositoryConfiguration.isDownloadRemoteIndex() );
114 remoteRepository.setRemoteIndexUrl( repositoryConfiguration.getRemoteIndexUrl() );
115 remoteRepository.setCronExpression( repositoryConfiguration.getRefreshCronExpression() );
116 remoteRepository.setIndexDirectory( repositoryConfiguration.getIndexDir() );
117 remoteRepository.setRemoteDownloadNetworkProxyId(
118 repositoryConfiguration.getRemoteDownloadNetworkProxyId() );
119 remoteRepository.setRemoteDownloadTimeout( repositoryConfiguration.getRemoteDownloadTimeout() );
120 remoteRepository.setDownloadRemoteIndexOnStartup(
121 repositoryConfiguration.isDownloadRemoteIndexOnStartup() );
122 remoteRepository.setDescription( repositoryConfiguration.getDescription() );
123 remoteRepository.setExtraHeaders( repositoryConfiguration.getExtraHeaders() );
124 remoteRepository.setExtraParameters( repositoryConfiguration.getExtraParameters() );
125 remoteRepository.setCheckPath(repositoryConfiguration.getCheckPath());
126 remoteRepositories.add( remoteRepository );
128 return remoteRepositories;
132 public RemoteRepository getRemoteRepository( String repositoryId )
133 throws RepositoryAdminException
135 for ( RemoteRepository remoteRepository : getRemoteRepositories() )
137 if ( StringUtils.equals( repositoryId, remoteRepository.getId() ) )
139 return remoteRepository;
146 public Boolean addRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation )
147 throws RepositoryAdminException
149 triggerAuditEvent( remoteRepository.getId(), null, AuditEvent.ADD_REMOTE_REPO, auditInformation );
150 getRepositoryCommonValidator().basicValidation( remoteRepository, false );
152 //TODO we can validate it's a good uri/url
153 if ( StringUtils.isEmpty( remoteRepository.getUrl() ) )
155 throw new RepositoryAdminException( "url cannot be null" );
158 //MRM-752 - url needs trimming
159 //MRM-1940 - URL should not end with a slash
160 remoteRepository.setUrl( StringUtils.stripEnd(StringUtils.trim( remoteRepository.getUrl() ), "/"));
162 if (StringUtils.isEmpty(remoteRepository.getCheckPath())) {
163 String checkUrl = remoteRepository.getUrl().toLowerCase();
164 for (RepositoryCheckPath path : getArchivaConfiguration ().getConfiguration().getArchivaDefaultConfiguration().getDefaultCheckPaths()) {
165 log.debug("Checking path for urls: {} <-> {}", checkUrl, path.getUrl());
166 if (checkUrl.startsWith(path.getUrl())) {
167 remoteRepository.setCheckPath(path.getPath());
173 RemoteRepositoryConfiguration remoteRepositoryConfiguration =
174 getRemoteRepositoryConfiguration( remoteRepository );
176 Configuration configuration = getArchivaConfiguration().getConfiguration();
177 configuration.addRemoteRepository( remoteRepositoryConfiguration );
178 saveConfiguration( configuration );
184 public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation )
185 throws RepositoryAdminException
188 triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_REMOTE_REPO, auditInformation );
190 Configuration configuration = getArchivaConfiguration().getConfiguration();
192 RemoteRepositoryConfiguration remoteRepositoryConfiguration =
193 configuration.getRemoteRepositoriesAsMap().get( repositoryId );
194 if ( remoteRepositoryConfiguration == null )
196 throw new RepositoryAdminException(
197 "remoteRepository with id " + repositoryId + " not exist cannot remove it" );
200 configuration.removeRemoteRepository( remoteRepositoryConfiguration );
202 // TODO use ProxyConnectorAdmin interface ?
203 // [MRM-520] Proxy Connectors are not deleted with the deletion of a Repository.
204 List<ProxyConnectorConfiguration> proxyConnectors = new ArrayList<>( configuration.getProxyConnectors() );
205 for ( ProxyConnectorConfiguration proxyConnector : proxyConnectors )
207 if ( StringUtils.equals( proxyConnector.getTargetRepoId(), repositoryId ) )
209 configuration.removeProxyConnector( proxyConnector );
213 saveConfiguration( configuration );
219 public Boolean updateRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation )
220 throws RepositoryAdminException
223 String repositoryId = remoteRepository.getId();
225 triggerAuditEvent( repositoryId, null, AuditEvent.MODIFY_REMOTE_REPO, auditInformation );
227 // update means : remove and add
229 Configuration configuration = getArchivaConfiguration().getConfiguration();
231 RemoteRepositoryConfiguration remoteRepositoryConfiguration =
232 configuration.getRemoteRepositoriesAsMap().get( repositoryId );
233 if ( remoteRepositoryConfiguration == null )
235 throw new RepositoryAdminException(
236 "remoteRepository with id " + repositoryId + " not exist cannot remove it" );
239 configuration.removeRemoteRepository( remoteRepositoryConfiguration );
241 remoteRepositoryConfiguration = getRemoteRepositoryConfiguration( remoteRepository );
242 configuration.addRemoteRepository( remoteRepositoryConfiguration );
243 saveConfiguration( configuration );
249 public Map<String, RemoteRepository> getRemoteRepositoriesAsMap()
250 throws RepositoryAdminException
252 java.util.Map<String, RemoteRepository> map = new HashMap<>();
254 for ( RemoteRepository repo : getRemoteRepositories() )
256 map.put( repo.getId(), repo );
263 public IndexingContext createIndexContext( RemoteRepository remoteRepository )
264 throws RepositoryAdminException
268 String appServerBase = getRegistry().getString( "appserver.base" );
270 String contextKey = "remote-" + remoteRepository.getId();
271 IndexingContext indexingContext = indexer.getIndexingContexts().get( contextKey );
272 if ( indexingContext != null )
274 return indexingContext;
276 // create remote repository path
277 File repoDir = new File( appServerBase, "data/remotes/" + remoteRepository.getId() );
278 if ( !repoDir.exists() )
283 File indexDirectory = null;
285 // is there configured indexDirectory ?
286 String indexDirectoryPath = remoteRepository.getIndexDirectory();
288 if ( StringUtils.isNotBlank( indexDirectoryPath ) )
290 if ( new File( indexDirectoryPath ).isAbsolute() )
292 indexDirectory = new File( indexDirectoryPath );
296 indexDirectory = new File( repoDir, indexDirectoryPath );
299 // if not configured use a default value
300 if ( indexDirectory == null )
302 indexDirectory = new File( repoDir, ".index" );
304 if ( !indexDirectory.exists() )
306 indexDirectory.mkdirs();
312 return indexer.addIndexingContext( contextKey, remoteRepository.getId(), repoDir, indexDirectory,
313 remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ),
316 catch ( IndexFormatTooOldException e )
318 // existing index with an old lucene format so we need to delete it!!!
319 // delete it first then recreate it.
320 log.warn( "the index of repository {} is too old we have to delete and recreate it", //
321 remoteRepository.getId() );
322 FileUtils.deleteDirectory( indexDirectory );
323 return indexer.addIndexingContext( contextKey, remoteRepository.getId(), repoDir, indexDirectory,
324 remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ),
329 catch ( IOException | UnsupportedExistingLuceneIndexException e )
331 throw new RepositoryAdminException( e.getMessage(), e );
336 protected String calculateIndexRemoteUrl( RemoteRepository remoteRepository )
338 if ( StringUtils.startsWith( remoteRepository.getRemoteIndexUrl(), "http" ) )
340 String baseUrl = remoteRepository.getRemoteIndexUrl();
341 return baseUrl.endsWith( "/" ) ? StringUtils.substringBeforeLast( baseUrl, "/" ) : baseUrl;
343 String baseUrl = StringUtils.endsWith( remoteRepository.getUrl(), "/" ) ? StringUtils.substringBeforeLast(
344 remoteRepository.getUrl(), "/" ) : remoteRepository.getUrl();
346 baseUrl = StringUtils.isEmpty( remoteRepository.getRemoteIndexUrl() )
347 ? baseUrl + "/.index"
348 : baseUrl + "/" + remoteRepository.getRemoteIndexUrl();
353 private RemoteRepositoryConfiguration getRemoteRepositoryConfiguration( RemoteRepository remoteRepository )
355 RemoteRepositoryConfiguration remoteRepositoryConfiguration = new RemoteRepositoryConfiguration();
356 remoteRepositoryConfiguration.setId( remoteRepository.getId() );
357 remoteRepositoryConfiguration.setPassword( remoteRepository.getPassword() );
358 remoteRepositoryConfiguration.setTimeout( remoteRepository.getTimeout() );
359 remoteRepositoryConfiguration.setUrl( remoteRepository.getUrl() );
360 remoteRepositoryConfiguration.setUsername( remoteRepository.getUserName() );
361 remoteRepositoryConfiguration.setLayout( remoteRepository.getLayout() );
362 remoteRepositoryConfiguration.setName( remoteRepository.getName() );
363 remoteRepositoryConfiguration.setDownloadRemoteIndex( remoteRepository.isDownloadRemoteIndex() );
364 remoteRepositoryConfiguration.setRemoteIndexUrl( remoteRepository.getRemoteIndexUrl() );
365 remoteRepositoryConfiguration.setRefreshCronExpression( remoteRepository.getCronExpression() );
366 remoteRepositoryConfiguration.setIndexDir( remoteRepository.getIndexDirectory() );
367 remoteRepositoryConfiguration.setRemoteDownloadNetworkProxyId(
368 remoteRepository.getRemoteDownloadNetworkProxyId() );
369 remoteRepositoryConfiguration.setRemoteDownloadTimeout( remoteRepository.getRemoteDownloadTimeout() );
370 remoteRepositoryConfiguration.setDownloadRemoteIndexOnStartup(
371 remoteRepository.isDownloadRemoteIndexOnStartup() );
372 remoteRepositoryConfiguration.setDescription( remoteRepository.getDescription() );
373 remoteRepositoryConfiguration.setExtraHeaders( remoteRepository.getExtraHeaders() );
374 remoteRepositoryConfiguration.setExtraParameters( remoteRepository.getExtraParameters() );
375 remoteRepositoryConfiguration.setCheckPath(remoteRepository.getCheckPath());
376 return remoteRepositoryConfiguration;