]> source.dussan.org Git - archiva.git/blob
3f8c58bbe68ed2c683218a3f742c62b3d35bc370
[archiva.git] /
1 package org.apache.archiva.admin.repository.remote;
2 /*
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
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
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
18  * under the License.
19  */
20
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.configuration.Configuration;
26 import org.apache.archiva.configuration.ProxyConnectorConfiguration;
27 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
28 import org.apache.archiva.configuration.RepositoryCheckPath;
29 import org.apache.archiva.indexer.UnsupportedBaseContextException;
30 import org.apache.archiva.metadata.model.facets.AuditEvent;
31 import org.apache.archiva.repository.RemoteRepository;
32 import org.apache.archiva.repository.PasswordCredentials;
33 import org.apache.archiva.repository.RepositoryCredentials;
34 import org.apache.archiva.repository.RepositoryException;
35 import org.apache.archiva.repository.RepositoryRegistry;
36 import org.apache.archiva.repository.features.RemoteIndexFeature;
37 import org.apache.commons.lang.StringUtils;
38 import org.apache.maven.index.NexusIndexer;
39 import org.apache.maven.index.context.IndexCreator;
40 import org.apache.maven.index.context.IndexingContext;
41 import org.apache.maven.index.context.UnsupportedExistingLuceneIndexException;
42 import org.apache.maven.index_shaded.lucene.index.IndexFormatTooOldException;
43 import org.springframework.stereotype.Service;
44
45 import javax.annotation.PostConstruct;
46 import javax.annotation.PreDestroy;
47 import javax.inject.Inject;
48 import java.io.IOException;
49 import java.nio.file.Files;
50 import java.nio.file.Path;
51 import java.nio.file.Paths;
52 import java.util.ArrayList;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56 import java.util.stream.Collectors;
57
58 /**
59  * @author Olivier Lamy
60  * @since 1.4-M1
61  */
62 @Service("remoteRepositoryAdmin#default")
63 public class DefaultRemoteRepositoryAdmin
64     extends AbstractRepositoryAdmin
65     implements RemoteRepositoryAdmin
66 {
67
68     @Inject
69     RepositoryRegistry repositoryRegistry;
70
71     @Inject
72     private List<? extends IndexCreator> indexCreators;
73
74     @Inject
75     private NexusIndexer indexer;
76
77     @PostConstruct
78     private void initialize()
79         throws RepositoryAdminException
80     {
81         for ( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository : getRemoteRepositories() )
82         {
83             createIndexContext( remoteRepository );
84         }
85     }
86
87     @PreDestroy
88     private void shutdown()
89         throws RepositoryAdminException
90     {
91         try
92         {
93             List<org.apache.archiva.admin.model.beans.RemoteRepository> remoteRepositories = getRemoteRepositories();
94             // close index on shutdown
95             for ( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository : remoteRepositories )
96             {
97                 IndexingContext context = indexer.getIndexingContexts().get( remoteRepository.getId() );
98                 if ( context != null )
99                 {
100                     indexer.removeIndexingContext( context, false );
101                 }
102             }
103         }
104         catch ( IOException e )
105         {
106             throw new RepositoryAdminException( e.getMessage(), e );
107         }
108     }
109
110
111     /*
112  * Conversion between the repository from the registry and the serialized DTO for the admin API
113  */
114     private org.apache.archiva.admin.model.beans.RemoteRepository convertRepo( RemoteRepository repo ) {
115         if (repo==null) {
116             return null;
117         }
118         org.apache.archiva.admin.model.beans.RemoteRepository adminRepo = new org.apache.archiva.admin.model.beans.RemoteRepository( getArchivaConfiguration().getDefaultLocale() );
119         setBaseRepoAttributes( adminRepo, repo );
120         adminRepo.setUrl( convertUriToString( repo.getLocation() ));
121         adminRepo.setCronExpression( repo.getSchedulingDefinition() );
122         adminRepo.setCheckPath( repo.getCheckPath() );
123         adminRepo.setExtraHeaders( repo.getExtraHeaders() );
124         adminRepo.setExtraParameters( repo.getExtraParameters() );
125         adminRepo.setTimeout( (int) repo.getTimeout().getSeconds() );
126         RepositoryCredentials creds = repo.getLoginCredentials();
127         if (creds!=null && creds instanceof PasswordCredentials) {
128             PasswordCredentials pCreds = (PasswordCredentials) creds;
129             adminRepo.setUserName( pCreds.getUsername() );
130             adminRepo.setPassword( new String(pCreds.getPassword()!=null ? pCreds.getPassword() : new char[0]) );
131         }
132         if (repo.supportsFeature( RemoteIndexFeature.class )) {
133             RemoteIndexFeature rif = repo.getFeature( RemoteIndexFeature.class ).get();
134             adminRepo.setRemoteIndexUrl( convertUriToString( rif.getIndexUri() ) );
135             adminRepo.setDownloadRemoteIndex( rif.isDownloadRemoteIndex() );
136             adminRepo.setRemoteDownloadNetworkProxyId( rif.getProxyId() );
137             adminRepo.setDownloadRemoteIndexOnStartup( rif.isDownloadRemoteIndexOnStartup() );
138             adminRepo.setRemoteDownloadTimeout( (int) rif.getDownloadTimeout().getSeconds() );
139         }
140         return adminRepo;
141     }
142
143     private RemoteRepositoryConfiguration getRepositoryConfiguration( org.apache.archiva.admin.model.beans.RemoteRepository repo) {
144         RemoteRepositoryConfiguration repoConfig = new RemoteRepositoryConfiguration();
145         setBaseRepoAttributes( repoConfig, repo );
146         repoConfig.setUrl( getRepositoryCommonValidator().removeExpressions( repo.getUrl() ) );
147         repoConfig.setRefreshCronExpression( repo.getCronExpression() );
148         repoConfig.setCheckPath( repo.getCheckPath() );
149         repoConfig.setExtraHeaders( repo.getExtraHeaders() );
150         repoConfig.setExtraParameters( repo.getExtraParameters() );
151         repoConfig.setUsername( repo.getUserName() );
152         repoConfig.setPassword( repo.getPassword() );
153         repoConfig.setTimeout( repo.getTimeout() );
154         repoConfig.setRemoteIndexUrl( repo.getRemoteIndexUrl() );
155         repoConfig.setDownloadRemoteIndex( repo.isDownloadRemoteIndex() );
156         repoConfig.setRemoteDownloadNetworkProxyId( repo.getRemoteDownloadNetworkProxyId() );
157         repoConfig.setDownloadRemoteIndexOnStartup( repo.isDownloadRemoteIndexOnStartup() );
158         repoConfig.setRemoteDownloadTimeout( repo.getRemoteDownloadTimeout() );
159         return repoConfig;
160     }
161
162     @Override
163     public List<org.apache.archiva.admin.model.beans.RemoteRepository> getRemoteRepositories()
164         throws RepositoryAdminException
165     {
166
167         return repositoryRegistry.getRemoteRepositories().stream().map( repo -> convertRepo( repo ) ).collect( Collectors.toList());
168     }
169
170     @Override
171     public org.apache.archiva.admin.model.beans.RemoteRepository getRemoteRepository( String repositoryId )
172         throws RepositoryAdminException
173     {
174         return convertRepo( repositoryRegistry.getRemoteRepository( repositoryId ));
175     }
176
177     @Override
178     public Boolean addRemoteRepository( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository, AuditInformation auditInformation )
179         throws RepositoryAdminException
180     {
181         triggerAuditEvent( remoteRepository.getId(), null, AuditEvent.ADD_REMOTE_REPO, auditInformation );
182         getRepositoryCommonValidator().basicValidation( remoteRepository, false );
183
184         //TODO we can validate it's a good uri/url
185         if ( StringUtils.isEmpty( remoteRepository.getUrl() ) )
186         {
187             throw new RepositoryAdminException( "url cannot be null" );
188         }
189
190         //MRM-752 - url needs trimming
191         //MRM-1940 - URL should not end with a slash
192         remoteRepository.setUrl( StringUtils.stripEnd(StringUtils.trim( remoteRepository.getUrl() ), "/"));
193
194         if (StringUtils.isEmpty(remoteRepository.getCheckPath())) {
195             String checkUrl = remoteRepository.getUrl().toLowerCase();
196             for (RepositoryCheckPath path : getArchivaConfiguration ().getConfiguration().getArchivaDefaultConfiguration().getDefaultCheckPaths()) {
197                 log.debug("Checking path for urls: {} <-> {}", checkUrl, path.getUrl());
198                 if (checkUrl.startsWith(path.getUrl())) {
199                     remoteRepository.setCheckPath(path.getPath());
200                     break;
201                 }
202             }
203         }
204
205         Configuration configuration = getArchivaConfiguration().getConfiguration();
206         RemoteRepositoryConfiguration remoteRepositoryConfiguration =
207             getRepositoryConfiguration( remoteRepository );
208
209         try
210         {
211             repositoryRegistry.putRepository( remoteRepositoryConfiguration, configuration );
212         }
213         catch ( RepositoryException e )
214         {
215             log.error("Could not add remote repository {}: {}", remoteRepositoryConfiguration.getId(), e.getMessage(), e);
216             throw new RepositoryAdminException( "Adding of remote repository failed"+(e.getMessage()==null?"":": "+e.getMessage()) );
217
218         }
219
220         saveConfiguration( configuration );
221
222         return Boolean.TRUE;
223     }
224
225     @Override
226     public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation )
227         throws RepositoryAdminException
228     {
229
230         triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_REMOTE_REPO, auditInformation );
231
232         Configuration configuration = getArchivaConfiguration().getConfiguration();
233
234         RemoteRepository repo = repositoryRegistry.getRemoteRepository( repositoryId );
235         if (repo==null) {
236             throw new RepositoryAdminException( "Could not delete repository "+repositoryId+". The repository does not exist." );
237         }
238         try
239         {
240             repositoryRegistry.removeRepository( repo, configuration );
241         }
242         catch ( RepositoryException e )
243         {
244             log.error("Deletion of remote repository failed {}: {}", repo.getId(), e.getMessage(), e);
245             throw new RepositoryAdminException( "Could not delete remote repository"+(e.getMessage()==null?"":": "+e.getMessage()) );
246         }
247
248         // TODO use ProxyConnectorAdmin interface ?
249         // [MRM-520] Proxy Connectors are not deleted with the deletion of a Repository.
250         List<ProxyConnectorConfiguration> proxyConnectors = new ArrayList<>( configuration.getProxyConnectors() );
251         for ( ProxyConnectorConfiguration proxyConnector : proxyConnectors )
252         {
253             if ( StringUtils.equals( proxyConnector.getTargetRepoId(), repositoryId ) )
254             {
255                 configuration.removeProxyConnector( proxyConnector );
256             }
257         }
258
259         saveConfiguration( configuration );
260
261         return Boolean.TRUE;
262     }
263
264     @Override
265     public Boolean updateRemoteRepository( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository, AuditInformation auditInformation )
266         throws RepositoryAdminException
267     {
268
269         String repositoryId = remoteRepository.getId();
270
271         triggerAuditEvent( repositoryId, null, AuditEvent.MODIFY_REMOTE_REPO, auditInformation );
272
273         // update means : remove and add
274
275         Configuration configuration = getArchivaConfiguration().getConfiguration();
276
277         RemoteRepositoryConfiguration remoteRepositoryConfiguration = getRepositoryConfiguration( remoteRepository );
278         try
279         {
280             repositoryRegistry.putRepository( remoteRepositoryConfiguration, configuration );
281         }
282         catch ( RepositoryException e )
283         {
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()) );
286         }
287         saveConfiguration( configuration );
288         return Boolean.TRUE;
289     }
290
291     @Override
292     public Map<String, org.apache.archiva.admin.model.beans.RemoteRepository> getRemoteRepositoriesAsMap()
293         throws RepositoryAdminException
294     {
295         java.util.Map<String, org.apache.archiva.admin.model.beans.RemoteRepository> map = new HashMap<>();
296
297         for ( org.apache.archiva.admin.model.beans.RemoteRepository repo : getRemoteRepositories() )
298         {
299             map.put( repo.getId(), repo );
300         }
301
302         return map;
303     }
304
305     @Override
306     public IndexingContext createIndexContext( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository )
307         throws RepositoryAdminException
308     {
309         try
310         {
311             RemoteRepository repo = repositoryRegistry.getRemoteRepository(remoteRepository.getId());
312             return repo.getIndexingContext().getBaseContext(IndexingContext.class);
313             /*String appServerBase = getRegistry().getString( "appserver.base" );
314
315             String contextKey = "remote-" + remoteRepository.getId();
316             IndexingContext indexingContext = indexer.getIndexingContexts().get( contextKey );
317             if ( indexingContext != null )
318             {
319                 return indexingContext;
320             }
321             // create remote repository path
322             Path repoDir = Paths.get( appServerBase, "data/remotes/" + remoteRepository.getId() );
323             if ( !Files.exists(repoDir) )
324             {
325                 Files.createDirectories(repoDir);
326             }
327
328             Path indexDirectory = null;
329
330             // is there configured indexDirectory ?
331             String indexDirectoryPath = remoteRepository.getIndexDirectory();
332
333             if ( StringUtils.isNotBlank( indexDirectoryPath ) )
334             {
335                 repoDir.resolve( indexDirectoryPath );
336             }
337             // if not configured use a default value
338             if ( indexDirectory == null )
339             {
340                 indexDirectory = repoDir.resolve(".index" );
341             }
342             if ( !Files.exists(indexDirectory) )
343             {
344                 Files.createDirectories(indexDirectory);
345             }
346
347             try
348             {
349
350                 return indexer.addIndexingContext( contextKey, remoteRepository.getId(), repoDir.toFile(), indexDirectory.toFile(),
351                                                    remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ),
352                                                    indexCreators );
353             }
354             catch ( IndexFormatTooOldException e )
355             {
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 ),
363                                                    indexCreators );
364
365             }*/
366         } catch (UnsupportedBaseContextException e) {
367             throw new RepositoryAdminException( e.getMessage(), e);
368         }
369
370     }
371
372     protected String calculateIndexRemoteUrl( org.apache.archiva.admin.model.beans.RemoteRepository remoteRepository )
373     {
374         if ( StringUtils.startsWith( remoteRepository.getRemoteIndexUrl(), "http" ) )
375         {
376             String baseUrl = remoteRepository.getRemoteIndexUrl();
377             return baseUrl.endsWith( "/" ) ? StringUtils.substringBeforeLast( baseUrl, "/" ) : baseUrl;
378         }
379         String baseUrl = StringUtils.endsWith( remoteRepository.getUrl(), "/" ) ? StringUtils.substringBeforeLast(
380             remoteRepository.getUrl(), "/" ) : remoteRepository.getUrl();
381
382         baseUrl = StringUtils.isEmpty( remoteRepository.getRemoteIndexUrl() )
383             ? baseUrl + "/.index"
384             : baseUrl + "/" + remoteRepository.getRemoteIndexUrl();
385         return baseUrl;
386
387     }
388
389
390
391 }