Merged from: r644205, 644275 git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@644276 13f79535-47bb-0310-9956-ffa450edef68tags/archiva-r676265
@@ -29,14 +29,18 @@ Understanding Proxy Connector Configuration of Apache Archiva | |||
By default, Archiva comes with the following policies: | |||
* <<<releases>>> - how to behave for released artifact metadata (those not carrying a <<<SNAPSHOT>>> version). This can be set to <<<always>>> (default), <<<hourly>>>, <<<daily>>>, <<<once>>> and <<<never>>>. | |||
* <<<Releases>>> - how to behave for released artifact metadata (those not carrying a <<<SNAPSHOT>>> version). This can be set to <<<always>>> (default), <<<hourly>>>, <<<daily>>>, <<<once>>> and <<<never>>>. | |||
* <<<snapshots>>> - how to behave for snapshot artifact metadata (those carrying a <<<SNAPSHOT>>> version). This can be set to <<<always>>> (default), <<<hourly>>>, <<<daily>>>, <<<once>>> and <<<never>>>. | |||
* <<<Snapshots>>> - how to behave for snapshot artifact metadata (those carrying a <<<SNAPSHOT>>> version). This can be set to <<<always>>> (default), <<<hourly>>>, <<<daily>>>, <<<once>>> and <<<never>>>. | |||
* <<<checksum>>> - how to handle incorrect checksums when downloading an artifact from the remote repository (ie, the checksum of the artifact does not match the corresponding detached checksum file). | |||
* <<<Checksum>>> - how to handle incorrect checksums when downloading an artifact from the remote repository (ie, the checksum of the artifact does not match the corresponding detached checksum file). | |||
The options are to fail the request for the remote artifact, fix the checksum on the fly (default), or simply ignore the incorrect checksum | |||
* <<<cache-failures>>> - whether failures retrieving the remote artifact should be cached (to save network bandwidth for missing or bad artifacts), or uncached (default). | |||
* <<<Cache failures>>> - whether failures retrieving the remote artifact should be cached (to save network bandwidth for missing or bad artifacts), or uncached (default). | |||
* <<<Return error when>>> - if a remote proxy causes an error, this option determines whether an existing artifact should be returned (error when <<<artifact not already present>>>), or the error passed on regardless (<<<always>>>). | |||
* <<<On remote error>>> - if a remote error is encountered, <<<stop>>> causes the error to be returned immediately, <<<queue error>>> will return all errors after checking for other successful remote repositories first, and <<<ignore>>> will disregard ay errors. | |||
[] | |||
@@ -29,7 +29,7 @@ import org.apache.maven.archiva.configuration.io.registry.ConfigurationRegistryW | |||
import org.apache.maven.archiva.policies.AbstractUpdatePolicy; | |||
import org.apache.maven.archiva.policies.CachedFailuresPolicy; | |||
import org.apache.maven.archiva.policies.ChecksumPolicy; | |||
import org.apache.maven.archiva.policies.DownloadPolicy; | |||
import org.apache.maven.archiva.policies.Policy; | |||
import org.apache.maven.archiva.policies.PostDownloadPolicy; | |||
import org.apache.maven.archiva.policies.PreDownloadPolicy; | |||
import org.codehaus.plexus.evaluator.DefaultExpressionEvaluator; | |||
@@ -280,7 +280,7 @@ public class DefaultArchivaConfiguration | |||
// Validate existance of policy key. | |||
if ( policyExists( policyId ) ) | |||
{ | |||
DownloadPolicy policy = findPolicy( policyId ); | |||
Policy policy = findPolicy( policyId ); | |||
// Does option exist? | |||
if ( !policy.getOptions().contains( setting ) ) | |||
{ | |||
@@ -323,7 +323,7 @@ public class DefaultArchivaConfiguration | |||
return config; | |||
} | |||
private DownloadPolicy findPolicy( String policyId ) | |||
private Policy findPolicy( String policyId ) | |||
{ | |||
if ( MapUtils.isEmpty( prePolicies ) ) | |||
{ | |||
@@ -337,7 +337,7 @@ public class DefaultArchivaConfiguration | |||
return null; | |||
} | |||
DownloadPolicy policy; | |||
Policy policy; | |||
policy = prePolicies.get( policyId ); | |||
if ( policy != null ) |
@@ -651,6 +651,20 @@ | |||
*/ | |||
public static final int UNORDERED = 0; | |||
/** | |||
* The policy key {@link #getPolicies()} for error handling. | |||
* See {@link org.apache.maven.archiva.policies.DownloadErrorPolicy} | |||
* for details on potential values to this policy key. | |||
*/ | |||
public static final String POLICY_PROPAGATE_ERRORS = "propagate-errors"; | |||
/** | |||
* The policy key {@link #getPolicies()} for error handling when an artifact is present. | |||
* See {@link org.apache.maven.archiva.policies.DownloadErrorPolicy} | |||
* for details on potential values to this policy key. | |||
*/ | |||
public static final String POLICY_PROPAGATE_ERRORS_ON_UPDATE = "propagate-errors-on-update"; | |||
/** | |||
* The policy key {@link #getPolicies()} for snapshot handling. | |||
* See {@link org.apache.maven.archiva.policies.SnapshotsPolicy} |
@@ -108,6 +108,11 @@ public class CachedFailuresPolicy | |||
return "cache-failures"; | |||
} | |||
public String getName() | |||
{ | |||
return "Cache failures"; | |||
} | |||
public List<String> getOptions() | |||
{ | |||
return options; |
@@ -157,6 +157,11 @@ public class ChecksumPolicy | |||
return "checksum"; | |||
} | |||
public String getName() | |||
{ | |||
return "Checksum"; | |||
} | |||
public List<String> getOptions() | |||
{ | |||
return options; |
@@ -0,0 +1,50 @@ | |||
package org.apache.maven.archiva.policies; | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one | |||
* or more contributor license agreements. See the NOTICE file | |||
* distributed with this work for additional information | |||
* regarding copyright ownership. The ASF licenses this file | |||
* to you under the Apache License, Version 2.0 (the | |||
* "License"); you may not use this file except in compliance | |||
* with the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, | |||
* software distributed under the License is distributed on an | |||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
* KIND, either express or implied. See the License for the | |||
* specific language governing permissions and limitations | |||
* under the License. | |||
*/ | |||
import java.io.File; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
/** | |||
* Policy to apply after the download has completed, but before the | |||
* resource is made available to the calling client. | |||
* | |||
* @author <a href="mailto:brett@apache.org">Brett Porter</a> | |||
* @version $Id$ | |||
*/ | |||
public interface DownloadErrorPolicy | |||
extends Policy | |||
{ | |||
/** | |||
* Apply the download error policy. | |||
* | |||
* @param policySetting the policy setting. | |||
* @param request the list of request properties that the policy might use. | |||
* @param localFile | |||
* @param exception the exception that triggered the error | |||
* @param previousExceptions any previously triggered exceptions | |||
* @return whether to process the exception or not | |||
* @throws PolicyConfigurationException if the policy is improperly configured | |||
*/ | |||
public boolean applyPolicy( String policySetting, Properties request, File localFile, Exception exception, | |||
Map<String, Exception> previousExceptions ) | |||
throws PolicyConfigurationException; | |||
} |
@@ -20,7 +20,6 @@ package org.apache.maven.archiva.policies; | |||
*/ | |||
import java.io.File; | |||
import java.util.List; | |||
import java.util.Properties; | |||
/** | |||
@@ -30,27 +29,8 @@ import java.util.Properties; | |||
* @version $Id$ | |||
*/ | |||
public interface DownloadPolicy | |||
extends Policy | |||
{ | |||
/** | |||
* Get the list of options for this policy. | |||
* | |||
* @return the list of options for this policy. | |||
*/ | |||
public List<String> getOptions(); | |||
/** | |||
* Get the default option for this policy. | |||
* | |||
* @return the default policy for this policy. | |||
*/ | |||
public String getDefaultOption(); | |||
/** | |||
* Get the id for this policy. | |||
* | |||
* @return the id for this policy. | |||
*/ | |||
public String getId(); | |||
/** | |||
* Apply the download policy. |
@@ -0,0 +1,55 @@ | |||
package org.apache.maven.archiva.policies; | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one | |||
* or more contributor license agreements. See the NOTICE file | |||
* distributed with this work for additional information | |||
* regarding copyright ownership. The ASF licenses this file | |||
* to you under the Apache License, Version 2.0 (the | |||
* "License"); you may not use this file except in compliance | |||
* with the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, | |||
* software distributed under the License is distributed on an | |||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
* KIND, either express or implied. See the License for the | |||
* specific language governing permissions and limitations | |||
* under the License. | |||
*/ | |||
import java.util.List; | |||
public interface Policy | |||
{ | |||
/** | |||
* Get the list of options for this policy. | |||
* | |||
* @return the list of options for this policy. | |||
*/ | |||
List<String> getOptions(); | |||
/** | |||
* Get the default option for this policy. | |||
* | |||
* @return the default policy for this policy. | |||
*/ | |||
String getDefaultOption(); | |||
/** | |||
* Get the id for this policy. | |||
* | |||
* @return the id for this policy. | |||
*/ | |||
String getId(); | |||
/** | |||
* Get the display name for this policy. | |||
* | |||
* @todo i18n | |||
* | |||
* @return the name for this policy | |||
*/ | |||
String getName(); | |||
} |
@@ -19,9 +19,6 @@ package org.apache.maven.archiva.policies; | |||
* under the License. | |||
*/ | |||
import java.io.File; | |||
import java.util.Properties; | |||
/** | |||
* Policy to apply after the download has completed, but before the | |||
* resource is made available to the calling client. | |||
@@ -32,18 +29,4 @@ import java.util.Properties; | |||
public interface PostDownloadPolicy | |||
extends DownloadPolicy | |||
{ | |||
/** | |||
* Apply the download policy. | |||
* | |||
* A true result allows the download to succeed. false indicates that the | |||
* download is a failure. | |||
* | |||
* @param policySetting the policy setting. | |||
* @param request the list of request properties that the policy might use. | |||
* @param localFile the local file that this policy affects | |||
* | |||
* @throws PolicyViolationException if the policy has been violated. | |||
*/ | |||
public void applyPolicy( String policySetting, Properties request, File localFile ) | |||
throws PolicyViolationException, PolicyConfigurationException; | |||
} |
@@ -20,9 +20,6 @@ package org.apache.maven.archiva.policies; | |||
*/ | |||
import java.io.File; | |||
import java.util.Properties; | |||
/** | |||
* Policy to apply before the download is attempted. | |||
* | |||
@@ -31,18 +28,4 @@ import java.util.Properties; | |||
*/ | |||
public interface PreDownloadPolicy extends DownloadPolicy | |||
{ | |||
/** | |||
* Apply the download policy. | |||
* | |||
* A true result lets the download occur. A false result prevents the download | |||
* from occuring. | |||
* | |||
* @param policySetting the policy setting. | |||
* @param request the list of request properties that the policy might use. | |||
* @param localFile the local file that this policy affects | |||
* | |||
* @throws PolicyViolationException if the policy has been violated. | |||
*/ | |||
public void applyPolicy( String policySetting, Properties request, File localFile ) | |||
throws PolicyViolationException, PolicyConfigurationException; | |||
} |
@@ -0,0 +1,118 @@ | |||
package org.apache.maven.archiva.policies; | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one | |||
* or more contributor license agreements. See the NOTICE file | |||
* distributed with this work for additional information | |||
* regarding copyright ownership. The ASF licenses this file | |||
* to you under the Apache License, Version 2.0 (the | |||
* "License"); you may not use this file except in compliance | |||
* with the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, | |||
* software distributed under the License is distributed on an | |||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
* KIND, either express or implied. See the License for the | |||
* specific language governing permissions and limitations | |||
* under the License. | |||
*/ | |||
import org.apache.commons.lang.StringUtils; | |||
import org.codehaus.plexus.logging.AbstractLogEnabled; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
/** | |||
* PropagateErrorsPolicy - a policy applied on error to determine how to treat the error. | |||
* | |||
* @plexus.component role="org.apache.maven.archiva.policies.DownloadErrorPolicy" | |||
* role-hint="propagate-errors" | |||
*/ | |||
public class PropagateErrorsDownloadPolicy | |||
extends AbstractLogEnabled | |||
implements DownloadErrorPolicy | |||
{ | |||
/** | |||
* Signifies any error should stop searching for other proxies. | |||
*/ | |||
public static final String STOP = "stop"; | |||
/** | |||
* Propagate errors at the end after all are gathered, if there was no successful download from other proxies. | |||
*/ | |||
public static final String QUEUE = "queue error"; | |||
/** | |||
* Ignore errors and treat as if it were not found. | |||
*/ | |||
public static final String IGNORE = "ignore"; | |||
private List<String> options = new ArrayList<String>(); | |||
public PropagateErrorsDownloadPolicy() | |||
{ | |||
options.add( STOP ); | |||
options.add( QUEUE ); | |||
options.add( IGNORE ); | |||
} | |||
public boolean applyPolicy( String policySetting, Properties request, File localFile, Exception exception, | |||
Map<String, Exception> previousExceptions ) | |||
throws PolicyConfigurationException | |||
{ | |||
if ( !options.contains( policySetting ) ) | |||
{ | |||
// Not a valid code. | |||
throw new PolicyConfigurationException( "Unknown error policy setting [" + policySetting + | |||
"], valid settings are [" + StringUtils.join( options.iterator(), "," ) + "]" ); | |||
} | |||
if ( IGNORE.equals( policySetting ) ) | |||
{ | |||
// Ignore. | |||
getLogger().debug( "Error policy set to IGNORE." ); | |||
return false; | |||
} | |||
String repositoryId = request.getProperty( "remoteRepositoryId" ); | |||
if ( STOP.equals( policySetting ) ) | |||
{ | |||
return true; | |||
} | |||
if ( QUEUE.equals( policySetting ) ) | |||
{ | |||
previousExceptions.put( repositoryId, exception ); | |||
return true; | |||
} | |||
throw new PolicyConfigurationException( | |||
"Unable to process checksum policy of [" + policySetting + "], please file a bug report." ); | |||
} | |||
public String getDefaultOption() | |||
{ | |||
return QUEUE; | |||
} | |||
public String getId() | |||
{ | |||
return "propagate-errors"; | |||
} | |||
public String getName() | |||
{ | |||
return "On remote error"; | |||
} | |||
public List<String> getOptions() | |||
{ | |||
return options; | |||
} | |||
} |
@@ -0,0 +1,105 @@ | |||
package org.apache.maven.archiva.policies; | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one | |||
* or more contributor license agreements. See the NOTICE file | |||
* distributed with this work for additional information | |||
* regarding copyright ownership. The ASF licenses this file | |||
* to you under the Apache License, Version 2.0 (the | |||
* "License"); you may not use this file except in compliance | |||
* with the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, | |||
* software distributed under the License is distributed on an | |||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
* KIND, either express or implied. See the License for the | |||
* specific language governing permissions and limitations | |||
* under the License. | |||
*/ | |||
import org.apache.commons.lang.StringUtils; | |||
import org.codehaus.plexus.logging.AbstractLogEnabled; | |||
import java.io.File; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
/** | |||
* PropagateErrorsPolicy - a policy applied on error to determine how to treat the error. | |||
* | |||
* @plexus.component role="org.apache.maven.archiva.policies.DownloadErrorPolicy" | |||
* role-hint="propagate-errors-on-update" | |||
*/ | |||
public class PropagateErrorsOnUpdateDownloadPolicy | |||
extends AbstractLogEnabled | |||
implements DownloadErrorPolicy | |||
{ | |||
/** | |||
* Signifies any error should cause a failure whether the artifact is already present or not. | |||
*/ | |||
public static final String ALWAYS = "always"; | |||
/** | |||
* Signifies any error should cause a failure only if the artifact is not already present. | |||
*/ | |||
public static final String NOT_PRESENT = "artifact not already present"; | |||
private List<String> options = new ArrayList<String>(); | |||
public PropagateErrorsOnUpdateDownloadPolicy() | |||
{ | |||
options.add( ALWAYS ); | |||
options.add( NOT_PRESENT ); | |||
} | |||
public boolean applyPolicy( String policySetting, Properties request, File localFile, Exception exception, | |||
Map<String,Exception> previousExceptions ) | |||
throws PolicyConfigurationException | |||
{ | |||
if ( !options.contains( policySetting ) ) | |||
{ | |||
// Not a valid code. | |||
throw new PolicyConfigurationException( "Unknown error policy setting [" + policySetting | |||
+ "], valid settings are [" + StringUtils.join( options.iterator(), "," ) + "]" ); | |||
} | |||
if ( ALWAYS.equals( policySetting ) ) | |||
{ | |||
// throw ther exception regardless | |||
return true; | |||
} | |||
if ( NOT_PRESENT.equals( policySetting ) ) | |||
{ | |||
// cancel the exception if the file exists | |||
return !localFile.exists(); | |||
} | |||
throw new PolicyConfigurationException( "Unable to process checksum policy of [" + policySetting | |||
+ "], please file a bug report." ); | |||
} | |||
public String getDefaultOption() | |||
{ | |||
return NOT_PRESENT; | |||
} | |||
public String getId() | |||
{ | |||
return "propagate-errors-on-update"; | |||
} | |||
public String getName() | |||
{ | |||
return "Return error when"; | |||
} | |||
public List<String> getOptions() | |||
{ | |||
return options; | |||
} | |||
} |
@@ -0,0 +1,66 @@ | |||
package org.apache.maven.archiva.policies; | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one | |||
* or more contributor license agreements. See the NOTICE file | |||
* distributed with this work for additional information | |||
* regarding copyright ownership. The ASF licenses this file | |||
* to you under the Apache License, Version 2.0 (the | |||
* "License"); you may not use this file except in compliance | |||
* with the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, | |||
* software distributed under the License is distributed on an | |||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
* KIND, either express or implied. See the License for the | |||
* specific language governing permissions and limitations | |||
* under the License. | |||
*/ | |||
import org.apache.maven.archiva.common.ArchivaException; | |||
import java.util.Collections; | |||
import java.util.Map; | |||
/** | |||
* One or more exceptions occurred downloading from a remote repository during the proxy phase. | |||
*/ | |||
public class ProxyDownloadException | |||
extends ArchivaException | |||
{ | |||
/** | |||
* A list of failures keyed by repository ID. | |||
*/ | |||
private final Map<String, Exception> failures; | |||
public ProxyDownloadException( String message, String repositoryId, Exception cause ) | |||
{ | |||
super( constructMessage( message, Collections.singletonMap( repositoryId, cause ) ), cause ); | |||
failures = Collections.singletonMap( repositoryId, cause ); | |||
} | |||
public ProxyDownloadException( String message, Map<String, Exception> failures ) | |||
{ | |||
super( constructMessage( message, failures ) ); | |||
this.failures = failures; | |||
} | |||
private static String constructMessage( String message, Map<String, Exception> failures ) | |||
{ | |||
String msg = message + ":"; | |||
for ( Map.Entry<String, Exception> entry : failures.entrySet() ) | |||
{ | |||
msg += "\n\t" + entry.getKey() + ": " + entry.getValue().getMessage(); | |||
} | |||
return msg; | |||
} | |||
public Map<String,Exception> getFailures() | |||
{ | |||
return failures; | |||
} | |||
} |
@@ -55,4 +55,9 @@ public class ReleasesPolicy | |||
{ | |||
return "releases"; | |||
} | |||
public String getName() | |||
{ | |||
return "Releases"; | |||
} | |||
} |
@@ -55,4 +55,9 @@ public class SnapshotsPolicy | |||
{ | |||
return "snapshots"; | |||
} | |||
public String getName() | |||
{ | |||
return "Snapshots"; | |||
} | |||
} |
@@ -19,16 +19,6 @@ package org.apache.maven.archiva.proxy; | |||
* under the License. | |||
*/ | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Properties; | |||
import java.util.Map.Entry; | |||
import org.apache.commons.collections.CollectionUtils; | |||
import org.apache.commons.io.FileUtils; | |||
import org.apache.commons.lang.StringUtils; | |||
@@ -41,11 +31,13 @@ import org.apache.maven.archiva.model.Keys; | |||
import org.apache.maven.archiva.model.ProjectReference; | |||
import org.apache.maven.archiva.model.RepositoryURL; | |||
import org.apache.maven.archiva.model.VersionedReference; | |||
import org.apache.maven.archiva.policies.DownloadErrorPolicy; | |||
import org.apache.maven.archiva.policies.DownloadPolicy; | |||
import org.apache.maven.archiva.policies.PolicyConfigurationException; | |||
import org.apache.maven.archiva.policies.PolicyViolationException; | |||
import org.apache.maven.archiva.policies.PostDownloadPolicy; | |||
import org.apache.maven.archiva.policies.PreDownloadPolicy; | |||
import org.apache.maven.archiva.policies.ProxyDownloadException; | |||
import org.apache.maven.archiva.policies.urlcache.UrlFailureCache; | |||
import org.apache.maven.archiva.repository.ContentNotFoundException; | |||
import org.apache.maven.archiva.repository.ManagedRepositoryContent; | |||
@@ -73,11 +65,23 @@ import org.codehaus.plexus.util.SelectorUtils; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.LinkedHashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Map.Entry; | |||
import java.util.Properties; | |||
/** | |||
* DefaultRepositoryProxyConnectors | |||
* | |||
* @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a> | |||
* @version $Id$ | |||
* @todo exception handling needs work - "not modified" is not really an exceptional case, and it has more layers than your average brown onion | |||
* @plexus.component role-hint="default" | |||
*/ | |||
public class DefaultRepositoryProxyConnectors | |||
@@ -116,7 +120,12 @@ public class DefaultRepositoryProxyConnectors | |||
private Map<String, PostDownloadPolicy> postDownloadPolicies; | |||
/** | |||
* @plexus.requirement | |||
* @plexus.requirement role="org.apache.maven.archiva.policies.DownloadErrorPolicy" | |||
*/ | |||
private Map<String, DownloadErrorPolicy> downloadErrorPolicies; | |||
/** | |||
* @plexus.requirement role-hint="default" | |||
*/ | |||
private UrlFailureCache urlFailureCache; | |||
@@ -136,26 +145,31 @@ public class DefaultRepositoryProxyConnectors | |||
* @param artifact the artifact reference to fetch. | |||
* @return the local file in the managed repository that was fetched, or null if the artifact was not (or | |||
* could not be) fetched. | |||
* @throws ProxyException if there was a problem fetching the artifact. | |||
* @throws PolicyViolationException if there was a problem fetching the artifact. | |||
*/ | |||
public File fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact ) | |||
throws ProxyDownloadException | |||
{ | |||
File localFile = toLocalFile( repository, artifact ); | |||
Properties requestProperties = new Properties(); | |||
requestProperties.setProperty( "filetype", "artifact" ); | |||
requestProperties.setProperty( "version", artifact.getVersion() ); | |||
requestProperties.setProperty( "managedRepositoryId", repository.getId() ); | |||
List<ProxyConnector> connectors = getProxyConnectors( repository ); | |||
Map<String, Exception> previousExceptions = new LinkedHashMap<String, Exception>(); | |||
for ( ProxyConnector connector : connectors ) | |||
{ | |||
RemoteRepositoryContent targetRepository = connector.getTargetRepository(); | |||
requestProperties.setProperty( "remoteRepositoryId", targetRepository.getId() ); | |||
String targetPath = targetRepository.toPath( artifact ); | |||
try | |||
{ | |||
File downloadedFile = transferFile( connector, targetRepository, targetPath, localFile, | |||
requestProperties ); | |||
File downloadedFile = | |||
transferFile( connector, targetRepository, targetPath, localFile, requestProperties ); | |||
if ( fileExists( downloadedFile ) ) | |||
{ | |||
@@ -175,12 +189,17 @@ public class DefaultRepositoryProxyConnectors | |||
} | |||
catch ( ProxyException e ) | |||
{ | |||
log.warn( "Transfer error from repository \"" + targetRepository.getRepository().getId() + | |||
"\" for artifact " + Keys.toKey( artifact ) + ", continuing to next repository. Error message: " + | |||
e.getMessage() ); | |||
log.debug( "Full stack trace", e ); | |||
validatePolicies( this.downloadErrorPolicies, connector.getPolicies(), requestProperties, artifact, | |||
targetRepository, localFile, e, previousExceptions ); | |||
} | |||
} | |||
if ( !previousExceptions.isEmpty() ) | |||
{ | |||
throw new ProxyDownloadException( "Failures occurred downloading from some remote repositories", | |||
previousExceptions ); | |||
} | |||
log.debug( "Exhausted all target repositories, artifact " + Keys.toKey( artifact ) + " not found." ); | |||
return null; | |||
@@ -471,10 +490,10 @@ public class DefaultRepositoryProxyConnectors | |||
* @param localFile the local file to place the downloaded resource into | |||
* @param requestProperties the request properties to utilize for policy handling. | |||
* @return the local file that was downloaded, or null if not downloaded. | |||
* @throws NotFoundException if the file was not found on the remote repository. | |||
* @throws NotFoundException if the file was not found on the remote repository. | |||
* @throws NotModifiedException if the localFile was present, and the resource was present on remote repository, | |||
* but the remote resource is not newer than the local File. | |||
* @throws ProxyException if transfer was unsuccessful. | |||
* @throws ProxyException if transfer was unsuccessful. | |||
*/ | |||
private File transferFile( ProxyConnector connector, RemoteRepositoryContent remoteRepository, String remotePath, | |||
File localFile, Properties requestProperties ) | |||
@@ -696,8 +715,8 @@ public class DefaultRepositoryProxyConnectors | |||
success = wagon.getIfNewer( remotePath, temp, localFile.lastModified() ); | |||
if ( !success ) | |||
{ | |||
throw new NotModifiedException( "Not downloaded, as local file is newer than remote side: " | |||
+ localFile.getAbsolutePath() ); | |||
throw new NotModifiedException( | |||
"Not downloaded, as local file is newer than remote side: " + localFile.getAbsolutePath() ); | |||
} | |||
if ( temp.exists() ) | |||
@@ -711,13 +730,15 @@ public class DefaultRepositoryProxyConnectors | |||
} | |||
catch ( ResourceDoesNotExistException e ) | |||
{ | |||
throw new NotFoundException( "Resource [" + remoteRepository.getURL() + "/" + remotePath | |||
+ "] does not exist: " + e.getMessage(), e ); | |||
throw new NotFoundException( | |||
"Resource [" + remoteRepository.getURL() + "/" + remotePath + "] does not exist: " + e.getMessage(), | |||
e ); | |||
} | |||
catch ( WagonException e ) | |||
{ | |||
throw new ProxyException( "Download failure on resource [" + remoteRepository.getURL() + "/" + remotePath + "]:" | |||
+ e.getMessage(), e ); | |||
throw new ProxyException( | |||
"Download failure on resource [" + remoteRepository.getURL() + "/" + remotePath + "]:" + e.getMessage(), | |||
e ); | |||
} | |||
finally | |||
{ | |||
@@ -742,10 +763,10 @@ public class DefaultRepositoryProxyConnectors | |||
{ | |||
for ( Entry<String, ? extends DownloadPolicy> entry : policies.entrySet() ) | |||
{ | |||
String key = (String) entry.getKey(); | |||
String key = entry.getKey(); | |||
DownloadPolicy policy = entry.getValue(); | |||
String defaultSetting = policy.getDefaultOption(); | |||
String setting = StringUtils.defaultString( (String) settings.get( key ), defaultSetting ); | |||
String setting = StringUtils.defaultString( settings.get( key ), defaultSetting ); | |||
log.debug( "Applying [" + key + "] policy with [" + setting + "]" ); | |||
try | |||
@@ -759,6 +780,56 @@ public class DefaultRepositoryProxyConnectors | |||
} | |||
} | |||
private void validatePolicies( Map<String, DownloadErrorPolicy> policies, Map<String, String> settings, | |||
Properties request, ArtifactReference artifact, RemoteRepositoryContent content, | |||
File localFile, ProxyException exception, Map<String, Exception> previousExceptions ) | |||
throws ProxyDownloadException | |||
{ | |||
boolean process = true; | |||
for ( Entry<String, ? extends DownloadErrorPolicy> entry : policies.entrySet() ) | |||
{ | |||
String key = entry.getKey(); | |||
DownloadErrorPolicy policy = entry.getValue(); | |||
String defaultSetting = policy.getDefaultOption(); | |||
String setting = StringUtils.defaultString( settings.get( key ), defaultSetting ); | |||
log.debug( "Applying [" + key + "] policy with [" + setting + "]" ); | |||
try | |||
{ | |||
// all policies must approve the exception, any can cancel | |||
process = policy.applyPolicy( setting, request, localFile, exception, previousExceptions ); | |||
if ( !process ) | |||
{ | |||
break; | |||
} | |||
} | |||
catch ( PolicyConfigurationException e ) | |||
{ | |||
log.error( e.getMessage(), e ); | |||
} | |||
} | |||
if ( process ) | |||
{ | |||
// if the exception was queued, don't throw it | |||
if ( !previousExceptions.containsKey( content.getId() ) ) | |||
{ | |||
throw new ProxyDownloadException( | |||
"An error occurred in downloading from the remote repository, and the policy is to fail immediately", | |||
content.getId(), exception ); | |||
} | |||
} | |||
else | |||
{ | |||
// if the exception was queued, but cancelled, remove it | |||
previousExceptions.remove( content.getId() ); | |||
} | |||
log.warn( "Transfer error from repository \"" + content.getRepository().getId() + "\" for artifact " + | |||
Keys.toKey( artifact ) + ", continuing to next repository. Error message: " + exception.getMessage() ); | |||
log.debug( "Full stack trace", exception ); | |||
} | |||
/** | |||
* Used to move the temporary file to its real destination. This is patterned from the way WagonManager handles | |||
* its downloaded files. | |||
@@ -802,7 +873,8 @@ public class DefaultRepositoryProxyConnectors | |||
* @param remoteRepository the remote repository to connect to. | |||
* @return true if the connection was successful. false if not connected. | |||
*/ | |||
private boolean connectToRepository( ProxyConnector connector, Wagon wagon, RemoteRepositoryContent remoteRepository ) | |||
private boolean connectToRepository( ProxyConnector connector, Wagon wagon, | |||
RemoteRepositoryContent remoteRepository ) | |||
{ | |||
boolean connected = false; | |||
@@ -851,15 +923,13 @@ public class DefaultRepositoryProxyConnectors | |||
catch ( ConnectionException e ) | |||
{ | |||
log.warn( | |||
"Could not connect to " + remoteRepository.getRepository().getName() + ": " | |||
+ e.getMessage() ); | |||
"Could not connect to " + remoteRepository.getRepository().getName() + ": " + e.getMessage() ); | |||
connected = false; | |||
} | |||
catch ( AuthenticationException e ) | |||
{ | |||
log.warn( | |||
"Could not connect to " + remoteRepository.getRepository().getName() + ": " | |||
+ e.getMessage() ); | |||
"Could not connect to " + remoteRepository.getRepository().getName() + ": " + e.getMessage() ); | |||
connected = false; | |||
} | |||
@@ -911,10 +981,10 @@ public class DefaultRepositoryProxyConnectors | |||
public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue ) | |||
{ | |||
if ( ConfigurationNames.isNetworkProxy( propertyName ) | |||
|| ConfigurationNames.isManagedRepositories( propertyName ) | |||
|| ConfigurationNames.isRemoteRepositories( propertyName ) | |||
|| ConfigurationNames.isProxyConnector( propertyName ) ) | |||
if ( ConfigurationNames.isNetworkProxy( propertyName ) || | |||
ConfigurationNames.isManagedRepositories( propertyName ) || | |||
ConfigurationNames.isRemoteRepositories( propertyName ) || | |||
ConfigurationNames.isProxyConnector( propertyName ) ) | |||
{ | |||
initConnectorsAndNetworkProxies(); | |||
} |
@@ -22,6 +22,7 @@ package org.apache.maven.archiva.proxy; | |||
import org.apache.maven.archiva.model.ArtifactReference; | |||
import org.apache.maven.archiva.model.ProjectReference; | |||
import org.apache.maven.archiva.model.VersionedReference; | |||
import org.apache.maven.archiva.policies.ProxyDownloadException; | |||
import org.apache.maven.archiva.repository.ManagedRepositoryContent; | |||
import java.io.File; | |||
@@ -45,11 +46,11 @@ public interface RepositoryProxyConnectors | |||
* @param repository the source repository to use. (must be a managed repository) | |||
* @param artifact the artifact to fetch. | |||
* @return true if the fetch operation succeeded in obtaining content, false if no content was obtained. | |||
* @throws ProxyException if there was a problem fetching the content from the target repositories. | |||
* @throws ProxyDownloadException if there was a problem fetching the content from the target repositories. | |||
*/ | |||
public File fetchFromProxies( ManagedRepositoryContent repository, ArtifactReference artifact ) | |||
throws ProxyException; | |||
throws ProxyDownloadException; | |||
/** | |||
* Performs the metadata fetch operation against the target repositories | |||
* of the provided source repository. | |||
@@ -60,11 +61,9 @@ public interface RepositoryProxyConnectors | |||
* @param repository the source repository to use. (must be a managed repository) | |||
* @param metadata the metadata to fetch. | |||
* @return true if the fetch operation succeeded in obtaining content, false if no content was obtained. | |||
* @throws ProxyException if there was a problem fetching the content from the target repositories. | |||
*/ | |||
public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata ) | |||
throws ProxyException; | |||
public File fetchFromProxies( ManagedRepositoryContent repository, VersionedReference metadata ); | |||
/** | |||
* Performs the metadata fetch operation against the target repositories | |||
* of the provided source repository. | |||
@@ -75,10 +74,8 @@ public interface RepositoryProxyConnectors | |||
* @param repository the source repository to use. (must be a managed repository) | |||
* @param metadata the metadata to fetch. | |||
* @return true if the fetch operation succeeded in obtaining content, false if no content was obtained. | |||
* @throws ProxyException if there was a problem fetching the content from the target repositories. | |||
*/ | |||
public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata ) | |||
throws ProxyException; | |||
public File fetchFromProxies( ManagedRepositoryContent repository, ProjectReference metadata ); | |||
/** | |||
* Get the List of {@link ProxyConnector} objects of the source repository. |
@@ -37,6 +37,8 @@ import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration; | |||
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration; | |||
import org.apache.maven.archiva.policies.CachedFailuresPolicy; | |||
import org.apache.maven.archiva.policies.ChecksumPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsDownloadPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy; | |||
import org.apache.maven.archiva.policies.ReleasesPolicy; | |||
import org.apache.maven.archiva.policies.SnapshotsPolicy; | |||
import org.apache.maven.archiva.repository.ManagedRepositoryContent; | |||
@@ -295,8 +297,23 @@ public abstract class AbstractProxyTestCase | |||
SnapshotsPolicy.ALWAYS, CachedFailuresPolicy.NO ); | |||
} | |||
protected void saveConnector( String sourceRepoId, String targetRepoId, String checksumPolicy, | |||
String releasePolicy, String snapshotPolicy, String cacheFailuresPolicy ) | |||
protected void saveConnector( String sourceRepoId, String targetRepoId, String checksumPolicy, String releasePolicy, | |||
String snapshotPolicy, String cacheFailuresPolicy ) | |||
{ | |||
saveConnector( sourceRepoId, targetRepoId, checksumPolicy, releasePolicy, snapshotPolicy, cacheFailuresPolicy, | |||
PropagateErrorsDownloadPolicy.QUEUE ); | |||
} | |||
protected void saveConnector( String sourceRepoId, String targetRepoId, String checksumPolicy, String releasePolicy, | |||
String snapshotPolicy, String cacheFailuresPolicy, String errorPolicy ) | |||
{ | |||
saveConnector( sourceRepoId, targetRepoId, checksumPolicy, releasePolicy, snapshotPolicy, cacheFailuresPolicy, | |||
errorPolicy, PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
} | |||
protected void saveConnector( String sourceRepoId, String targetRepoId, String checksumPolicy, String releasePolicy, | |||
String snapshotPolicy, String cacheFailuresPolicy, String errorPolicy, | |||
String errorOnUpdatePolicy ) | |||
{ | |||
ProxyConnectorConfiguration connectorConfig = new ProxyConnectorConfiguration(); | |||
connectorConfig.setSourceRepoId( sourceRepoId ); | |||
@@ -305,6 +322,8 @@ public abstract class AbstractProxyTestCase | |||
connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_RELEASES, releasePolicy ); | |||
connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_SNAPSHOTS, snapshotPolicy ); | |||
connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_CACHE_FAILURES, cacheFailuresPolicy ); | |||
connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS, errorPolicy ); | |||
connectorConfig.addPolicy( ProxyConnectorConfiguration.POLICY_PROPAGATE_ERRORS_ON_UPDATE, errorOnUpdatePolicy ); | |||
int count = config.getConfiguration().getProxyConnectors().size(); | |||
config.getConfiguration().addProxyConnector( connectorConfig ); | |||
@@ -318,6 +337,10 @@ public abstract class AbstractProxyTestCase | |||
config.triggerChange( prefix + ".policies.checksum", connectorConfig.getPolicy( "checksum", "" ) ); | |||
config.triggerChange( prefix + ".policies.snapshots", connectorConfig.getPolicy( "snapshots", "" ) ); | |||
config.triggerChange( prefix + ".policies.cache-failures", connectorConfig.getPolicy( "cache-failures", "" ) ); | |||
config.triggerChange( prefix + ".policies.propagate-errors", | |||
connectorConfig.getPolicy( "propagate-errors", "" ) ); | |||
config.triggerChange( prefix + ".policies.propagate-errors-on-update", | |||
connectorConfig.getPolicy( "propagate-errors-on-update", "" ) ); | |||
} | |||
protected void saveManagedRepositoryConfig( String id, String name, String path, String layout ) |
@@ -0,0 +1,627 @@ | |||
package org.apache.maven.archiva.proxy; | |||
/* | |||
* Licensed to the Apache Software Foundation (ASF) under one | |||
* or more contributor license agreements. See the NOTICE file | |||
* distributed with this work for additional information | |||
* regarding copyright ownership. The ASF licenses this file | |||
* to you under the Apache License, Version 2.0 (the | |||
* "License"); you may not use this file except in compliance | |||
* with the License. You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, | |||
* software distributed under the License is distributed on an | |||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
* KIND, either express or implied. See the License for the | |||
* specific language governing permissions and limitations | |||
* under the License. | |||
*/ | |||
import org.apache.maven.archiva.policies.CachedFailuresPolicy; | |||
import org.apache.maven.archiva.policies.ChecksumPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsDownloadPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy; | |||
import org.apache.maven.archiva.policies.ProxyDownloadException; | |||
import org.apache.maven.archiva.policies.ReleasesPolicy; | |||
import org.apache.maven.archiva.policies.SnapshotsPolicy; | |||
import org.apache.maven.archiva.repository.layout.LayoutException; | |||
import org.apache.maven.wagon.ResourceDoesNotExistException; | |||
import org.apache.maven.wagon.TransferFailedException; | |||
import org.apache.maven.wagon.authorization.AuthorizationException; | |||
import java.io.File; | |||
/** | |||
* ErrorHandlingTest | |||
* | |||
* @author Brett Porter | |||
* @version $Id$ | |||
*/ | |||
public class ErrorHandlingTest | |||
extends AbstractProxyTestCase | |||
{ | |||
private static final String PATH_IN_BOTH_REMOTES_NOT_LOCAL = | |||
"org/apache/maven/test/get-in-both-proxies/1.0/get-in-both-proxies-1.0.jar"; | |||
private static final String PATH_IN_BOTH_REMOTES_AND_LOCAL = | |||
"org/apache/maven/test/get-on-multiple-repos/1.0/get-on-multiple-repos-1.0.pom"; | |||
private static final String ID_MOCKED_PROXIED1 = "badproxied1"; | |||
private static final String NAME_MOCKED_PROXIED1 = "Bad Proxied 1"; | |||
private static final String ID_MOCKED_PROXIED2 = "badproxied2"; | |||
private static final String NAME_MOCKED_PROXIED2 = "Bad Proxied 2"; | |||
public void testPropagateErrorImmediatelyWithErrorThenSuccess() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2 ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED1 ); | |||
} | |||
public void testPropagateErrorImmediatelyWithNotFoundThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.STOP ); | |||
simulateGetError( path, expectedFile, createResourceNotFoundException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED2 ); | |||
} | |||
public void testPropagateErrorImmediatelyWithSuccessThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1 ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.STOP ); | |||
confirmSuccess( path, expectedFile, REPOPATH_PROXIED1 ); | |||
} | |||
public void testPropagateErrorImmediatelyWithNotFoundThenSuccess() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2 ); | |||
simulateGetError( path, expectedFile, createResourceNotFoundException() ); | |||
confirmSuccess( path, expectedFile, REPOPATH_PROXIED2 ); | |||
} | |||
public void testPropagateErrorAtEndWithErrorThenSuccess() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2 ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED1 ); | |||
} | |||
public void testPropagateErrorAtEndWithSuccessThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1 ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE ); | |||
confirmSuccess( path, expectedFile, REPOPATH_PROXIED1 ); | |||
} | |||
public void testPropagateErrorAtEndWithNotFoundThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE ); | |||
simulateGetError( path, expectedFile, createResourceNotFoundException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED2 ); | |||
} | |||
public void testPropagateErrorAtEndWithErrorThenNotFound() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createResourceNotFoundException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED1 ); | |||
} | |||
public void testPropagateErrorAtEndWithErrorThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmFailures( path, new String[]{ID_MOCKED_PROXIED1, ID_MOCKED_PROXIED2} ); | |||
} | |||
public void testPropagateErrorAtEndWithNotFoundThenSuccess() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2 ); | |||
simulateGetError( path, expectedFile, createResourceNotFoundException() ); | |||
confirmSuccess( path, expectedFile, REPOPATH_PROXIED2 ); | |||
} | |||
public void testIgnoreErrorWithErrorThenSuccess() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED2 ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmSuccess( path, expectedFile, REPOPATH_PROXIED2 ); | |||
} | |||
public void testIgnoreErrorWithSuccessThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
saveConnector( ID_DEFAULT_MANAGED, ID_PROXIED1 ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE ); | |||
confirmSuccess( path, expectedFile, REPOPATH_PROXIED1 ); | |||
} | |||
public void testIgnoreErrorWithNotFoundThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE ); | |||
simulateGetError( path, expectedFile, createResourceNotFoundException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
} | |||
public void testIgnoreErrorWithErrorThenNotFound() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createResourceNotFoundException() ); | |||
confirmNotDownloadedNoError( path ); | |||
} | |||
public void testIgnoreErrorWithErrorThenError() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
} | |||
public void testPropagateOnUpdateAlwaysArtifactNotPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED1 ); | |||
} | |||
public void testPropagateOnUpdateAlwaysArtifactPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_AND_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFilePresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED1 ); | |||
} | |||
public void testPropagateOnUpdateAlwaysQueueArtifactNotPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmFailures( path, new String[] { ID_MOCKED_PROXIED1, ID_MOCKED_PROXIED2 } ); | |||
} | |||
public void testPropagateOnUpdateAlwaysQueueArtifactPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_AND_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFilePresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
confirmFailures( path, new String[] { ID_MOCKED_PROXIED1, ID_MOCKED_PROXIED2 } ); | |||
} | |||
public void testPropagateOnUpdateAlwaysIgnoreArtifactNotPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
} | |||
public void testPropagateOnUpdateAlwaysIgnoreArtifactPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_AND_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFilePresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.ALWAYS ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
assertTrue( expectedFile.exists() ); | |||
} | |||
public void testPropagateOnUpdateNotPresentArtifactNotPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmSingleFailure( path, ID_MOCKED_PROXIED1 ); | |||
} | |||
public void testPropagateOnUpdateNotPresentArtifactPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_AND_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFilePresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.STOP, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
assertTrue( expectedFile.exists() ); | |||
} | |||
public void testPropagateOnUpdateNotPresentQueueArtifactNotPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmFailures( path, new String[] { ID_MOCKED_PROXIED1, ID_MOCKED_PROXIED2 } ); | |||
} | |||
public void testPropagateOnUpdateNotPresentQueueArtifactPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_AND_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFilePresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.QUEUE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
assertTrue( expectedFile.exists() ); | |||
} | |||
public void testPropagateOnUpdateNotPresentIgnoreArtifactNotPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_NOT_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFileNotPresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
simulateGetError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
} | |||
public void testPropagateOnUpdateNotPresentIgnoreArtifactPresent() | |||
throws Exception | |||
{ | |||
String path = PATH_IN_BOTH_REMOTES_AND_LOCAL; | |||
File expectedFile = setupRepositoriesWithLocalFilePresent( path ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED1, NAME_MOCKED_PROXIED1, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
createMockedProxyConnector( ID_MOCKED_PROXIED2, NAME_MOCKED_PROXIED2, PropagateErrorsDownloadPolicy.IGNORE, | |||
PropagateErrorsOnUpdateDownloadPolicy.NOT_PRESENT ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
simulateGetIfNewerError( path, expectedFile, createTransferException() ); | |||
confirmNotDownloadedNoError( path ); | |||
assertTrue( expectedFile.exists() ); | |||
} | |||
// ------------------------------------------ | |||
// HELPER METHODS | |||
// ------------------------------------------ | |||
private void createMockedProxyConnector( String id, String name, String errorPolicy ) | |||
{ | |||
saveRemoteRepositoryConfig( id, name, "test://bad.machine.com/repo/", "default" ); | |||
saveConnector( ID_DEFAULT_MANAGED, id, ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS, SnapshotsPolicy.ALWAYS, | |||
CachedFailuresPolicy.NO, errorPolicy ); | |||
} | |||
private void createMockedProxyConnector( String id, String name, String errorPolicy, String errorOnUpdatePolicy ) | |||
{ | |||
saveRemoteRepositoryConfig( id, name, "test://bad.machine.com/repo/", "default" ); | |||
saveConnector( ID_DEFAULT_MANAGED, id, ChecksumPolicy.FIX, ReleasesPolicy.ALWAYS, SnapshotsPolicy.ALWAYS, | |||
CachedFailuresPolicy.NO, errorPolicy, errorOnUpdatePolicy ); | |||
} | |||
private File setupRepositoriesWithLocalFileNotPresent( String path ) | |||
throws Exception | |||
{ | |||
setupTestableManagedRepository( path ); | |||
File file = new File( managedDefaultDir, path ); | |||
assertNotExistsInManagedDefaultRepo( file ); | |||
return file; | |||
} | |||
private File setupRepositoriesWithLocalFilePresent( String path ) | |||
throws Exception | |||
{ | |||
setupTestableManagedRepository( path ); | |||
File file = new File( managedDefaultDir, path ); | |||
assertTrue( file.exists() ); | |||
return file; | |||
} | |||
private void simulateGetError( String path, File expectedFile, Exception throwable ) | |||
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException | |||
{ | |||
wagonMock.get( path, createExpectedTempFile( expectedFile ) ); | |||
wagonMockControl.setThrowable( throwable, 1 ); | |||
} | |||
private void simulateGetIfNewerError( String path, File expectedFile, TransferFailedException exception ) | |||
throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException | |||
{ | |||
wagonMock.getIfNewer( path, createExpectedTempFile( expectedFile ), expectedFile.lastModified() ); | |||
wagonMockControl.setThrowable( exception, 1 ); | |||
} | |||
private File createExpectedTempFile( File expectedFile ) | |||
{ | |||
return new File( expectedFile.getParentFile(), expectedFile.getName() + ".tmp" ).getAbsoluteFile(); | |||
} | |||
private void confirmSingleFailure( String path, String id ) | |||
throws LayoutException | |||
{ | |||
confirmFailures( path, new String[]{id} ); | |||
} | |||
private void confirmFailures( String path, String[] ids ) | |||
throws LayoutException | |||
{ | |||
wagonMockControl.replay(); | |||
// Attempt the proxy fetch. | |||
File downloadedFile = null; | |||
try | |||
{ | |||
downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, | |||
managedDefaultRepository.toArtifactReference( path ) ); | |||
fail( "Proxy should not have succeeded" ); | |||
} | |||
catch ( ProxyDownloadException e ) | |||
{ | |||
assertEquals( ids.length, e.getFailures().size() ); | |||
for ( String id : ids ) | |||
{ | |||
assertTrue( e.getFailures().keySet().contains( id ) ); | |||
} | |||
} | |||
wagonMockControl.verify(); | |||
assertNotDownloaded( downloadedFile ); | |||
} | |||
private void confirmSuccess( String path, File expectedFile, String basedir ) | |||
throws Exception | |||
{ | |||
File downloadedFile = performDownload( path ); | |||
File proxied1File = new File( basedir, path ); | |||
assertFileEquals( expectedFile, downloadedFile, proxied1File ); | |||
} | |||
private void confirmNotDownloadedNoError( String path ) | |||
throws Exception | |||
{ | |||
File downloadedFile = performDownload( path ); | |||
assertNotDownloaded( downloadedFile ); | |||
} | |||
private File performDownload( String path ) | |||
throws ProxyDownloadException, LayoutException | |||
{ | |||
wagonMockControl.replay(); | |||
// Attempt the proxy fetch. | |||
File downloadedFile = proxyHandler.fetchFromProxies( managedDefaultRepository, | |||
managedDefaultRepository.toArtifactReference( path ) ); | |||
wagonMockControl.verify(); | |||
return downloadedFile; | |||
} | |||
private static TransferFailedException createTransferException() | |||
{ | |||
return new TransferFailedException( "test download exception" ); | |||
} | |||
private static ResourceDoesNotExistException createResourceNotFoundException() | |||
{ | |||
return new ResourceDoesNotExistException( "test download not found" ); | |||
} | |||
} |
@@ -0,0 +1,118 @@ | |||
<!-- | |||
~ Licensed to the Apache Software Foundation (ASF) under one | |||
~ or more contributor license agreements. See the NOTICE file | |||
~ distributed with this work for additional information | |||
~ regarding copyright ownership. The ASF licenses this file | |||
~ to you under the Apache License, Version 2.0 (the | |||
~ "License"); you may not use this file except in compliance | |||
~ with the License. You may obtain a copy of the License at | |||
~ | |||
~ http://www.apache.org/licenses/LICENSE-2.0 | |||
~ | |||
~ Unless required by applicable law or agreed to in writing, | |||
~ software distributed under the License is distributed on an | |||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |||
~ KIND, either express or implied. See the License for the | |||
~ specific language governing permissions and limitations | |||
~ under the License. | |||
--> | |||
<component-set> | |||
<components> | |||
<component> | |||
<role>org.apache.maven.wagon.Wagon</role> | |||
<role-hint>test</role-hint> | |||
<implementation>org.apache.maven.archiva.proxy.WagonDelegate</implementation> | |||
</component> | |||
<component> | |||
<role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role> | |||
<role-hint>mock</role-hint> | |||
<implementation>org.apache.maven.archiva.proxy.MockConfiguration</implementation> | |||
</component> | |||
<component> | |||
<role>org.apache.maven.archiva.repository.RepositoryContentFactory</role> | |||
<role-hint>mocked</role-hint> | |||
<implementation>org.apache.maven.archiva.repository.RepositoryContentFactory</implementation> | |||
<description>RepositoryContentRequest</description> | |||
<requirements> | |||
<requirement> | |||
<role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role> | |||
<role-hint>mock</role-hint> | |||
<field-name>archivaConfiguration</field-name> | |||
</requirement> | |||
</requirements> | |||
</component> | |||
<component> | |||
<role>org.apache.maven.archiva.proxy.RepositoryProxyConnectors</role> | |||
<role-hint>default</role-hint> | |||
<implementation>org.apache.maven.archiva.proxy.DefaultRepositoryProxyConnectors</implementation> | |||
<description>DefaultRepositoryProxyConnectors</description> | |||
<requirements> | |||
<requirement> | |||
<role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role> | |||
<role-hint>mock</role-hint> | |||
<field-name>archivaConfiguration</field-name> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.wagon.Wagon</role> | |||
<field-name>wagons</field-name> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.archiva.repository.RepositoryContentFactory</role> | |||
<role-hint>mocked</role-hint> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.archiva.repository.metadata.MetadataTools</role> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.archiva.policies.PreDownloadPolicy</role> | |||
<field-name>preDownloadPolicies</field-name> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.archiva.policies.PostDownloadPolicy</role> | |||
<field-name>postDownloadPolicies</field-name> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.archiva.policies.DownloadErrorPolicy</role> | |||
<field-name>downloadErrorPolicies</field-name> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.archiva.policies.urlcache.UrlFailureCache</role> | |||
<role-hint>default</role-hint> | |||
<field-name>urlFailureCache</field-name> | |||
</requirement> | |||
<requirement> | |||
<role>org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers</role> | |||
<field-name>consumers</field-name> | |||
</requirement> | |||
</requirements> | |||
</component> | |||
<component> | |||
<role>org.codehaus.plexus.cache.Cache</role> | |||
<role-hint>url-failures-cache</role-hint> | |||
<implementation>org.codehaus.plexus.cache.ehcache.EhcacheCache</implementation> | |||
<description>URL Failure Cache</description> | |||
<configuration> | |||
<disk-expiry-thread-interval-seconds>600</disk-expiry-thread-interval-seconds> | |||
<disk-persistent>false</disk-persistent> <!--disabling disk persistence for unit testing. --> | |||
<disk-store-path>${java.io.tmpdir}/archiva/urlcache</disk-store-path> | |||
<eternal>false</eternal> | |||
<max-elements-in-memory>1000</max-elements-in-memory> | |||
<memory-eviction-policy>LRU</memory-eviction-policy> | |||
<name>url-failures-cache</name> | |||
<overflow-to-disk>false</overflow-to-disk> | |||
<!-- 45 minutes = 2700 seconds --> | |||
<time-to-idle-seconds>2700</time-to-idle-seconds> | |||
<!-- 30 minutes = 1800 seconds --> | |||
<time-to-live-seconds>1800</time-to-live-seconds> | |||
</configuration> | |||
</component> | |||
<component> | |||
<role>org.codehaus.plexus.logging.LoggerManager</role> | |||
<implementation>org.codehaus.plexus.logging.slf4j.Slf4jLoggerManager</implementation> | |||
<lifecycle-handler>basic</lifecycle-handler> | |||
</component> | |||
</components> | |||
</component-set> |
@@ -22,7 +22,8 @@ package org.apache.maven.archiva.web.action.admin.connectors.proxy; | |||
import com.opensymphony.xwork.Preparable; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration; | |||
import org.apache.maven.archiva.policies.DownloadPolicy; | |||
import org.apache.maven.archiva.policies.DownloadErrorPolicy; | |||
import org.apache.maven.archiva.policies.Policy; | |||
import org.apache.maven.archiva.policies.PostDownloadPolicy; | |||
import org.apache.maven.archiva.policies.PreDownloadPolicy; | |||
@@ -54,6 +55,11 @@ public abstract class AbstractProxyConnectorFormAction | |||
*/ | |||
private Map<String, PostDownloadPolicy> postDownloadPolicyMap; | |||
/** | |||
* @plexus.requirement role="org.apache.maven.archiva.policies.DownloadErrorPolicy" | |||
*/ | |||
private Map<String, DownloadErrorPolicy> downloadErrorPolicyMap; | |||
/** | |||
* The list of network proxy ids that are available. | |||
*/ | |||
@@ -72,7 +78,7 @@ public abstract class AbstractProxyConnectorFormAction | |||
/** | |||
* The map of policies that are available to be set. | |||
*/ | |||
private Map<String, DownloadPolicy> policyMap; | |||
private Map<String, Policy> policyMap; | |||
/** | |||
* The property key to add or remove. | |||
@@ -185,7 +191,7 @@ public abstract class AbstractProxyConnectorFormAction | |||
return pattern; | |||
} | |||
public Map<String, DownloadPolicy> getPolicyMap() | |||
public Map<String, Policy> getPolicyMap() | |||
{ | |||
return policyMap; | |||
} | |||
@@ -318,7 +324,7 @@ public abstract class AbstractProxyConnectorFormAction | |||
this.pattern = pattern; | |||
} | |||
public void setPolicyMap( Map<String, DownloadPolicy> policyMap ) | |||
public void setPolicyMap( Map<String, Policy> policyMap ) | |||
{ | |||
this.policyMap = policyMap; | |||
} | |||
@@ -363,12 +369,13 @@ public abstract class AbstractProxyConnectorFormAction | |||
return options; | |||
} | |||
protected Map<String, DownloadPolicy> createPolicyMap() | |||
protected Map<String, Policy> createPolicyMap() | |||
{ | |||
Map<String, DownloadPolicy> policyMap = new HashMap<String, DownloadPolicy>(); | |||
Map<String, Policy> policyMap = new HashMap<String, Policy>(); | |||
policyMap.putAll( preDownloadPolicyMap ); | |||
policyMap.putAll( postDownloadPolicyMap ); | |||
policyMap.putAll( downloadErrorPolicyMap ); | |||
return policyMap; | |||
} | |||
@@ -387,10 +394,10 @@ public abstract class AbstractProxyConnectorFormAction | |||
else | |||
{ | |||
// Validate / Fix policy settings arriving from browser. | |||
for ( Map.Entry<String, DownloadPolicy> entry : getPolicyMap().entrySet() ) | |||
for ( Map.Entry<String, Policy> entry : getPolicyMap().entrySet() ) | |||
{ | |||
String policyId = (String) entry.getKey(); | |||
DownloadPolicy policy = (DownloadPolicy) entry.getValue(); | |||
String policyId = entry.getKey(); | |||
Policy policy = entry.getValue(); | |||
List<String> options = policy.getOptions(); | |||
if ( !connector.getPolicies().containsKey( policyId ) ) |
@@ -23,7 +23,7 @@ import org.apache.maven.archiva.common.utils.PathUtil; | |||
import org.apache.maven.archiva.model.ArtifactReference; | |||
import org.apache.maven.archiva.model.ProjectReference; | |||
import org.apache.maven.archiva.model.VersionedReference; | |||
import org.apache.maven.archiva.proxy.ProxyException; | |||
import org.apache.maven.archiva.policies.ProxyDownloadException; | |||
import org.apache.maven.archiva.proxy.RepositoryProxyConnectors; | |||
import org.apache.maven.archiva.repository.ManagedRepositoryContent; | |||
import org.apache.maven.archiva.repository.RepositoryContentFactory; | |||
@@ -364,7 +364,7 @@ public class ProxiedDavServer | |||
{ | |||
/* eat it */ | |||
} | |||
catch ( ProxyException e ) | |||
catch ( ProxyDownloadException e ) | |||
{ | |||
throw new ServletException( "Unable to fetch artifact resource.", e ); | |||
} | |||
@@ -391,10 +391,6 @@ public class ProxiedDavServer | |||
{ | |||
/* eat it */ | |||
} | |||
catch ( ProxyException e ) | |||
{ | |||
throw new ServletException( "Unable to fetch versioned metadata resource.", e ); | |||
} | |||
try | |||
{ | |||
@@ -409,10 +405,6 @@ public class ProxiedDavServer | |||
{ | |||
/* eat it */ | |||
} | |||
catch ( ProxyException e ) | |||
{ | |||
throw new ServletException( "Unable to fetch project metadata resource.", e ); | |||
} | |||
return false; | |||
} | |||
@@ -428,7 +420,7 @@ public class ProxiedDavServer | |||
* artifact. | |||
*/ | |||
protected void applyServerSideRelocation( ArtifactReference artifact ) | |||
throws ProxyException | |||
throws ProxyDownloadException | |||
{ | |||
if ( "pom".equals( artifact.getType() ) ) | |||
{ |
@@ -42,7 +42,7 @@ | |||
<tr> | |||
<td> | |||
<ww:label for="policy_${policy.key}" required="true" | |||
theme="simple">${policy.key}: | |||
theme="simple">${policy.value.name}: | |||
</ww:label> | |||
</td> | |||
<td> |
@@ -28,6 +28,8 @@ import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration; | |||
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration; | |||
import org.apache.maven.archiva.policies.CachedFailuresPolicy; | |||
import org.apache.maven.archiva.policies.ChecksumPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsDownloadPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy; | |||
import org.apache.maven.archiva.policies.ReleasesPolicy; | |||
import org.apache.maven.archiva.policies.SnapshotsPolicy; | |||
import org.apache.maven.archiva.web.action.AbstractWebworkTestCase; | |||
@@ -36,6 +38,7 @@ import org.codehaus.plexus.registry.RegistryException; | |||
import org.easymock.MockControl; | |||
import java.util.List; | |||
import java.util.Map; | |||
/** | |||
* AddProxyConnectorActionTest | |||
@@ -390,10 +393,13 @@ public class AddProxyConnectorActionTest | |||
connector.setTargetRepoId( "central" ); | |||
// TODO: Set these options programatically via list of available policies. | |||
connector.getPolicies().put( "releases", new ReleasesPolicy().getDefaultOption() ); | |||
connector.getPolicies().put( "snapshots", new SnapshotsPolicy().getDefaultOption() ); | |||
connector.getPolicies().put( "checksum", new ChecksumPolicy().getDefaultOption() ); | |||
connector.getPolicies().put( "cache-failures", new CachedFailuresPolicy().getDefaultOption() ); | |||
Map<String, String> policies = connector.getPolicies(); | |||
policies.put( "releases", new ReleasesPolicy().getDefaultOption() ); | |||
policies.put( "snapshots", new SnapshotsPolicy().getDefaultOption() ); | |||
policies.put( "checksum", new ChecksumPolicy().getDefaultOption() ); | |||
policies.put( "cache-failures", new CachedFailuresPolicy().getDefaultOption() ); | |||
policies.put( "propagate-errors", new PropagateErrorsDownloadPolicy().getDefaultOption() ); | |||
policies.put( "propagate-errors-on-update", new PropagateErrorsOnUpdateDownloadPolicy().getDefaultOption() ); | |||
} | |||
@Override |
@@ -28,6 +28,8 @@ import org.apache.maven.archiva.configuration.ProxyConnectorConfiguration; | |||
import org.apache.maven.archiva.configuration.RemoteRepositoryConfiguration; | |||
import org.apache.maven.archiva.policies.CachedFailuresPolicy; | |||
import org.apache.maven.archiva.policies.ChecksumPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsDownloadPolicy; | |||
import org.apache.maven.archiva.policies.PropagateErrorsOnUpdateDownloadPolicy; | |||
import org.apache.maven.archiva.policies.ReleasesPolicy; | |||
import org.apache.maven.archiva.policies.SnapshotsPolicy; | |||
import org.apache.maven.archiva.web.action.AbstractWebworkTestCase; | |||
@@ -36,6 +38,7 @@ import org.codehaus.plexus.registry.RegistryException; | |||
import org.easymock.MockControl; | |||
import java.util.List; | |||
import java.util.Map; | |||
/** | |||
* EditProxyConnectorActionTest | |||
@@ -395,10 +398,13 @@ public class EditProxyConnectorActionTest | |||
connector.setTargetRepoId( TEST_TARGET_ID ); | |||
// TODO: Set these options programatically via list of available policies. | |||
connector.getPolicies().put( "releases", new ReleasesPolicy().getDefaultOption() ); | |||
connector.getPolicies().put( "snapshots", new SnapshotsPolicy().getDefaultOption() ); | |||
connector.getPolicies().put( "checksum", new ChecksumPolicy().getDefaultOption() ); | |||
connector.getPolicies().put( "cache-failures", new CachedFailuresPolicy().getDefaultOption() ); | |||
Map<String, String> policies = connector.getPolicies(); | |||
policies.put( "releases", new ReleasesPolicy().getDefaultOption() ); | |||
policies.put( "snapshots", new SnapshotsPolicy().getDefaultOption() ); | |||
policies.put( "checksum", new ChecksumPolicy().getDefaultOption() ); | |||
policies.put( "cache-failures", new CachedFailuresPolicy().getDefaultOption() ); | |||
policies.put( "propagate-errors", new PropagateErrorsDownloadPolicy().getDefaultOption() ); | |||
policies.put( "propagate-errors-on-update", new PropagateErrorsOnUpdateDownloadPolicy().getDefaultOption() ); | |||
config.addProxyConnector( connector ); | |||