Author: olamy
Date: Thu Sep 22 13:47:58 2011
New Revision: 1174134
URL: http://svn.apache.org/viewvc?rev=1174134&view=rev
Log:
[WAGON-328] Allow putDirectory to continue even if an individual file transfer
fails
Submitted by Andrew Phillips.
Modified:
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java
Modified:
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
URL:
http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java?rev=1174134&r1=1174133&r2=1174134&view=diff
==============================================================================
---
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
(original)
+++
maven/wagon/trunk/wagon-provider-api/src/main/java/org/apache/maven/wagon/AbstractWagon.java
Thu Sep 22 13:47:58 2011
@@ -721,7 +721,6 @@ public abstract class AbstractWagon
protected void fireTransferError( Resource resource, Exception e, int
requestType )
{
TransferEvent transferEvent = new TransferEvent( this, resource, e,
requestType );
-
transferEventSupport.fireTransferError( transferEvent );
}
Modified:
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
URL:
http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java?rev=1174134&r1=1174133&r2=1174134&view=diff
==============================================================================
---
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
(original)
+++
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/main/java/org/apache/maven/wagon/providers/webdav/WebDavWagon.java
Thu Sep 22 13:47:58 2011
@@ -19,12 +19,6 @@ package org.apache.maven.wagon.providers
* under the License.
*/
-import java.io.File;
-import java.io.IOException;
-import java.net.URLDecoder;
-import java.util.ArrayList;
-import java.util.List;
-
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.jackrabbit.webdav.DavConstants;
@@ -48,6 +42,12 @@ import org.codehaus.plexus.util.FileUtil
import org.codehaus.plexus.util.StringUtils;
import org.w3c.dom.Node;
+import java.io.File;
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* <p>WebDavWagon</p>
* <p/>
@@ -57,30 +57,32 @@ import org.w3c.dom.Node;
* @author <a href="mailto:[email protected]">Joakim Erdfelt</a>
* @author <a href="mailto:[email protected]">Carlos Sanchez</a>
* @author <a href="mailto:[email protected]">James William Dumay</a>
- *
* @plexus.component role="org.apache.maven.wagon.Wagon"
- * role-hint="dav"
- * instantiation-strategy="per-lookup"
+ * role-hint="dav"
+ * instantiation-strategy="per-lookup"
*/
public class WebDavWagon
extends AbstractHttpClientWagon
{
+ protected static final String CONTINUE_ON_FAILURE_PROPERTY =
"wagon.webdav.continueOnFailure";
+
+ private final boolean continueOnFailure = Boolean.getBoolean(
CONTINUE_ON_FAILURE_PROPERTY );
+
/**
* Defines the protocol mapping to use.
- *
+ * <p/>
* First string is the user definition way to define a webdav url,
* the second string is the internal representation of that url.
- *
+ * <p/>
* NOTE: The order of the mapping becomes the search order.
*/
- private static final String[][] protocolMap = new String[][] {
- { "dav:http://", "http://" }, /* maven 2.0.x url string format.
(violates URI spec) */
- { "dav:https://", "https://" }, /* maven 2.0.x url string format.
(violates URI spec) */
- { "dav+http://", "http://" }, /* URI spec compliant
(protocol+transport) */
- { "dav+https://", "https://" }, /* URI spec compliant
(protocol+transport) */
- { "dav://", "http://" }, /* URI spec compliant (protocol only)
*/
- { "davs://", "https://" } /* URI spec compliant (protocol only)
*/
- };
+ private static final String[][] protocolMap =
+ new String[][]{ { "dav:http://", "http://" }, /* maven 2.0.x url
string format. (violates URI spec) */
+ { "dav:https://", "https://" }, /* maven 2.0.x url string format.
(violates URI spec) */
+ { "dav+http://", "http://" }, /* URI spec compliant
(protocol+transport) */
+ { "dav+https://", "https://" }, /* URI spec compliant
(protocol+transport) */
+ { "dav://", "http://" }, /* URI spec compliant (protocol
only) */
+ { "davs://", "https://" } /* URI spec compliant (protocol
only) */ };
/**
* This wagon supports directory copying
@@ -112,7 +114,7 @@ public class WebDavWagon
{
baseUrl += ":" + repository.getPort();
}
-
+
// create relative path that will always have a leading and trailing
slash
String relpath = FileUtils.normalize( getPath( basedir, dir ) + "/" );
@@ -252,7 +254,7 @@ public class WebDavWagon
MultiStatusResponse response =
multiStatus.getResponses()[i];
- String entryUrl = response.getHref();
+ String entryUrl = response.getHref();
String fileName = PathUtils.filename(
URLDecoder.decode( entryUrl ) );
if ( entryUrl.endsWith( "/" ) )
{
@@ -298,8 +300,8 @@ public class WebDavWagon
method.releaseConnection();
}
}
- throw new ResourceDoesNotExistException( "Destination path exists but
is not a "
- + "WebDAV collection (directory): " + url );
+ throw new ResourceDoesNotExistException(
+ "Destination path exists but is not a " + "WebDAV collection
(directory): " + url );
}
public String getURL( Repository repository )
@@ -319,4 +321,28 @@ public class WebDavWagon
// No mapping trigger? then just return as-is.
return url;
}
+
+
+ public void put( File source, String resourceName )
+ throws TransferFailedException, ResourceDoesNotExistException,
AuthorizationException
+ {
+ try
+ {
+ super.put( source, resourceName );
+ }
+ catch ( TransferFailedException e )
+ {
+ if ( continueOnFailure )
+ {
+ // TODO use a logging mechanism here or a fireTransferWarning
+ System.out.println(
+ "WARN: Skip unable to transfer '" + resourceName + "' from
'" + source.getPath() + "' due to "
+ + e.getMessage() );
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ }
}
Modified:
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java
URL:
http://svn.apache.org/viewvc/maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java?rev=1174134&r1=1174133&r2=1174134&view=diff
==============================================================================
---
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java
(original)
+++
maven/wagon/trunk/wagon-providers/wagon-webdav-jackrabbit/src/test/java/org/apache/maven/wagon/providers/webdav/WebDavWagonTest.java
Thu Sep 22 13:47:58 2011
@@ -16,8 +16,11 @@ package org.apache.maven.wagon.providers
*/
import it.could.webdav.DAVServlet;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.StreamingWagon;
+import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.http.HttpWagonTestCase;
import org.apache.maven.wagon.repository.Repository;
@@ -28,6 +31,7 @@ import org.mortbay.jetty.servlet.Servlet
import java.io.File;
import java.io.IOException;
+import java.net.SocketTimeoutException;
import java.util.List;
import java.util.Properties;
@@ -68,7 +72,7 @@ public class WebDavWagonTest
return ( file.lastModified() / 1000 ) * 1000;
}
-
+
private File getDavRepository()
{
return getTestFile(
"target/test-output/http-repository/newfolder/folder2" );
@@ -134,8 +138,9 @@ public class WebDavWagonTest
assertURL( "dav+https://localhost:" + getTestRepositoryPort() +
"/dav/",
"https://localhost:" + getTestRepositoryPort() + "/dav/" );
}
-
- public void testMkdirs() throws Exception
+
+ public void testMkdirs()
+ throws Exception
{
setupRepositories();
@@ -143,33 +148,33 @@ public class WebDavWagonTest
WebDavWagon wagon = (WebDavWagon) getWagon();
wagon.connect( testRepository, getAuthInfo() );
-
+
try
{
File dir = getRepositoryDirectory();
-
+
// check basedir also doesn't exist and will need to be created
dir = new File( dir, testRepository.getBasedir() );
assertFalse( dir.exists() );
-
+
// test leading /
assertFalse( new File( dir, "foo" ).exists() );
wagon.mkdirs( "/foo" );
assertTrue( new File( dir, "foo" ).exists() );
-
+
// test trailing /
assertFalse( new File( dir, "bar" ).exists() );
wagon.mkdirs( "bar/" );
assertTrue( new File( dir, "bar" ).exists() );
-
+
// test when already exists
wagon.mkdirs( "bar" );
-
+
// test several parts
assertFalse( new File( dir, "1/2/3/4" ).exists() );
wagon.mkdirs( "1/2/3/4" );
assertTrue( new File( dir, "1/2/3/4" ).exists() );
-
+
// test additional part and trailing /
assertFalse( new File( dir, "1/2/3/4/5" ).exists() );
wagon.mkdirs( "1/2/3/4/5/" );
@@ -178,12 +183,13 @@ public class WebDavWagonTest
finally
{
wagon.disconnect();
-
+
tearDownWagonTestingFixtures();
}
}
- public void testMkdirsWithNoBasedir() throws Exception
+ public void testMkdirsWithNoBasedir()
+ throws Exception
{
// WAGON-244
setupRepositories();
@@ -191,29 +197,29 @@ public class WebDavWagonTest
setupWagonTestingFixtures();
// reconstruct with no basedir
- testRepository.setUrl( testRepository.getProtocol() + "://" +
testRepository.getHost() + ":"
- + testRepository.getPort() );
+ testRepository.setUrl(
+ testRepository.getProtocol() + "://" + testRepository.getHost() +
":" + testRepository.getPort() );
WebDavWagon wagon = (WebDavWagon) getWagon();
wagon.connect( testRepository, getAuthInfo() );
-
+
try
{
File dir = getRepositoryDirectory();
-
+
// check basedir also doesn't exist and will need to be created
dir = new File( dir, testRepository.getBasedir() );
assertTrue( dir.exists() );
-
+
// test leading /
assertFalse( new File( dir, "foo" ).exists() );
wagon.mkdirs( "/foo" );
- assertTrue( new File( dir, "foo" ).exists() );
+ assertTrue( new File( dir, "foo" ).exists() );
}
finally
{
wagon.disconnect();
-
+
tearDownWagonTestingFixtures();
}
}
@@ -225,6 +231,7 @@ public class WebDavWagonTest
/**
* Make sure wagon webdav can detect remote directory
+ *
* @throws Exception
*/
public void testWagonWebDavGetFileList()
@@ -236,20 +243,15 @@ public class WebDavWagonTest
String dirName = "file-list";
- String filenames[] = new String[] {
- "test-resource.txt",
- "test-resource.pom",
- "test-resource b.txt",
- "more-resources.dat" };
+ String filenames[] =
+ new String[]{ "test-resource.txt", "test-resource.pom",
"test-resource b.txt", "more-resources.dat" };
for ( int i = 0; i < filenames.length; i++ )
{
putFile( dirName + "/" + filenames[i], dirName + "/" +
filenames[i], filenames[i] + "\n" );
}
- String dirnames[] = new String[] {
- "test-dir1",
- "test-dir2"};
+ String dirnames[] = new String[]{ "test-dir1", "test-dir2" };
for ( int i = 0; i < dirnames.length; i++ )
{
@@ -293,11 +295,10 @@ public class WebDavWagonTest
}
catch ( ResourceDoesNotExistException e )
{
-
+
}
-
+
wagon.disconnect();
-
tearDownWagonTestingFixtures();
}
@@ -328,4 +329,99 @@ public class WebDavWagonTest
}
}
+
+ public void testWagonFailsOnPutFailureByDefault()
+ throws Exception
+ {
+ setupRepositories();
+
+ setupWagonTestingFixtures();
+
+ File testFile = getTempFile();
+
+ System.clearProperty( WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY );
+
+ WebDavWagon wagon = new TimeoutSimulatingWagon();
+ wagon.connect( testRepository, getAuthInfo() );
+
+ try
+ {
+ String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
+
+ try
+ {
+ wagon.put( testFile, filename );
+ fail( "Exception expected" );
+ }
+ catch ( TransferFailedException e )
+ {
+
+ }
+ }
+ finally
+ {
+ wagon.disconnect();
+
+ tearDownWagonTestingFixtures();
+ }
+ }
+
+ private File getTempFile()
+ throws IOException
+ {
+ File inputFile = File.createTempFile( "test-resource", ".txt" );
+ inputFile.deleteOnExit();
+ return inputFile;
+ }
+
+ private static class TimeoutSimulatingWagon
+ extends WebDavWagon
+ {
+ private static final String TIMEOUT_TRIGGER = "timeout";
+
+ protected int execute( HttpMethod httpMethod )
+ throws HttpException, IOException
+ {
+ if ( httpMethod.getPath().contains( TIMEOUT_TRIGGER ) )
+ {
+ throw new SocketTimeoutException( "Timeout triggered by
request for '" + httpMethod.getPath() + "'" );
+ }
+ else
+ {
+ return super.execute( httpMethod );
+ }
+ }
+ }
+
+ public void testWagonContinuesOnPutFailureIfPropertySet()
+ throws Exception
+ {
+ setupRepositories();
+
+ setupWagonTestingFixtures();
+
+ File testFile = getTempFile();
+
+ String continueOnFailureProperty =
WebDavWagon.CONTINUE_ON_FAILURE_PROPERTY;
+ System.setProperty( continueOnFailureProperty, "true" );
+
+ WebDavWagon wagon = new TimeoutSimulatingWagon();
+ wagon.connect( testRepository, getAuthInfo() );
+
+ try
+ {
+ String filename = TimeoutSimulatingWagon.TIMEOUT_TRIGGER + ".txt";
+
+ wagon.put( testFile, filename );
+ }
+ finally
+ {
+ wagon.disconnect();
+
+ System.clearProperty( continueOnFailureProperty );
+
+ tearDownWagonTestingFixtures();
+ }
+ }
+
}