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.remote.RemoteRepositoryAdmin;
24 import org.apache.archiva.admin.repository.AbstractRepositoryAdmin;
25 import org.apache.archiva.common.utils.PathUtil;
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.indexer.UnsupportedBaseContextException;
31 import org.apache.archiva.metadata.model.facets.AuditEvent;
32 import org.apache.archiva.repository.RemoteRepository;
33 import org.apache.archiva.repository.PasswordCredentials;
34 import org.apache.archiva.repository.RepositoryCredentials;
35 import org.apache.archiva.repository.RepositoryException;
36 import org.apache.archiva.repository.RepositoryRegistry;
37 import org.apache.archiva.repository.features.IndexCreationEvent;
38 import org.apache.archiva.repository.features.IndexCreationFeature;
39 import org.apache.archiva.repository.features.RemoteIndexFeature;
40 import org.apache.commons.lang.StringUtils;
41 import org.apache.maven.index.NexusIndexer;
42 import org.apache.maven.index.context.IndexCreator;
43 import org.apache.maven.index.context.IndexingContext;
44 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
45 import org.apache.maven.index_shaded.lucene.index.IndexFormatTooOldException;
46 import org.springframework.stereotype.Service;
48 import javax.annotation.PostConstruct;
49 import javax.annotation.PreDestroy;
50 import javax.inject.Inject;
51 import java.io.IOException;
53 import java.nio.file.Files;
54 import java.nio.file.Path;
55 import java.nio.file.Paths;
56 import java.util.ArrayList;
57 import java.util.HashMap;
58 import java.util.List;
60 import java.util.stream.Collectors;
63 * @author Olivier Lamy
66 @Service("remoteRepositoryAdmin#default")
67 public class DefaultRemoteRepositoryAdmin
68 extends AbstractRepositoryAdmin
69 implements RemoteRepositoryAdmin
73 RepositoryRegistry repositoryRegistry;
76 private List<? extends IndexCreator> indexCreators;
79 private NexusIndexer indexer;
82 private void initialize()
83 throws RepositoryAdminException
85 for ( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository : getRemoteRepositories() )
87 createIndexContext( remoteRepository );
92 private void shutdown()
93 throws RepositoryAdminException
97 List<org.apache.archiva.admin.model.beans.RemoteRepository> remoteRepositories = getRemoteRepositories();
98 // close index on shutdown
99 for ( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository : remoteRepositories )
101 IndexingContext context = indexer.getIndexingContexts().get( remoteRepository.getId() );
102 if ( context != null )
104 indexer.removeIndexingContext( context, false );
108 catch ( IOException e )
110 throw new RepositoryAdminException( e.getMessage(), e );
116 * Conversion between the repository from the registry and the serialized DTO for the admin API
118 private org.apache.archiva.admin.model.beans.RemoteRepository convertRepo( RemoteRepository repo ) {
122 org.apache.archiva.admin.model.beans.RemoteRepository adminRepo = new org.apache.archiva.admin.model.beans.RemoteRepository( getArchivaConfiguration().getDefaultLocale() );
123 setBaseRepoAttributes( adminRepo, repo );
124 adminRepo.setUrl( convertUriToString( repo.getLocation() ));
125 adminRepo.setCronExpression( repo.getSchedulingDefinition() );
126 adminRepo.setCheckPath( repo.getCheckPath() );
127 adminRepo.setExtraHeaders( repo.getExtraHeaders() );
128 adminRepo.setExtraParameters( repo.getExtraParameters() );
129 adminRepo.setTimeout( (int) repo.getTimeout().getSeconds() );
130 RepositoryCredentials creds = repo.getLoginCredentials();
131 if (creds!=null && creds instanceof PasswordCredentials) {
132 PasswordCredentials pCreds = (PasswordCredentials) creds;
133 adminRepo.setUserName( pCreds.getUsername() );
134 adminRepo.setPassword( new String(pCreds.getPassword()!=null ? pCreds.getPassword() : new char[0]) );
136 if (repo.supportsFeature( RemoteIndexFeature.class )) {
137 RemoteIndexFeature rif = repo.getFeature( RemoteIndexFeature.class ).get();
138 adminRepo.setRemoteIndexUrl( convertUriToString( rif.getIndexUri() ) );
139 adminRepo.setDownloadRemoteIndex( rif.isDownloadRemoteIndex() );
140 adminRepo.setRemoteDownloadNetworkProxyId( rif.getProxyId() );
141 adminRepo.setDownloadRemoteIndexOnStartup( rif.isDownloadRemoteIndexOnStartup() );
142 adminRepo.setRemoteDownloadTimeout( (int) rif.getDownloadTimeout().getSeconds() );
144 if (repo.supportsFeature(IndexCreationFeature.class)) {
145 IndexCreationFeature icf = repo.getFeature(IndexCreationFeature.class).get();
146 adminRepo.setIndexDirectory(PathUtil.getPathFromUri(icf.getIndexPath()).toString());
148 adminRepo.setDescription(repo.getDescription());
152 private RemoteRepositoryConfiguration getRepositoryConfiguration( org.apache.archiva.admin.model.beans.RemoteRepository repo) {
153 RemoteRepositoryConfiguration repoConfig = new RemoteRepositoryConfiguration();
154 setBaseRepoAttributes( repoConfig, repo );
155 repoConfig.setUrl( getRepositoryCommonValidator().removeExpressions( repo.getUrl() ) );
156 repoConfig.setRefreshCronExpression( repo.getCronExpression() );
157 repoConfig.setCheckPath( repo.getCheckPath() );
158 repoConfig.setExtraHeaders( repo.getExtraHeaders() );
159 repoConfig.setExtraParameters( repo.getExtraParameters() );
160 repoConfig.setUsername( repo.getUserName() );
161 repoConfig.setPassword( repo.getPassword() );
162 repoConfig.setTimeout( repo.getTimeout() );
163 repoConfig.setRemoteIndexUrl( repo.getRemoteIndexUrl() );
164 repoConfig.setDownloadRemoteIndex( repo.isDownloadRemoteIndex() );
165 repoConfig.setRemoteDownloadNetworkProxyId( repo.getRemoteDownloadNetworkProxyId() );
166 repoConfig.setDownloadRemoteIndexOnStartup( repo.isDownloadRemoteIndexOnStartup() );
167 repoConfig.setRemoteDownloadTimeout( repo.getRemoteDownloadTimeout() );
168 repoConfig.setDescription(repo.getDescription());
169 repoConfig.setIndexDir(repo.getIndexDirectory());
174 public List<org.apache.archiva.admin.model.beans.RemoteRepository> getRemoteRepositories()
175 throws RepositoryAdminException
178 return repositoryRegistry.getRemoteRepositories().stream().map( repo -> convertRepo( repo ) ).collect( Collectors.toList());
182 public org.apache.archiva.admin.model.beans.RemoteRepository getRemoteRepository( String repositoryId )
183 throws RepositoryAdminException
185 return convertRepo( repositoryRegistry.getRemoteRepository( repositoryId ));
189 public Boolean addRemoteRepository( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository, AuditInformation auditInformation )
190 throws RepositoryAdminException
192 triggerAuditEvent( remoteRepository.getId(), null, AuditEvent.ADD_REMOTE_REPO, auditInformation );
193 getRepositoryCommonValidator().basicValidation( remoteRepository, false );
195 //TODO we can validate it's a good uri/url
196 if ( StringUtils.isEmpty( remoteRepository.getUrl() ) )
198 throw new RepositoryAdminException( "url cannot be null" );
201 //MRM-752 - url needs trimming
202 //MRM-1940 - URL should not end with a slash
203 remoteRepository.setUrl( StringUtils.stripEnd(StringUtils.trim( remoteRepository.getUrl() ), "/"));
205 if (StringUtils.isEmpty(remoteRepository.getCheckPath())) {
206 String checkUrl = remoteRepository.getUrl().toLowerCase();
207 for (RepositoryCheckPath path : getArchivaConfiguration ().getConfiguration().getArchivaDefaultConfiguration().getDefaultCheckPaths()) {
208 log.debug("Checking path for urls: {} <-> {}", checkUrl, path.getUrl());
209 if (checkUrl.startsWith(path.getUrl())) {
210 remoteRepository.setCheckPath(path.getPath());
216 Configuration configuration = getArchivaConfiguration().getConfiguration();
217 RemoteRepositoryConfiguration remoteRepositoryConfiguration =
218 getRepositoryConfiguration( remoteRepository );
222 repositoryRegistry.putRepository( remoteRepositoryConfiguration, configuration );
224 catch ( RepositoryException e )
226 log.error("Could not add remote repository {}: {}", remoteRepositoryConfiguration.getId(), e.getMessage(), e);
227 throw new RepositoryAdminException( "Adding of remote repository failed"+(e.getMessage()==null?"":": "+e.getMessage()) );
231 saveConfiguration( configuration );
237 public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation )
238 throws RepositoryAdminException
241 triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_REMOTE_REPO, auditInformation );
243 Configuration configuration = getArchivaConfiguration().getConfiguration();
245 RemoteRepository repo = repositoryRegistry.getRemoteRepository( repositoryId );
247 throw new RepositoryAdminException( "Could not delete repository "+repositoryId+". The repository does not exist." );
251 repositoryRegistry.removeRepository( repo, configuration );
253 catch ( RepositoryException e )
255 log.error("Deletion of remote repository failed {}: {}", repo.getId(), e.getMessage(), e);
256 throw new RepositoryAdminException( "Could not delete remote repository"+(e.getMessage()==null?"":": "+e.getMessage()) );
259 saveConfiguration( configuration );
265 public Boolean updateRemoteRepository( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository, AuditInformation auditInformation )
266 throws RepositoryAdminException
269 String repositoryId = remoteRepository.getId();
271 triggerAuditEvent( repositoryId, null, AuditEvent.MODIFY_REMOTE_REPO, auditInformation );
273 // update means : remove and add
275 Configuration configuration = getArchivaConfiguration().getConfiguration();
277 RemoteRepositoryConfiguration remoteRepositoryConfiguration = getRepositoryConfiguration( remoteRepository );
280 repositoryRegistry.putRepository( remoteRepositoryConfiguration, configuration );
282 catch ( RepositoryException e )
284 log.error("Could not update remote repository {}: {}", remoteRepositoryConfiguration.getId(), e.getMessage(), e);
285 throw new RepositoryAdminException( "Update of remote repository failed"+(e.getMessage()==null?"":": "+e.getMessage()) );
287 saveConfiguration( configuration );
292 public Map<String, org.apache.archiva.admin.model.beans.RemoteRepository> getRemoteRepositoriesAsMap()
293 throws RepositoryAdminException
295 java.util.Map<String, org.apache.archiva.admin.model.beans.RemoteRepository> map = new HashMap<>();
297 for ( org.apache.archiva.admin.model.beans.RemoteRepository repo : getRemoteRepositories() )
299 map.put( repo.getId(), repo );
306 public IndexingContext createIndexContext( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository )
307 throws RepositoryAdminException
311 RemoteRepository repo = repositoryRegistry.getRemoteRepository(remoteRepository.getId());
312 return repo.getIndexingContext().getBaseContext(IndexingContext.class);
313 /*String appServerBase = getRegistry().getString( "appserver.base" );
315 String contextKey = "remote-" + remoteRepository.getId();
316 IndexingContext indexingContext = indexer.getIndexingContexts().get( contextKey );
317 if ( indexingContext != null )
319 return indexingContext;
321 // create remote repository path
322 Path repoDir = Paths.get( appServerBase, "data/remotes/" + remoteRepository.getId() );
323 if ( !Files.exists(repoDir) )
325 Files.createDirectories(repoDir);
328 Path indexDirectory = null;
330 // is there configured indexDirectory ?
331 String indexDirectoryPath = remoteRepository.getIndexDirectory();
333 if ( StringUtils.isNotBlank( indexDirectoryPath ) )
335 repoDir.resolve( indexDirectoryPath );
337 // if not configured use a default value
338 if ( indexDirectory == null )
340 indexDirectory = repoDir.resolve(".index" );
342 if ( !Files.exists(indexDirectory) )
344 Files.createDirectories(indexDirectory);
350 return indexer.addIndexingContext( contextKey, remoteRepository.getId(), repoDir.toFile(), indexDirectory.toFile(),
351 remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ),
354 catch ( IndexFormatTooOldException e )
356 // existing index with an old lucene format so we need to delete it!!!
357 // delete it first then recreate it.
358 log.warn( "the index of repository {} is too old we have to delete and recreate it", //
359 remoteRepository.getId() );
360 org.apache.archiva.common.utils.FileUtils.deleteDirectory( indexDirectory );
361 return indexer.addIndexingContext( contextKey, remoteRepository.getId(), repoDir.toFile(), indexDirectory.toFile(),
362 remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ),
366 } catch (UnsupportedBaseContextException e) {
367 throw new RepositoryAdminException( e.getMessage(), e);