]> source.dussan.org Git - archiva.git/blob
f50d7259e1d90ad05fffc6b2cba17fe17fcb9da9
[archiva.git] /
1 package org.apache.archiva.repository.maven2;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import org.apache.archiva.common.utils.PathUtil;
23 import org.apache.archiva.configuration.AbstractRepositoryConfiguration;
24 import org.apache.archiva.configuration.ArchivaConfiguration;
25 import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
26 import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
27 import org.apache.archiva.repository.*;
28 import org.apache.archiva.repository.features.ArtifactCleanupFeature;
29 import org.apache.archiva.repository.features.IndexCreationFeature;
30 import org.apache.archiva.repository.features.RemoteIndexFeature;
31 import org.apache.archiva.repository.features.StagingRepositoryFeature;
32 import org.apache.commons.lang.StringUtils;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.springframework.stereotype.Service;
36
37 import javax.inject.Inject;
38 import java.io.IOException;
39 import java.net.URI;
40 import java.net.URISyntaxException;
41 import java.nio.file.Files;
42 import java.nio.file.Path;
43 import java.nio.file.Paths;
44 import java.time.Duration;
45 import java.time.Period;
46 import java.time.temporal.ChronoUnit;
47 import java.util.HashSet;
48 import java.util.Set;
49
50 /**
51  * Provider for the maven2 repository implementations
52  */
53 @Service("mavenRepositoryProvider")
54 public class MavenRepositoryProvider implements RepositoryProvider {
55
56
57     @Inject
58     private ArchivaConfiguration archivaConfiguration;
59
60     private static final Logger log = LoggerFactory.getLogger(MavenRepositoryProvider.class);
61
62     static final Set<RepositoryType> TYPES = new HashSet<>();
63
64     static {
65         TYPES.add(RepositoryType.MAVEN);
66     }
67
68     @Override
69     public Set<RepositoryType> provides() {
70         return TYPES;
71     }
72
73     @Override
74     public EditableManagedRepository createManagedInstance(String id, String name) {
75         return new MavenManagedRepository(id, name, archivaConfiguration.getRepositoryBaseDir());
76     }
77
78     @Override
79     public EditableRemoteRepository createRemoteInstance(String id, String name) {
80         return new MavenRemoteRepository(id, name, archivaConfiguration.getRemoteRepositoryBaseDir());
81     }
82
83     private URI getURIFromString(String uriStr) throws RepositoryException {
84         URI uri;
85         try {
86             if (StringUtils.isEmpty(uriStr)) {
87                 return new URI("");
88             }
89             if (uriStr.startsWith("/")) {
90                 // only absolute paths are prepended with file scheme
91                 uri = new URI("file://" + uriStr);
92             } else {
93                 uri = new URI(uriStr);
94             }
95             if (uri.getScheme() != null && !"file".equals(uri.getScheme())) {
96                 log.error("Bad URI scheme found: {}, URI={}", uri.getScheme(), uri);
97                 throw new RepositoryException("The uri " + uriStr + " is not valid. Only file:// URI is allowed for maven.");
98             }
99         } catch (URISyntaxException e) {
100             String newCfg = "file://" + uriStr;
101             try {
102                 uri = new URI(newCfg);
103             } catch (URISyntaxException e1) {
104                 log.error("Could not create URI from {} -> ", uriStr, newCfg);
105                 throw new RepositoryException("The config entry " + uriStr + " cannot be converted to URI.");
106             }
107         }
108         log.debug("Setting location uri: {}", uri);
109         return uri;
110     }
111
112     @Override
113     public ManagedRepository createManagedInstance(ManagedRepositoryConfiguration cfg) throws RepositoryException {
114         MavenManagedRepository repo = new MavenManagedRepository(cfg.getId(), cfg.getName(), archivaConfiguration.getRepositoryBaseDir());
115         updateManagedInstance(repo, cfg);
116         return repo;
117     }
118
119     @Override
120     public void updateManagedInstance(EditableManagedRepository repo, ManagedRepositoryConfiguration cfg) throws RepositoryException {
121         try {
122             repo.setLocation(getURIFromString(cfg.getLocation()));
123         } catch (UnsupportedURIException e) {
124             throw new RepositoryException("The location entry is not a valid uri: " + cfg.getLocation());
125         }
126         setBaseConfig(repo, cfg);
127         Path repoDir = repo.getLocalPath();
128         if (!Files.exists(repoDir)) {
129             log.debug("Creating repo directory {}", repoDir);
130             try {
131                 Files.createDirectories(repoDir);
132             } catch (IOException e) {
133                 log.error("Could not create directory {} for repository {}", repo.getLocalPath(), repo.getId(), e);
134                 throw new RepositoryException("Could not create directory for repository " + repo.getLocalPath());
135             }
136         }
137         repo.setSchedulingDefinition(cfg.getRefreshCronExpression());
138         repo.setBlocksRedeployment(cfg.isBlockRedeployments());
139         repo.setScanned(cfg.isScanned());
140         if (cfg.isReleases()) {
141             repo.addActiveReleaseScheme(ReleaseScheme.RELEASE);
142         }
143         if (cfg.isSnapshots()) {
144             repo.addActiveReleaseScheme(ReleaseScheme.SNAPSHOT);
145         }
146
147         StagingRepositoryFeature stagingRepositoryFeature = repo.getFeature(StagingRepositoryFeature.class).get();
148         stagingRepositoryFeature.setStageRepoNeeded(cfg.isStageRepoNeeded());
149
150         IndexCreationFeature indexCreationFeature = repo.getFeature(IndexCreationFeature.class).get();
151         indexCreationFeature.setSkipPackedIndexCreation(cfg.isSkipPackedIndexCreation());
152         indexCreationFeature.setIndexPath(getURIFromString(cfg.getIndexDir()));
153         Path indexPath;
154         if (indexCreationFeature.getIndexPath().getScheme() == null) {
155             indexPath = Paths.get(indexCreationFeature.getIndexPath().getPath());
156         } else {
157             indexPath = Paths.get(indexCreationFeature.getIndexPath());
158         }
159         Path absoluteIndexPath;
160         if (indexPath.isAbsolute()) {
161             absoluteIndexPath = indexPath;
162         } else {
163             absoluteIndexPath = PathUtil.getPathFromUri(repo.getLocation()).resolve(indexCreationFeature.getIndexPath().getPath());
164         }
165         try {
166             Files.createDirectories(absoluteIndexPath);
167         } catch (IOException e) {
168             log.error("Could not create index directory {}", absoluteIndexPath);
169             throw new RepositoryException("Could not create index directory " + absoluteIndexPath);
170         }
171
172         ArtifactCleanupFeature artifactCleanupFeature = repo.getFeature(ArtifactCleanupFeature.class).get();
173
174         artifactCleanupFeature.setDeleteReleasedSnapshots(cfg.isDeleteReleasedSnapshots());
175         artifactCleanupFeature.setRetentionCount(cfg.getRetentionCount());
176         artifactCleanupFeature.setRetentionPeriod(Period.ofDays(cfg.getRetentionPeriod()));
177     }
178
179
180     @Override
181     public ManagedRepository createStagingInstance(ManagedRepositoryConfiguration baseConfiguration) throws RepositoryException {
182         log.debug("Creating staging instance for {}", baseConfiguration.getId());
183         return createManagedInstance(getStageRepoConfig(baseConfiguration));
184     }
185
186
187     @Override
188     public RemoteRepository createRemoteInstance(RemoteRepositoryConfiguration cfg) throws RepositoryException {
189         MavenRemoteRepository repo = new MavenRemoteRepository(cfg.getId(), cfg.getName(), archivaConfiguration.getRemoteRepositoryBaseDir());
190         updateRemoteInstance(repo, cfg);
191         return repo;
192     }
193
194     private String convertUriToPath(URI uri) {
195         if (uri.getScheme() == null) {
196             return uri.getPath();
197         } else if ("file".equals(uri.getScheme())) {
198             return Paths.get(uri).toString();
199         } else {
200             return uri.toString();
201         }
202     }
203
204     @Override
205     public void updateRemoteInstance(EditableRemoteRepository repo, RemoteRepositoryConfiguration cfg) throws RepositoryException {
206         setBaseConfig(repo, cfg);
207         repo.setCheckPath(cfg.getCheckPath());
208         repo.setSchedulingDefinition(cfg.getRefreshCronExpression());
209         try {
210             repo.setLocation(new URI(cfg.getUrl()));
211         } catch (UnsupportedURIException | URISyntaxException e) {
212             log.error("Could not set remote url " + cfg.getUrl());
213             throw new RepositoryException("The url config is not a valid uri: " + cfg.getUrl());
214         }
215         repo.setTimeout(Duration.ofSeconds(cfg.getTimeout()));
216         RemoteIndexFeature remoteIndexFeature = repo.getFeature(RemoteIndexFeature.class).get();
217         remoteIndexFeature.setDownloadRemoteIndex(cfg.isDownloadRemoteIndex());
218         remoteIndexFeature.setDownloadRemoteIndexOnStartup(cfg.isDownloadRemoteIndexOnStartup());
219         remoteIndexFeature.setDownloadTimeout(Duration.ofSeconds(cfg.getRemoteDownloadTimeout()));
220         remoteIndexFeature.setProxyId(cfg.getRemoteDownloadNetworkProxyId());
221         if (cfg.isDownloadRemoteIndex()) {
222             try {
223                 remoteIndexFeature.setIndexUri(new URI(cfg.getRemoteIndexUrl()));
224             } catch (URISyntaxException e) {
225                 log.error("Could not set remote index url " + cfg.getRemoteIndexUrl());
226                 remoteIndexFeature.setDownloadRemoteIndex(false);
227                 remoteIndexFeature.setDownloadRemoteIndexOnStartup(false);
228             }
229         }
230         repo.setExtraHeaders(cfg.getExtraHeaders());
231         repo.setExtraParameters(cfg.getExtraParameters());
232         PasswordCredentials credentials = new PasswordCredentials("", new char[0]);
233         if (cfg.getPassword() != null && cfg.getUsername() != null) {
234             credentials.setPassword(cfg.getPassword().toCharArray());
235             credentials.setUsername(cfg.getUsername());
236             repo.setCredentials(credentials);
237         } else {
238             credentials.setPassword(new char[0]);
239         }
240         if (cfg.getIndexDir() != null) {
241             IndexCreationFeature indexCreationFeature = repo.getFeature(IndexCreationFeature.class).get();
242             indexCreationFeature.setIndexPath(getURIFromString(cfg.getIndexDir()));
243         }
244     }
245
246     @Override
247     public RemoteRepositoryConfiguration getRemoteConfiguration(RemoteRepository remoteRepository) throws RepositoryException {
248         if (!(remoteRepository instanceof MavenRemoteRepository)) {
249             log.error("Wrong remote repository type " + remoteRepository.getClass().getName());
250             throw new RepositoryException("The given repository type cannot be handled by the maven provider: " + remoteRepository.getClass().getName());
251         }
252         RemoteRepositoryConfiguration cfg = new RemoteRepositoryConfiguration();
253         cfg.setType(remoteRepository.getType().toString());
254         cfg.setId(remoteRepository.getId());
255         cfg.setName(remoteRepository.getName());
256         cfg.setDescription(remoteRepository.getDescription());
257         cfg.setUrl(remoteRepository.getLocation().toString());
258         cfg.setTimeout((int) remoteRepository.getTimeout().toMillis() / 1000);
259         cfg.setCheckPath(remoteRepository.getCheckPath());
260         RepositoryCredentials creds = remoteRepository.getLoginCredentials();
261         if (creds != null) {
262             if (creds instanceof PasswordCredentials) {
263                 PasswordCredentials pCreds = (PasswordCredentials) creds;
264                 cfg.setPassword(new String(pCreds.getPassword()));
265                 cfg.setUsername(pCreds.getUsername());
266             }
267         }
268         cfg.setLayout(remoteRepository.getLayout());
269         cfg.setExtraParameters(remoteRepository.getExtraParameters());
270         cfg.setExtraHeaders(remoteRepository.getExtraHeaders());
271         cfg.setRefreshCronExpression(remoteRepository.getSchedulingDefinition());
272
273         IndexCreationFeature indexCreationFeature = remoteRepository.getFeature(IndexCreationFeature.class).get();
274         cfg.setIndexDir(convertUriToPath(indexCreationFeature.getIndexPath()));
275
276         RemoteIndexFeature remoteIndexFeature = remoteRepository.getFeature(RemoteIndexFeature.class).get();
277         cfg.setRemoteIndexUrl(remoteIndexFeature.getIndexUri().toString());
278         cfg.setRemoteDownloadTimeout((int) remoteIndexFeature.getDownloadTimeout().get(ChronoUnit.SECONDS));
279         cfg.setDownloadRemoteIndexOnStartup(remoteIndexFeature.isDownloadRemoteIndexOnStartup());
280         cfg.setDownloadRemoteIndex(remoteIndexFeature.isDownloadRemoteIndex());
281         cfg.setRemoteDownloadNetworkProxyId(remoteIndexFeature.getProxyId());
282
283
284         return cfg;
285
286     }
287
288     @Override
289     public ManagedRepositoryConfiguration getManagedConfiguration(ManagedRepository managedRepository) throws RepositoryException {
290         if (!(managedRepository instanceof MavenManagedRepository || managedRepository instanceof BasicManagedRepository)) {
291             log.error("Wrong remote repository type " + managedRepository.getClass().getName());
292             throw new RepositoryException("The given repository type cannot be handled by the maven provider: " + managedRepository.getClass().getName());
293         }
294         ManagedRepositoryConfiguration cfg = new ManagedRepositoryConfiguration();
295         cfg.setType(managedRepository.getType().toString());
296         cfg.setId(managedRepository.getId());
297         cfg.setName(managedRepository.getName());
298         cfg.setDescription(managedRepository.getDescription());
299         cfg.setLocation(convertUriToPath(managedRepository.getLocation()));
300         cfg.setLayout(managedRepository.getLayout());
301         cfg.setRefreshCronExpression(managedRepository.getSchedulingDefinition());
302         cfg.setScanned(managedRepository.isScanned());
303         cfg.setBlockRedeployments(managedRepository.blocksRedeployments());
304         StagingRepositoryFeature stagingRepositoryFeature = managedRepository.getFeature(StagingRepositoryFeature.class).get();
305         cfg.setStageRepoNeeded(stagingRepositoryFeature.isStageRepoNeeded());
306         IndexCreationFeature indexCreationFeature = managedRepository.getFeature(IndexCreationFeature.class).get();
307         cfg.setIndexDir(convertUriToPath(indexCreationFeature.getIndexPath()));
308         cfg.setSkipPackedIndexCreation(indexCreationFeature.isSkipPackedIndexCreation());
309
310         ArtifactCleanupFeature artifactCleanupFeature = managedRepository.getFeature(ArtifactCleanupFeature.class).get();
311         cfg.setRetentionCount(artifactCleanupFeature.getRetentionCount());
312         cfg.setRetentionPeriod(artifactCleanupFeature.getRetentionPeriod().getDays());
313         cfg.setDeleteReleasedSnapshots(artifactCleanupFeature.isDeleteReleasedSnapshots());
314
315         if (managedRepository.getActiveReleaseSchemes().contains(ReleaseScheme.RELEASE)) {
316             cfg.setReleases(true);
317         } else {
318             cfg.setReleases(false);
319         }
320         if (managedRepository.getActiveReleaseSchemes().contains(ReleaseScheme.SNAPSHOT)) {
321             cfg.setSnapshots(true);
322         } else {
323             cfg.setSnapshots(false);
324         }
325         return cfg;
326
327     }
328
329     private ManagedRepositoryConfiguration getStageRepoConfig(ManagedRepositoryConfiguration repository) {
330         ManagedRepositoryConfiguration stagingRepository = new ManagedRepositoryConfiguration();
331         stagingRepository.setId(repository.getId() + StagingRepositoryFeature.STAGING_REPO_POSTFIX);
332         stagingRepository.setLayout(repository.getLayout());
333         stagingRepository.setName(repository.getName() + StagingRepositoryFeature.STAGING_REPO_POSTFIX);
334         stagingRepository.setBlockRedeployments(repository.isBlockRedeployments());
335         stagingRepository.setRetentionPeriod(repository.getRetentionPeriod());
336         stagingRepository.setDeleteReleasedSnapshots(repository.isDeleteReleasedSnapshots());
337         stagingRepository.setStageRepoNeeded(false);
338
339         String path = repository.getLocation();
340         int lastIndex = path.replace('\\', '/').lastIndexOf('/');
341         stagingRepository.setLocation(path.substring(0, lastIndex) + "/" + stagingRepository.getId());
342
343         if (StringUtils.isNotBlank(repository.getIndexDir())) {
344             Path indexDir = null;
345             try {
346                 indexDir = Paths.get(new URI(repository.getIndexDir().startsWith("file://") ? repository.getIndexDir() : "file://" + repository.getIndexDir()));
347                 if (indexDir.isAbsolute()) {
348                     Path newDir = Paths.get(new URI(stagingRepository.getLocation().startsWith("file://") ? stagingRepository.getLocation() : "file://" + stagingRepository.getLocation())).resolve(".index");
349                     log.debug("Changing index directory {} -> {}", indexDir, newDir);
350                     stagingRepository.setIndexDir(newDir.toString());
351                 } else {
352                     log.debug("Keeping index directory {}", repository.getIndexDir());
353                     stagingRepository.setIndexDir(repository.getIndexDir());
354                 }
355             } catch (URISyntaxException e) {
356                 log.error("Could not parse index path as uri {}", repository.getIndexDir());
357                 stagingRepository.setIndexDir("");
358             }
359             // in case of absolute dir do not use the same
360         }
361         stagingRepository.setRefreshCronExpression(repository.getRefreshCronExpression());
362         stagingRepository.setReleases(repository.isReleases());
363         stagingRepository.setRetentionCount(repository.getRetentionCount());
364         stagingRepository.setScanned(repository.isScanned());
365         stagingRepository.setSnapshots(repository.isSnapshots());
366         stagingRepository.setSkipPackedIndexCreation(repository.isSkipPackedIndexCreation());
367         // do not duplicate description
368         //stagingRepository.getDescription("")
369         return stagingRepository;
370     }
371
372     private void setBaseConfig(EditableRepository repo, AbstractRepositoryConfiguration cfg) throws RepositoryException {
373
374         URI baseUri = archivaConfiguration.getRepositoryBaseDir().toUri();
375         repo.setBaseUri(baseUri);
376
377         repo.setName(repo.getPrimaryLocale(), cfg.getName());
378         repo.setDescription(repo.getPrimaryLocale(), cfg.getDescription());
379         repo.setLayout(cfg.getLayout());
380     }
381
382     public ArchivaConfiguration getArchivaConfiguration() {
383         return archivaConfiguration;
384     }
385
386     public void setArchivaConfiguration(ArchivaConfiguration archivaConfiguration) {
387         this.archivaConfiguration = archivaConfiguration;
388     }
389
390     @Override
391     public <T> void raise(RepositoryEvent<T> event) {
392         //
393     }
394 }