This project has retired. For details please refer to its
Attic page.
MavenRepositoryProxyHandler xref
1 package org.apache.archiva.proxy.maven;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.model.RepositoryURL;
23 import org.apache.archiva.proxy.DefaultRepositoryProxyHandler;
24 import org.apache.archiva.proxy.NotFoundException;
25 import org.apache.archiva.proxy.NotModifiedException;
26 import org.apache.archiva.proxy.ProxyException;
27 import org.apache.archiva.proxy.model.NetworkProxy;
28 import org.apache.archiva.proxy.model.ProxyConnector;
29 import org.apache.archiva.proxy.model.RepositoryProxyHandler;
30 import org.apache.archiva.repository.*;
31 import org.apache.archiva.repository.base.PasswordCredentials;
32 import org.apache.archiva.repository.storage.StorageAsset;
33 import org.apache.commons.lang3.StringUtils;
34 import org.apache.maven.wagon.ConnectionException;
35 import org.apache.maven.wagon.ResourceDoesNotExistException;
36 import org.apache.maven.wagon.Wagon;
37 import org.apache.maven.wagon.WagonException;
38 import org.apache.maven.wagon.authentication.AuthenticationException;
39 import org.apache.maven.wagon.authentication.AuthenticationInfo;
40 import org.apache.maven.wagon.proxy.ProxyInfo;
41 import org.apache.maven.wagon.repository.Repository;
42 import org.springframework.stereotype.Service;
43
44 import javax.inject.Inject;
45 import java.io.IOException;
46 import java.nio.file.Files;
47 import java.nio.file.Path;
48 import java.util.ArrayList;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.concurrent.ConcurrentHashMap;
52 import java.util.concurrent.ConcurrentMap;
53
54
55
56
57
58
59 @Service( "repositoryProxyHandler#maven" )
60 public class MavenRepositoryProxyHandler extends DefaultRepositoryProxyHandler {
61
62 private static final List<RepositoryType> REPOSITORY_TYPES = new ArrayList<>();
63
64 static {
65 REPOSITORY_TYPES.add(RepositoryType.MAVEN);
66 }
67
68 @Inject
69 private WagonFactory wagonFactory;
70
71 private ConcurrentMap<String, ProxyInfo> networkProxyMap = new ConcurrentHashMap<>();
72
73 @Override
74 public void initialize() {
75 super.initialize();
76 }
77
78 private void updateWagonProxyInfo(Map<String, NetworkProxy> proxyList) {
79 this.networkProxyMap.clear();
80 for (Map.Entry<String, NetworkProxy> proxyEntry : proxyList.entrySet()) {
81 String key = proxyEntry.getKey();
82 NetworkProxy networkProxyDef = proxyEntry.getValue();
83
84 ProxyInfo proxy = new ProxyInfo();
85
86 proxy.setType(networkProxyDef.getProtocol());
87 proxy.setHost(networkProxyDef.getHost());
88 proxy.setPort(networkProxyDef.getPort());
89 proxy.setUserName(networkProxyDef.getUsername());
90 proxy.setPassword(new String(networkProxyDef.getPassword()));
91
92 this.networkProxyMap.put(key, proxy);
93 }
94 }
95
96 @Override
97 public void setNetworkProxies(Map<String, NetworkProxy> networkProxies ) {
98 super.setNetworkProxies( networkProxies );
99 updateWagonProxyInfo( networkProxies );
100 }
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 protected void transferResources( ProxyConnector connector, RemoteRepository remoteRepository,
116 StorageAsset tmpResource, StorageAsset[] checksumFiles, String url, String remotePath, StorageAsset resource,
117 Path workingDirectory, ManagedRepository repository )
118 throws ProxyException, NotModifiedException {
119 Wagon wagon = null;
120 try {
121 RepositoryURL repoUrl = remoteRepository.getContent().getURL();
122 String protocol = repoUrl.getProtocol();
123 NetworkProxy networkProxy = null;
124 String proxyId = connector.getProxyId();
125 if (StringUtils.isNotBlank(proxyId)) {
126
127 networkProxy = getNetworkProxy(proxyId);
128 }
129 WagonFactoryRequest wagonFactoryRequest = new WagonFactoryRequest("wagon#" + protocol,
130 remoteRepository.getExtraHeaders());
131 if (networkProxy == null) {
132
133 log.warn("No network proxy with id {} found for connector {}->{}", proxyId,
134 connector.getSourceRepository().getId(), connector.getTargetRepository().getId());
135 } else {
136 wagonFactoryRequest = wagonFactoryRequest.networkProxy(networkProxy);
137 }
138 wagon = wagonFactory.getWagon(wagonFactoryRequest);
139 if (wagon == null) {
140 throw new ProxyException("Unsupported target repository protocol: " + protocol);
141 }
142
143 if (wagon == null) {
144 throw new ProxyException("Unsupported target repository protocol: " + protocol);
145 }
146
147 boolean connected = connectToRepository(connector, wagon, remoteRepository);
148 if (connected) {
149 transferArtifact(wagon, remoteRepository, remotePath, repository, resource.getFilePath(), workingDirectory,
150 tmpResource);
151
152
153
154
155 for (int i=0; i<checksumFiles.length; i++) {
156 String ext = "."+StringUtils.substringAfterLast(checksumFiles[i].getName( ), "." );
157 transferChecksum(wagon, remoteRepository, remotePath, repository, resource.getFilePath(), ext,
158 checksumFiles[i].getFilePath());
159 }
160 }
161 } catch (NotFoundException e) {
162 urlFailureCache.cacheFailure(url);
163 throw e;
164 } catch (NotModifiedException e) {
165
166 throw e;
167 } catch (ProxyException e) {
168 urlFailureCache.cacheFailure(url);
169 throw e;
170 } catch (WagonFactoryException e) {
171 throw new ProxyException(e.getMessage(), e);
172 } finally {
173 if (wagon != null) {
174 try {
175 wagon.disconnect();
176 } catch (ConnectionException e) {
177 log.warn("Unable to disconnect wagon.", e);
178 }
179 }
180 }
181 }
182
183 protected void transferArtifact(Wagon wagon, RemoteRepository remoteRepository, String remotePath,
184 ManagedRepository repository, Path resource, Path tmpDirectory,
185 StorageAsset destFile)
186 throws ProxyException {
187 transferSimpleFile(wagon, remoteRepository, remotePath, repository, resource, destFile.getFilePath());
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203 protected void transferChecksum( Wagon wagon, RemoteRepository remoteRepository, String remotePath,
204 ManagedRepository repository, Path resource, String ext,
205 Path destFile )
206 throws ProxyException {
207 String url = remoteRepository.getLocation().toString() + remotePath + ext;
208
209
210 if (urlFailureCache.hasFailedBefore(url)) {
211 return;
212 }
213
214 try {
215 transferSimpleFile(wagon, remoteRepository, remotePath + ext, repository, resource, destFile);
216 log.debug("Checksum {} Downloaded: {} to move to {}", url, destFile, resource);
217 } catch (NotFoundException e) {
218 urlFailureCache.cacheFailure(url);
219 log.debug("Transfer failed, checksum not found: {}", url);
220
221 } catch (NotModifiedException e) {
222 log.debug("Transfer skipped, checksum not modified: {}", url);
223
224 } catch (ProxyException e) {
225 urlFailureCache.cacheFailure(url);
226 log.warn("Transfer failed on checksum: {} : {}", url, e.getMessage(), e);
227
228 throw e;
229 }
230 }
231
232
233
234
235
236
237
238
239
240
241
242 protected void transferSimpleFile(Wagon wagon, RemoteRepository remoteRepository, String remotePath,
243 ManagedRepository repository, Path origFile, Path destFile)
244 throws ProxyException {
245 assert (remotePath != null);
246
247
248 try {
249 boolean success = false;
250
251 if (!Files.exists(origFile)) {
252 log.debug("Retrieving {} from {}", remotePath, remoteRepository.getId());
253 wagon.get(addParameters(remotePath, remoteRepository), destFile.toFile());
254 success = true;
255
256
257 log.debug("Downloaded successfully.");
258 } else {
259 log.debug("Retrieving {} from {} if updated", remotePath, remoteRepository.getId());
260 try {
261 success = wagon.getIfNewer(addParameters(remotePath, remoteRepository), destFile.toFile(),
262 Files.getLastModifiedTime(origFile).toMillis());
263 } catch (IOException e) {
264 throw new ProxyException("Failed to the modification time of " + origFile.toAbsolutePath());
265 }
266 if (!success) {
267 throw new NotModifiedException(
268 "Not downloaded, as local file is newer than remote side: " + origFile.toAbsolutePath());
269 }
270
271 if (Files.exists(destFile)) {
272 log.debug("Downloaded successfully.");
273 }
274 }
275 } catch (ResourceDoesNotExistException e) {
276 throw new NotFoundException(
277 "Resource [" + remoteRepository.getLocation() + "/" + remotePath + "] does not exist: " + e.getMessage(),
278 e);
279 } catch (WagonException e) {
280
281
282 String msg =
283 "Download failure on resource [" + remoteRepository.getLocation() + "/" + remotePath + "]:" + e.getMessage();
284 if (e.getCause() != null) {
285 msg += " (cause: " + e.getCause() + ")";
286 }
287 throw new ProxyException(msg, e);
288 }
289 }
290
291
292
293
294
295
296
297
298
299 protected boolean connectToRepository(ProxyConnector connector, Wagon wagon,
300 RemoteRepository remoteRepository) {
301 boolean connected = false;
302
303 final ProxyInfo networkProxy =
304 connector.getProxyId() == null ? null : this.networkProxyMap.get(connector.getProxyId());
305
306 if (log.isDebugEnabled()) {
307 if (networkProxy != null) {
308
309 String msg = "Using network proxy " + networkProxy.getHost() + ":" + networkProxy.getPort()
310 + " to connect to remote repository " + remoteRepository.getLocation();
311 if (networkProxy.getNonProxyHosts() != null) {
312 msg += "; excluding hosts: " + networkProxy.getNonProxyHosts();
313 }
314 if (StringUtils.isNotBlank(networkProxy.getUserName())) {
315 msg += "; as user: " + networkProxy.getUserName();
316 }
317 log.debug(msg);
318 }
319 }
320
321 AuthenticationInfo authInfo = null;
322 String username = "";
323 String password = "";
324 RepositoryCredentials repCred = remoteRepository.getLoginCredentials();
325 if (repCred != null && repCred instanceof PasswordCredentials ) {
326 PasswordCredentials pwdCred = (PasswordCredentials) repCred;
327 username = pwdCred.getUsername();
328 password = pwdCred.getPassword() == null ? "" : new String(pwdCred.getPassword());
329 }
330
331 if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
332 log.debug("Using username {} to connect to remote repository {}", username, remoteRepository.getLocation());
333 authInfo = new AuthenticationInfo();
334 authInfo.setUserName(username);
335 authInfo.setPassword(password);
336 }
337
338
339
340 long timeoutInMilliseconds = remoteRepository.getTimeout().toMillis();
341
342
343
344 wagon.setReadTimeout((int) timeoutInMilliseconds);
345 wagon.setTimeout((int) timeoutInMilliseconds);
346
347 try {
348 Repository wagonRepository =
349 new Repository(remoteRepository.getId(), remoteRepository.getLocation().toString());
350 wagon.connect(wagonRepository, authInfo, networkProxy);
351 connected = true;
352 } catch (ConnectionException | AuthenticationException e) {
353 log.warn("Could not connect to {}: {}", remoteRepository.getId(), e.getMessage());
354 connected = false;
355 }
356
357 return connected;
358 }
359
360
361 public WagonFactory getWagonFactory() {
362 return wagonFactory;
363 }
364
365 public void setWagonFactory(WagonFactory wagonFactory) {
366 this.wagonFactory = wagonFactory;
367 }
368
369 @Override
370 public List<RepositoryType> supports() {
371 return REPOSITORY_TYPES;
372 }
373
374 @Override
375 public void addNetworkproxy( String id, NetworkProxy networkProxy )
376 {
377
378 }
379
380 @Override
381 public <T extends RepositoryProxyHandler> T getHandler( Class<T> clazz ) throws IllegalArgumentException
382 {
383 if (clazz.isAssignableFrom( this.getClass() )) {
384 return (T)this;
385 } else {
386 throw new IllegalArgumentException( "This Proxy Handler is no subclass of " + clazz );
387 }
388 }
389 }