]> source.dussan.org Git - archiva.git/blob
d54c797b02f7d3dfab0dd4b8bcd7dc5b424febb5
[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.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;
39
40 import javax.annotation.PostConstruct;
41 import javax.annotation.PreDestroy;
42 import javax.inject.Inject;
43 import java.io.File;
44 import java.io.IOException;
45 import java.util.ArrayList;
46 import java.util.HashMap;
47 import java.util.List;
48 import java.util.Map;
49
50 /**
51  * @author Olivier Lamy
52  * @since 1.4-M1
53  */
54 @Service("remoteRepositoryAdmin#default")
55 public class DefaultRemoteRepositoryAdmin
56     extends AbstractRepositoryAdmin
57     implements RemoteRepositoryAdmin
58 {
59
60     @Inject
61     private List<? extends IndexCreator> indexCreators;
62
63     @Inject
64     private NexusIndexer indexer;
65
66     @PostConstruct
67     private void initialize()
68         throws RepositoryAdminException
69     {
70         for ( RemoteRepository remoteRepository : getRemoteRepositories() )
71         {
72             createIndexContext( remoteRepository );
73         }
74     }
75
76     @PreDestroy
77     private void shutdown()
78         throws RepositoryAdminException
79     {
80         try
81         {
82             List<RemoteRepository> remoteRepositories = getRemoteRepositories();
83             // close index on shutdown
84             for ( RemoteRepository remoteRepository : remoteRepositories )
85             {
86                 IndexingContext context = indexer.getIndexingContexts().get( remoteRepository.getId() );
87                 if ( context != null )
88                 {
89                     indexer.removeIndexingContext( context, false );
90                 }
91             }
92         }
93         catch ( IOException e )
94         {
95             throw new RepositoryAdminException( e.getMessage(), e );
96         }
97     }
98
99
100     @Override
101     public List<RemoteRepository> getRemoteRepositories()
102         throws RepositoryAdminException
103     {
104         List<RemoteRepository> remoteRepositories =
105             new ArrayList<>( getArchivaConfiguration().getConfiguration().getRemoteRepositories().size() );
106         for ( RemoteRepositoryConfiguration repositoryConfiguration : getArchivaConfiguration().getConfiguration().getRemoteRepositories() )
107         {
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 );
127         }
128         return remoteRepositories;
129     }
130
131     @Override
132     public RemoteRepository getRemoteRepository( String repositoryId )
133         throws RepositoryAdminException
134     {
135         for ( RemoteRepository remoteRepository : getRemoteRepositories() )
136         {
137             if ( StringUtils.equals( repositoryId, remoteRepository.getId() ) )
138             {
139                 return remoteRepository;
140             }
141         }
142         return null;
143     }
144
145     @Override
146     public Boolean addRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation )
147         throws RepositoryAdminException
148     {
149         triggerAuditEvent( remoteRepository.getId(), null, AuditEvent.ADD_REMOTE_REPO, auditInformation );
150         getRepositoryCommonValidator().basicValidation( remoteRepository, false );
151
152         //TODO we can validate it's a good uri/url
153         if ( StringUtils.isEmpty( remoteRepository.getUrl() ) )
154         {
155             throw new RepositoryAdminException( "url cannot be null" );
156         }
157
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() ), "/"));
161
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());
168                     break;
169                 }
170             }
171         }
172
173         RemoteRepositoryConfiguration remoteRepositoryConfiguration =
174             getRemoteRepositoryConfiguration( remoteRepository );
175
176         Configuration configuration = getArchivaConfiguration().getConfiguration();
177         configuration.addRemoteRepository( remoteRepositoryConfiguration );
178         saveConfiguration( configuration );
179
180         return Boolean.TRUE;
181     }
182
183     @Override
184     public Boolean deleteRemoteRepository( String repositoryId, AuditInformation auditInformation )
185         throws RepositoryAdminException
186     {
187
188         triggerAuditEvent( repositoryId, null, AuditEvent.DELETE_REMOTE_REPO, auditInformation );
189
190         Configuration configuration = getArchivaConfiguration().getConfiguration();
191
192         RemoteRepositoryConfiguration remoteRepositoryConfiguration =
193             configuration.getRemoteRepositoriesAsMap().get( repositoryId );
194         if ( remoteRepositoryConfiguration == null )
195         {
196             throw new RepositoryAdminException(
197                 "remoteRepository with id " + repositoryId + " not exist cannot remove it" );
198         }
199
200         configuration.removeRemoteRepository( remoteRepositoryConfiguration );
201
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 )
206         {
207             if ( StringUtils.equals( proxyConnector.getTargetRepoId(), repositoryId ) )
208             {
209                 configuration.removeProxyConnector( proxyConnector );
210             }
211         }
212
213         saveConfiguration( configuration );
214
215         return Boolean.TRUE;
216     }
217
218     @Override
219     public Boolean updateRemoteRepository( RemoteRepository remoteRepository, AuditInformation auditInformation )
220         throws RepositoryAdminException
221     {
222
223         String repositoryId = remoteRepository.getId();
224
225         triggerAuditEvent( repositoryId, null, AuditEvent.MODIFY_REMOTE_REPO, auditInformation );
226
227         // update means : remove and add
228
229         Configuration configuration = getArchivaConfiguration().getConfiguration();
230
231         RemoteRepositoryConfiguration remoteRepositoryConfiguration =
232             configuration.getRemoteRepositoriesAsMap().get( repositoryId );
233         if ( remoteRepositoryConfiguration == null )
234         {
235             throw new RepositoryAdminException(
236                 "remoteRepository with id " + repositoryId + " not exist cannot remove it" );
237         }
238
239         configuration.removeRemoteRepository( remoteRepositoryConfiguration );
240
241         remoteRepositoryConfiguration = getRemoteRepositoryConfiguration( remoteRepository );
242         configuration.addRemoteRepository( remoteRepositoryConfiguration );
243         saveConfiguration( configuration );
244
245         return Boolean.TRUE;
246     }
247
248     @Override
249     public Map<String, RemoteRepository> getRemoteRepositoriesAsMap()
250         throws RepositoryAdminException
251     {
252         java.util.Map<String, RemoteRepository> map = new HashMap<>();
253
254         for ( RemoteRepository repo : getRemoteRepositories() )
255         {
256             map.put( repo.getId(), repo );
257         }
258
259         return map;
260     }
261
262     @Override
263     public IndexingContext createIndexContext( RemoteRepository remoteRepository )
264         throws RepositoryAdminException
265     {
266         try
267         {
268             String appServerBase = getRegistry().getString( "appserver.base" );
269
270             String contextKey = "remote-" + remoteRepository.getId();
271             IndexingContext indexingContext = indexer.getIndexingContexts().get( contextKey );
272             if ( indexingContext != null )
273             {
274                 return indexingContext;
275             }
276             // create remote repository path
277             File repoDir = new File( appServerBase, "data/remotes/" + remoteRepository.getId() );
278             if ( !repoDir.exists() )
279             {
280                 repoDir.mkdirs();
281             }
282
283             File indexDirectory = null;
284
285             // is there configured indexDirectory ?
286             String indexDirectoryPath = remoteRepository.getIndexDirectory();
287
288             if ( StringUtils.isNotBlank( indexDirectoryPath ) )
289             {
290                 if ( new File( indexDirectoryPath ).isAbsolute() )
291                 {
292                     indexDirectory = new File( indexDirectoryPath );
293                 }
294                 else
295                 {
296                     indexDirectory = new File( repoDir, indexDirectoryPath );
297                 }
298             }
299             // if not configured use a default value
300             if ( indexDirectory == null )
301             {
302                 indexDirectory = new File( repoDir, ".index" );
303             }
304             if ( !indexDirectory.exists() )
305             {
306                 indexDirectory.mkdirs();
307             }
308
309             try
310             {
311
312                 return indexer.addIndexingContext( contextKey, remoteRepository.getId(), repoDir, indexDirectory,
313                                                    remoteRepository.getUrl(), calculateIndexRemoteUrl( remoteRepository ),
314                                                    indexCreators );
315             }
316             catch ( IndexFormatTooOldException e )
317             {
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 ),
325                                                    indexCreators );
326
327             }
328         }
329         catch ( IOException | UnsupportedExistingLuceneIndexException e )
330         {
331             throw new RepositoryAdminException( e.getMessage(), e );
332         }
333
334     }
335
336     protected String calculateIndexRemoteUrl( RemoteRepository remoteRepository )
337     {
338         if ( StringUtils.startsWith( remoteRepository.getRemoteIndexUrl(), "http" ) )
339         {
340             String baseUrl = remoteRepository.getRemoteIndexUrl();
341             return baseUrl.endsWith( "/" ) ? StringUtils.substringBeforeLast( baseUrl, "/" ) : baseUrl;
342         }
343         String baseUrl = StringUtils.endsWith( remoteRepository.getUrl(), "/" ) ? StringUtils.substringBeforeLast(
344             remoteRepository.getUrl(), "/" ) : remoteRepository.getUrl();
345
346         baseUrl = StringUtils.isEmpty( remoteRepository.getRemoteIndexUrl() )
347             ? baseUrl + "/.index"
348             : baseUrl + "/" + remoteRepository.getRemoteIndexUrl();
349         return baseUrl;
350
351     }
352
353     private RemoteRepositoryConfiguration getRemoteRepositoryConfiguration( RemoteRepository remoteRepository )
354     {
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;
377     }
378
379 }