You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@ant.apache.org by ja...@apache.org on 2017/07/24 05:38:55 UTC
[1/2] ant-ivy git commit: IVY-735 Support timeouts on resolvers
Repository: ant-ivy
Updated Branches:
refs/heads/master 692071797 -> 6607bdcb3
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/util/url/HttpClientHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/url/HttpClientHandler.java b/src/java/org/apache/ivy/util/url/HttpClientHandler.java
index 2c25026..469ad0c 100644
--- a/src/java/org/apache/ivy/util/url/HttpClientHandler.java
+++ b/src/java/org/apache/ivy/util/url/HttpClientHandler.java
@@ -17,19 +17,6 @@
*/
package org.apache.ivy.util.url;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Locale;
-
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
@@ -48,11 +35,25 @@ import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.util.CopyProgressListener;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.HostUtil;
import org.apache.ivy.util.Message;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
/**
*
*/
@@ -93,8 +94,16 @@ public class HttpClientHandler extends AbstractURLHandler {
}
}
- public InputStream openStream(URL url) throws IOException {
- GetMethod get = doGet(url, 0);
+ @Override
+ public InputStream openStream(final URL url) throws IOException {
+ return this.openStream(url, null);
+ }
+
+ @Override
+ public InputStream openStream(final URL url, final TimeoutConstraint timeoutConstraint) throws IOException {
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
+ final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
+ final GetMethod get = doGet(url, connectionTimeout, readTimeout);
if (!checkStatusCode(url, get)) {
get.releaseConnection();
throw new IOException("The HTTP response code for " + url
@@ -103,11 +112,21 @@ public class HttpClientHandler extends AbstractURLHandler {
Header encoding = get.getResponseHeader("Content-Encoding");
return getDecodingInputStream(encoding == null ? null : encoding.getValue(),
- get.getResponseBodyAsStream());
+ get.getResponseBodyAsStream());
}
- public void download(URL src, File dest, CopyProgressListener l) throws IOException {
- GetMethod get = doGet(src, 0);
+ @Override
+ public void download(final URL src, final File dest, final CopyProgressListener l) throws IOException {
+ this.download(src, dest, l, null);
+ }
+
+ @Override
+ public void download(final URL src, final File dest, final CopyProgressListener listener,
+ final TimeoutConstraint timeoutConstraint) throws IOException {
+
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
+ final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
+ final GetMethod get = doGet(src, connectionTimeout, readTimeout);
try {
// We can only figure the content we got is want we want if the status is success.
if (!checkStatusCode(src, get)) {
@@ -117,18 +136,28 @@ public class HttpClientHandler extends AbstractURLHandler {
Header encoding = get.getResponseHeader("Content-Encoding");
InputStream is = getDecodingInputStream(encoding == null ? null : encoding.getValue(),
- get.getResponseBodyAsStream());
- FileUtil.copy(is, dest, l);
+ get.getResponseBodyAsStream());
+ FileUtil.copy(is, dest, listener);
dest.setLastModified(getLastModified(get));
} finally {
get.releaseConnection();
}
}
- public void upload(File src, URL dest, CopyProgressListener l) throws IOException {
- HttpClient client = getClient();
+ @Override
+ public void upload(final File src, final URL dest, final CopyProgressListener l) throws IOException {
+ this.upload(src, dest, l, null);
+ }
- PutMethod put = new PutMethod(normalizeToString(dest));
+ @Override
+ public void upload(final File src, final URL dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
+ final HttpClient client = getClient();
+ // TODO: Use the newer way of settings the connection timeout via HttpConnectionManagerParams
+ // once we stop support for HttpClient 2.x version
+ client.setConnectionTimeout(connectionTimeout);
+
+ final PutMethod put = new PutMethod(normalizeToString(dest));
put.setDoAuthentication(useAuthentication(dest) || useProxyAuthentication());
put.getParams().setBooleanParameter("http.protocol.expect-continue", true);
try {
@@ -138,20 +167,29 @@ public class HttpClientHandler extends AbstractURLHandler {
} finally {
put.releaseConnection();
}
+
+ }
+
+ @Override
+ public URLInfo getURLInfo(final URL url) {
+ return this.getURLInfo(url, null);
}
- public URLInfo getURLInfo(URL url) {
- return getURLInfo(url, 0);
+ @Override
+ public URLInfo getURLInfo(final URL url, final int timeout) {
+ return this.getURLInfo(url, createTimeoutConstraints(timeout));
}
- @SuppressWarnings("deprecation")
- public URLInfo getURLInfo(URL url, int timeout) {
+ @Override
+ public URLInfo getURLInfo(final URL url, final TimeoutConstraint timeoutConstraint) {
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
+ final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
HttpMethodBase method = null;
try {
if (getRequestMethod() == URLHandler.REQUEST_METHOD_HEAD) {
- method = doHead(url, timeout);
+ method = doHead(url, connectionTimeout, readTimeout);
} else {
- method = doGet(url, timeout);
+ method = doGet(url, connectionTimeout, readTimeout);
}
if (checkStatusCode(url, method)) {
return new URLInfo(true, getResponseContentLength(method), getLastModified(method),
@@ -246,10 +284,12 @@ public class HttpClientHandler extends AbstractURLHandler {
return helper.getHttpClientMajorVersion();
}
- @SuppressWarnings("deprecation")
- private GetMethod doGet(URL url, int timeout) throws IOException {
- HttpClient client = getClient();
- client.setTimeout(timeout);
+ private GetMethod doGet(final URL url, final int connectionTimeout, final int readTimeout) throws IOException {
+ final HttpClient client = getClient();
+ // TODO: Use the newer way of settings the connection and read timeout via HttpConnectionManagerParams
+ // once we stop support for HttpClient 2.x version
+ client.setConnectionTimeout(connectionTimeout);
+ client.setTimeout(readTimeout);
GetMethod get = new GetMethod(normalizeToString(url));
get.setDoAuthentication(useAuthentication(url) || useProxyAuthentication());
@@ -258,10 +298,12 @@ public class HttpClientHandler extends AbstractURLHandler {
return get;
}
- @SuppressWarnings("deprecation")
- private HeadMethod doHead(URL url, int timeout) throws IOException {
- HttpClient client = getClient();
- client.setTimeout(timeout);
+ private HeadMethod doHead(final URL url, final int connectionTimeout, final int readTimeout) throws IOException {
+ final HttpClient client = getClient();
+ // TODO: Use the newer way of settings the connection and read timeout via HttpConnectionManagerParams
+ // once we stop support for HttpClient 2.x version
+ client.setConnectionTimeout(connectionTimeout);
+ client.setTimeout(readTimeout);
HeadMethod head = new HeadMethod(normalizeToString(url));
head.setDoAuthentication(useAuthentication(url) || useProxyAuthentication());
@@ -290,18 +332,18 @@ public class HttpClientHandler extends AbstractURLHandler {
httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
if (useProxyAuthentication()) {
httpClient.getState().setProxyCredentials(
- new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM),
- createCredentials(proxyUserName, proxyPasswd));
+ new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM),
+ createCredentials(proxyUserName, proxyPasswd));
}
}
// user-agent
httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT,
- getUserAgent());
+ getUserAgent());
// authentication
httpClient.getParams().setParameter(CredentialsProvider.PROVIDER,
- new IvyCredentialsProvider());
+ new IvyCredentialsProvider());
}
return httpClient;
@@ -376,7 +418,7 @@ public class HttpClientHandler extends AbstractURLHandler {
String realm = scheme.getRealm();
org.apache.ivy.util.Credentials c = CredentialsStore.INSTANCE.getCredentials(realm,
- host);
+ host);
if (c != null) {
return createCredentials(c.getUserName(), c.getPasswd());
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/util/url/URLHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/url/URLHandler.java b/src/java/org/apache/ivy/util/url/URLHandler.java
index b429ef9..0b31c5e 100644
--- a/src/java/org/apache/ivy/util/url/URLHandler.java
+++ b/src/java/org/apache/ivy/util/url/URLHandler.java
@@ -17,13 +17,14 @@
*/
package org.apache.ivy.util.url;
+import org.apache.ivy.core.settings.TimeoutConstraint;
+import org.apache.ivy.util.CopyProgressListener;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
-import org.apache.ivy.util.CopyProgressListener;
-
/**
* This interface is responsible for handling some URL manipulation (stream opening, downloading,
* check reachability, ...).
@@ -34,14 +35,14 @@ public interface URLHandler {
* Using the slower REQUEST method for getting the basic URL infos. Use this when getting errors
* behind a problematic/special proxy or firewall chain.
*/
- public static final int REQUEST_METHOD_GET = 1;
+ int REQUEST_METHOD_GET = 1;
/**
* Using the faster HEAD method for getting the basic URL infos. Works for most common networks.
*/
- public static final int REQUEST_METHOD_HEAD = 2;
+ int REQUEST_METHOD_HEAD = 2;
- public static class URLInfo {
+ class URLInfo {
private long contentLength;
private long lastModified;
@@ -55,7 +56,7 @@ public interface URLHandler {
}
protected URLInfo(boolean available, long contentLength, long lastModified,
- String bodyCharset) {
+ String bodyCharset) {
this.available = available;
this.contentLength = contentLength;
this.lastModified = lastModified;
@@ -79,86 +80,210 @@ public interface URLHandler {
}
}
- public static final URLInfo UNAVAILABLE = new URLInfo(false, 0, 0);
+ URLInfo UNAVAILABLE = new URLInfo(false, 0, 0);
/**
* Please prefer getURLInfo when several infos are needed.
*
* @param url the url to check
* @return true if the target is reachable
+ * @deprecated Use {@link #isReachable(URL, TimeoutConstraint)} instead
*/
- public boolean isReachable(URL url);
+ @Deprecated
+ boolean isReachable(URL url);
/**
* Please prefer getURLInfo when several infos are needed.
*
- * @param url the url to check
+ * @param url the url to check
* @param timeout the timeout in milliseconds
* @return true if the target is reachable
+ * @deprecated Use {@link #isReachable(URL, TimeoutConstraint)} instead
+ */
+ @Deprecated
+ boolean isReachable(URL url, int timeout);
+
+ /**
+ * Returns true if the passed <code>URL</code> is reachable. Else returns false. Uses the
+ * passed <code>timeoutConstraint</code> for determining the connectivity to the URL.
+ * <p>
+ * Please use {@link #getURLInfo(URL, TimeoutConstraint)} if more one information about the <code>url</code>
+ * is needed
+ *
+ * @param url The URL to access
+ * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case the timeouts
+ * are implementation specific
+ * @return
+ * @since 2.5
*/
- public boolean isReachable(URL url, int timeout);
+ boolean isReachable(URL url, TimeoutConstraint timeoutConstraint);
/**
* Please prefer getURLInfo when several infos are needed.
*
* @param url the url to check
* @return the length of the target if the given url is reachable, 0 otherwise. No error code in
- * case of http urls.
+ * case of http urls.
+ * @deprecated Use {@link #getContentLength(URL, TimeoutConstraint)} instead
*/
- public long getContentLength(URL url);
+ @Deprecated
+ long getContentLength(URL url);
/**
- * @param url
- * the url to check
- * @param timeout
- * the maximum time before considering an url is not reachable a
- * timeout of zero indicates no timeout
+ * @param url the url to check
+ * @param timeout the maximum time before considering an url is not reachable a
+ * timeout of zero indicates no timeout
* @return the length of the target if the given url is reachable, 0 otherwise. No error code in
- * case of http urls.
+ * case of http urls.
+ * @deprecated Use {@link #getContentLength(URL, TimeoutConstraint)} instead
*/
- public long getContentLength(URL url, int timeout);
+ @Deprecated
+ long getContentLength(URL url, int timeout);
+
+ /**
+ * Returns the number of bytes of data that's available for the resource at the passed <code>url</code>.
+ * Returns 0 if the passed <code>url</code> isn't reachable
+ *
+ * @param url The URL to access
+ * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case the timeouts
+ * are implementation specific
+ * @return
+ * @since 2.5
+ */
+ long getContentLength(URL url, TimeoutConstraint timeoutConstraint);
/**
* Please prefer getURLInfo when several infos are needed.
*
- * @param url
- * the url to check
+ * @param url the url to check
* @return last modified timestamp of the given url
+ * @deprecated Use {@link #getLastModified(URL, TimeoutConstraint)} instead
*/
- public long getLastModified(URL url);
+ @Deprecated
+ long getLastModified(URL url);
/**
* Please prefer getURLInfo when several infos are needed.
*
- * @param url the url to check
+ * @param url the url to check
* @param timeout the timeout in milliseconds
* @return last modified timestamp of the given url
+ * @deprecated Use {@link #getLastModified(URL, TimeoutConstraint)} instead
*/
- public long getLastModified(URL url, int timeout);
+ @Deprecated
+ long getLastModified(URL url, int timeout);
/**
- * @param url
- * The url from which information is retrieved.
+ * Returns the last modified timestamp of the resource accessible at the passed <code>url</code>.
+ * <p>
+ * Please use {@link #getURLInfo(URL, TimeoutConstraint)} if more one information about the <code>url</code>
+ * is needed
+ *
+ * @param url The URL to access
+ * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case the timeouts
+ * are implementation specific
+ * @return
+ * @since 2.5
+ */
+ long getLastModified(URL url, TimeoutConstraint timeoutConstraint);
+
+ /**
+ * @param url The url from which information is retrieved.
* @return The URLInfo extracted from the given url, or {@link #UNAVAILABLE} instance when the
- * url is not reachable.
+ * url is not reachable.
+ * @deprecated Use {@link #getURLInfo(URL, TimeoutConstraint)} instead
*/
- public URLInfo getURLInfo(URL url);
+ @Deprecated
+ URLInfo getURLInfo(URL url);
/**
- * @param url
- * The url from which information is retrieved.
- * @param timeout
- * The timeout in milliseconds.
+ * @param url The url from which information is retrieved.
+ * @param timeout The timeout in milliseconds.
* @return The URLInfo extracted from the given url, or {@link #UNAVAILABLE} when the url is not
- * reachable, never null.
+ * reachable, never null.
+ * @deprecated Use {@link #getURLInfo(URL, TimeoutConstraint)} instead
*/
- public URLInfo getURLInfo(URL url, int timeout);
+ @Deprecated
+ URLInfo getURLInfo(URL url, int timeout);
- public InputStream openStream(URL url) throws IOException;
+ /**
+ * Returns the {@link URLInfo} extracted from the given url, or {@link #UNAVAILABLE} when the url is not
+ * reachable. Never returns null.
+ *
+ * @param url The URL for which the information is to be retrieved
+ * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case the timeouts
+ * are implementation specific
+ * @return
+ * @since 2.5
+ */
+ URLInfo getURLInfo(URL url, TimeoutConstraint timeoutConstraint);
+
+ /**
+ * @param url
+ * @return
+ * @throws IOException
+ * @deprecated Use {@link #openStream(URL, TimeoutConstraint)} instead
+ */
+ @Deprecated
+ InputStream openStream(URL url) throws IOException;
- public void download(URL src, File dest, CopyProgressListener l) throws IOException;
+ /**
+ * Opens and returns an {@link InputStream} to the passed <code>url</code>.
+ *
+ * @param url The URL to which an {@link InputStream} has to be opened
+ * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case the timeouts
+ * are implementation specific
+ * @return
+ * @throws IOException
+ * @since 2.5
+ */
+ InputStream openStream(URL url, TimeoutConstraint timeoutConstraint) throws IOException;
- public void upload(File src, URL dest, CopyProgressListener l) throws IOException;
+ /**
+ * @param src
+ * @param dest
+ * @param l
+ * @throws IOException
+ * @deprecated Use {@link #download(URL, File, CopyProgressListener, TimeoutConstraint)} instead
+ */
+ @Deprecated
+ void download(URL src, File dest, CopyProgressListener l) throws IOException;
+
+ /**
+ * Downloads the resource available at <code>src</code> to the target <code>dest</code>
+ *
+ * @param src The source URL to download the resource from
+ * @param dest The destination {@link File} to download the resource to
+ * @param listener The listener that will be notified of the download progress
+ * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case the timeouts
+ * are implementation specific
+ * @throws IOException
+ * @since 2.5
+ */
+ void download(URL src, File dest, CopyProgressListener listener, TimeoutConstraint timeoutConstraint) throws IOException;
+
+ /**
+ * @param src
+ * @param dest
+ * @param l
+ * @throws IOException
+ * @deprecated Use {@link #upload(File, URL, CopyProgressListener, TimeoutConstraint)} instead
+ */
+ @Deprecated
+ void upload(File src, URL dest, CopyProgressListener l) throws IOException;
+
+ /**
+ * Uploads the <code>src</code> {@link File} to the target <code>dest</code> {@link URL}
+ *
+ * @param src The source {@link File} to upload
+ * @param dest The target URL where the {@link File} has to be uploaded
+ * @param listener The listener that will be notified of the upload progress
+ * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case the timeouts
+ * are implementation specific
+ * @throws IOException
+ * @since 2.5
+ */
+ void upload(File src, URL dest, CopyProgressListener listener, TimeoutConstraint timeoutConstraint) throws IOException;
- public void setRequestMethod(int requestMethod);
+ void setRequestMethod(int requestMethod);
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/util/url/URLHandlerDispatcher.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/url/URLHandlerDispatcher.java b/src/java/org/apache/ivy/util/url/URLHandlerDispatcher.java
index 2c89098..354d46e 100644
--- a/src/java/org/apache/ivy/util/url/URLHandlerDispatcher.java
+++ b/src/java/org/apache/ivy/util/url/URLHandlerDispatcher.java
@@ -17,6 +17,9 @@
*/
package org.apache.ivy.util.url;
+import org.apache.ivy.core.settings.TimeoutConstraint;
+import org.apache.ivy.util.CopyProgressListener;
+
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -24,8 +27,6 @@ import java.net.URL;
import java.util.HashMap;
import java.util.Map;
-import org.apache.ivy.util.CopyProgressListener;
-
/**
* This class is used to dispatch downloading requests
*/
@@ -37,48 +38,94 @@ public class URLHandlerDispatcher implements URLHandler {
public URLHandlerDispatcher() {
}
- public boolean isReachable(URL url) {
- return getHandler(url.getProtocol()).isReachable(url);
+ @Override
+ public boolean isReachable(final URL url) {
+ return this.isReachable(url, null);
+ }
+
+ @Override
+ public boolean isReachable(final URL url, final int timeout) {
+ return this.isReachable(url, createTimeoutConstraints(timeout));
+ }
+
+ @Override
+ public boolean isReachable(final URL url, final TimeoutConstraint timeoutConstraint) {
+ return this.getHandler(url.getProtocol()).isReachable(url, timeoutConstraint);
+ }
+
+ @Override
+ public long getContentLength(final URL url) {
+ return this.getContentLength(url, null);
+ }
+
+ @Override
+ public long getContentLength(final URL url, final int timeout) {
+ return this.getContentLength(url, createTimeoutConstraints(timeout));
+ }
+
+ @Override
+ public long getContentLength(final URL url, final TimeoutConstraint timeoutConstraint) {
+ return this.getHandler(url.getProtocol()).getContentLength(url, timeoutConstraint);
}
- public boolean isReachable(URL url, int timeout) {
- return getHandler(url.getProtocol()).isReachable(url, timeout);
+ @Override
+ public long getLastModified(final URL url) {
+ return this.getLastModified(url, null);
}
- public long getContentLength(URL url) {
- return getHandler(url.getProtocol()).getContentLength(url);
+ @Override
+ public long getLastModified(final URL url, final int timeout) {
+ return this.getLastModified(url, createTimeoutConstraints(timeout));
}
- public long getContentLength(URL url, int timeout) {
- return getHandler(url.getProtocol()).getContentLength(url, timeout);
+ @Override
+ public long getLastModified(final URL url, final TimeoutConstraint timeoutConstraint) {
+ return this.getHandler(url.getProtocol()).getLastModified(url, timeoutConstraint);
}
- public long getLastModified(URL url) {
- return getHandler(url.getProtocol()).getLastModified(url);
+ @Override
+ public URLInfo getURLInfo(final URL url) {
+ return this.getURLInfo(url, null);
}
- public long getLastModified(URL url, int timeout) {
- return getHandler(url.getProtocol()).getLastModified(url, timeout);
+ @Override
+ public URLInfo getURLInfo(final URL url, final int timeout) {
+ return this.getURLInfo(url, createTimeoutConstraints(timeout));
}
- public URLInfo getURLInfo(URL url) {
- return getHandler(url.getProtocol()).getURLInfo(url);
+ @Override
+ public URLInfo getURLInfo(final URL url, final TimeoutConstraint timeoutConstraint) {
+ return this.getHandler(url.getProtocol()).getURLInfo(url, timeoutConstraint);
}
- public URLInfo getURLInfo(URL url, int timeout) {
- return getHandler(url.getProtocol()).getURLInfo(url, timeout);
+ @Override
+ public InputStream openStream(final URL url) throws IOException {
+ return this.openStream(url, null);
}
- public InputStream openStream(URL url) throws IOException {
- return getHandler(url.getProtocol()).openStream(url);
+ @Override
+ public InputStream openStream(final URL url, final TimeoutConstraint timeoutConstraint) throws IOException {
+ return this.getHandler(url.getProtocol()).openStream(url, timeoutConstraint);
}
- public void download(URL src, File dest, CopyProgressListener l) throws IOException {
- getHandler(src.getProtocol()).download(src, dest, l);
+ @Override
+ public void download(final URL src, final File dest, final CopyProgressListener l) throws IOException {
+ this.download(src, dest, l);
}
- public void upload(File src, URL dest, CopyProgressListener l) throws IOException {
- getHandler(dest.getProtocol()).upload(src, dest, l);
+ @Override
+ public void download(final URL src, final File dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
+ this.getHandler(src.getProtocol()).download(src, dest, listener, timeoutConstraint);
+ }
+
+ @Override
+ public void upload(final File src, final URL dest, final CopyProgressListener l) throws IOException {
+ this.upload(src, dest, l);
+ }
+
+ @Override
+ public void upload(final File src, final URL dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
+ this.getHandler(dest.getProtocol()).upload(src, dest, listener, timeoutConstraint);
}
public void setRequestMethod(int requestMethod) {
@@ -104,4 +151,19 @@ public class URLHandlerDispatcher implements URLHandler {
public void setDefault(URLHandler default1) {
defaultHandler = default1;
}
+
+ private static TimeoutConstraint createTimeoutConstraints(final int connectionTimeout) {
+ return new TimeoutConstraint() {
+ @Override
+ public int getConnectionTimeout() {
+ return connectionTimeout;
+ }
+
+ @Override
+ public int getReadTimeout() {
+ return -1;
+ }
+
+ };
+ }
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/LocalFileRepoOverHttp.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/LocalFileRepoOverHttp.java b/test/java/org/apache/ivy/LocalFileRepoOverHttp.java
new file mode 100644
index 0000000..c1fb17d
--- /dev/null
+++ b/test/java/org/apache/ivy/LocalFileRepoOverHttp.java
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+package org.apache.ivy;
+
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import org.apache.ivy.util.Message;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+/**
+ * A {@link HttpHandler} that can be used in tests to serve local file system based resources over HTTP
+ * NOTE: This handler reads the complete file contents, all into memory while serving it and thus isn't suitable
+ * with very large files. Use this handler only in test cases where the files to serve are reasonably small in size
+ */
+final class LocalFileRepoOverHttp implements HttpHandler {
+
+ private final String webContextRoot;
+ private final Path localFileRepoRoot;
+
+ LocalFileRepoOverHttp(final String webContextRoot, final Path localFileRepoRoot) {
+ if (!Files.isDirectory(localFileRepoRoot)) {
+ throw new IllegalArgumentException(localFileRepoRoot + " is either missing or not a directory");
+ }
+ this.webContextRoot = webContextRoot;
+ this.localFileRepoRoot = localFileRepoRoot;
+ }
+
+ @Override
+ public void handle(final HttpExchange httpExchange) throws IOException {
+ final URI requestURI = httpExchange.getRequestURI();
+ Message.info("Handling " + httpExchange.getRequestMethod() + " request " + requestURI);
+ final URI artifactURI;
+ try {
+ artifactURI = new URI(webContextRoot).relativize(requestURI);
+ } catch (URISyntaxException e) {
+ throw new IOException(e);
+ }
+ final Path localFilePath = localFileRepoRoot.resolve(artifactURI.toString());
+ if (httpExchange.getRequestMethod().equals("HEAD")) {
+ final boolean available = this.isPresent(localFilePath);
+ if (!available) {
+ httpExchange.sendResponseHeaders(404, -1);
+ } else {
+ httpExchange.sendResponseHeaders(200, -1);
+ }
+ return;
+ }
+ if (!httpExchange.getRequestMethod().equals("GET")) {
+ throw new IOException("Cannot handle " + httpExchange.getRequestMethod() + " HTTP method");
+ }
+ final OutputStream responseStream = httpExchange.getResponseBody();
+ final int numBytes = this.serve(httpExchange, localFilePath, responseStream);
+ responseStream.close();
+ }
+
+ private boolean isPresent(final Path localFile) {
+ return Files.isRegularFile(localFile);
+ }
+
+ private int serve(final HttpExchange httpExchange, final Path localFile, final OutputStream os) throws IOException {
+ if (!Files.isRegularFile(localFile)) {
+ throw new IOException("No such file at path " + localFile);
+ }
+ Message.debug("Serving contents of " + localFile + " for request " + httpExchange.getRequestURI());
+ final byte[] data = Files.readAllBytes(localFile);
+ httpExchange.sendResponseHeaders(200, data.length);
+ os.write(data);
+ return data.length;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/TestHelper.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/TestHelper.java b/test/java/org/apache/ivy/TestHelper.java
index e20144b..a908fbd 100644
--- a/test/java/org/apache/ivy/TestHelper.java
+++ b/test/java/org/apache/ivy/TestHelper.java
@@ -17,19 +17,7 @@
*/
package org.apache.ivy;
-import static org.junit.Assert.assertEquals;
-
-import java.io.File;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.net.Authenticator;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Date;
-import java.util.LinkedHashSet;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
+import com.sun.net.httpserver.HttpServer;
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.core.event.EventManager;
import org.apache.ivy.core.module.descriptor.Artifact;
@@ -51,6 +39,21 @@ import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Delete;
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.Authenticator;
+import java.net.InetSocketAddress;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.junit.Assert.assertEquals;
+
public class TestHelper {
public static DefaultArtifact newArtifact(String organisation, String module, String revision,
@@ -371,4 +374,33 @@ public class TestHelper {
return null;
}
}
+
+ /**
+ * Creates a HTTP server, backed by a local file system, which can be used as a repository to serve Ivy module descriptors
+ * and artifacts.
+ * NOTE: This is supposed to be used only in test cases and only a limited functionality is added in the handler(s) backing the
+ * server
+ *
+ * @param serverAddress The address to which the server will be bound
+ * @param webAppContext The context root of the application which will be handling the requests to the server
+ * @param localFilesystemRepoRoot The path to the root directory containing the module descriptors and artifacts
+ * @return
+ * @throws IOException
+ */
+ public static AutoCloseable createHttpServerBackedRepository(final InetSocketAddress serverAddress, final String webAppContext,
+ final Path localFilesystemRepoRoot) throws IOException {
+ final LocalFileRepoOverHttp handler = new LocalFileRepoOverHttp(webAppContext, localFilesystemRepoRoot);
+ final HttpServer server = HttpServer.create(serverAddress, -1);
+ // setup the handler
+ server.createContext(webAppContext, handler);
+ // start the server
+ server.start();
+ return new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ final int delaySeconds = 0;
+ server.stop(delaySeconds);
+ }
+ };
+ }
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/core/resolve/ResolveTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/core/resolve/ResolveTest.java b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
index 43d3cf4..3de1346 100644
--- a/test/java/org/apache/ivy/core/resolve/ResolveTest.java
+++ b/test/java/org/apache/ivy/core/resolve/ResolveTest.java
@@ -840,7 +840,7 @@ public class ResolveTest {
// put necessary stuff in cache, and it should now be ok
File ivyfile = getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"));
File art = getArchiveFileInCache(ivy, "org1", "mod1.2", "2.0", "mod1.2", "jar", "jar");
- FileUtil.copy(ResolveTest.class.getResource("ivy-mod1.2.xml"), ivyfile, null);
+ FileUtil.copy(ResolveTest.class.getResource("ivy-mod1.2.xml"), ivyfile, null, null);
FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), art, null);
ResolveReport report = ivy.resolve(new File(
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java b/test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java
index 2cf7a4f..6a271a4 100644
--- a/test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java
+++ b/test/java/org/apache/ivy/core/settings/XmlSettingsParserTest.java
@@ -17,16 +17,6 @@
*/
package org.apache.ivy.core.settings;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.ParseException;
-import java.util.List;
-
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.module.descriptor.Artifact;
@@ -47,6 +37,7 @@ import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.plugins.resolver.FileSystemResolver;
import org.apache.ivy.plugins.resolver.IBiblioResolver;
import org.apache.ivy.plugins.resolver.MockResolver;
+import org.apache.ivy.plugins.resolver.URLResolver;
import org.apache.ivy.plugins.resolver.packager.PackagerResolver;
import org.apache.ivy.plugins.version.ChainVersionMatcher;
import org.apache.ivy.plugins.version.MockVersionMatcher;
@@ -55,8 +46,19 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
/**
- * TODO write javadoc
+ * Test the parsing of Ivy settings file through the {@link XmlSettingsParser}
*/
public class XmlSettingsParserTest {
@Rule
@@ -77,7 +79,7 @@ public class XmlSettingsParserTest {
assertEquals("[module]/ivys/ivy-[revision].xml", settings.getDefaultCacheIvyPattern());
assertEquals("[module]/[type]s/[artifact]-[revision].[ext]",
- settings.getDefaultCacheArtifactPattern());
+ settings.getDefaultCacheArtifactPattern());
LatestStrategy latest = settings.getLatestStrategy("mylatest-revision");
assertNotNull(latest);
@@ -95,7 +97,7 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals("lib/[organisation]/[module]/ivys/ivy-[revision].xml",
- ivyPatterns.get(0));
+ ivyPatterns.get(0));
LatestStrategy strategy = fsres.getLatestStrategy();
assertNotNull(strategy);
@@ -120,15 +122,15 @@ public class XmlSettingsParserTest {
assertTrue(strategy instanceof LatestTimeStrategy);
assertEquals("libraries",
- settings.getResolver(ModuleRevisionId.newInstance("unknown", "lib", "1.0")).getName());
+ settings.getResolver(ModuleRevisionId.newInstance("unknown", "lib", "1.0")).getName());
assertEquals("internal",
- settings.getResolver(ModuleRevisionId.newInstance("apache", "ant", "1.0")).getName());
+ settings.getResolver(ModuleRevisionId.newInstance("apache", "ant", "1.0")).getName());
assertEquals("int2",
- settings.getResolver(ModuleRevisionId.newInstance("apache", "ivy", "2.0")).getName());
+ settings.getResolver(ModuleRevisionId.newInstance("apache", "ivy", "2.0")).getName());
assertEquals("int1",
- settings.getResolver(ModuleRevisionId.newInstance("apache", "ivy", "1.0")).getName());
+ settings.getResolver(ModuleRevisionId.newInstance("apache", "ivy", "1.0")).getName());
assertEquals("int1",
- settings.getResolver(ModuleRevisionId.newInstance("apache", "ivyde", "1.0")).getName());
+ settings.getResolver(ModuleRevisionId.newInstance("apache", "ivyde", "1.0")).getName());
}
@Test
@@ -217,7 +219,7 @@ public class XmlSettingsParserTest {
assertEquals("[module]/ivys/ivy-[revision].xml", settings.getDefaultCacheIvyPattern());
assertEquals("[module]/[type]s/[artifact]-[revision].[ext]",
- settings.getDefaultCacheArtifactPattern());
+ settings.getDefaultCacheArtifactPattern());
assertEquals(true, settings.isDefaultUseOrigin());
DefaultRepositoryCacheManager c = (DefaultRepositoryCacheManager) settings
@@ -226,13 +228,13 @@ public class XmlSettingsParserTest {
assertEquals("mycache", c.getName());
assertEquals(1000, c.getDefaultTTL());
assertEquals(200,
- c.getTTL(ModuleRevisionId.newInstance("apache", "ivy", "latest.integration")));
+ c.getTTL(ModuleRevisionId.newInstance("apache", "ivy", "latest.integration")));
assertEquals(10 * 60 * 1000 + 20 * 1000, // 10m 20s
- c.getTTL(ModuleRevisionId.newInstance("org1", "A", "A")));
+ c.getTTL(ModuleRevisionId.newInstance("org1", "A", "A")));
assertEquals(5 * 3600 * 1000, // 5h
- c.getTTL(ModuleRevisionId.newInstance("org2", "A", "A")));
+ c.getTTL(ModuleRevisionId.newInstance("org2", "A", "A")));
assertEquals(60 * 3600 * 1000, // 2d 12h = 60h
- c.getTTL(ModuleRevisionId.newInstance("org3", "A", "A")));
+ c.getTTL(ModuleRevisionId.newInstance("org3", "A", "A")));
assertEquals(new File("mycache").getCanonicalFile(), c.getBasedir().getCanonicalFile());
assertEquals(false, c.isUseOrigin());
assertEquals("no-lock", c.getLockStrategy().getName());
@@ -328,7 +330,7 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals("sharedrep/[organisation]/[module]/ivys/ivy-[revision].xml",
- ivyPatterns.get(0));
+ ivyPatterns.get(0));
DependencyResolver external = settings.getResolver("external");
assertNotNull(external);
@@ -344,7 +346,7 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals("sharedrep/[organisation]/[module]/ivys/ivy-[revision].xml",
- ivyPatterns.get(0));
+ ivyPatterns.get(0));
}
@Test
@@ -367,8 +369,8 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals(
- "path/to/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
- ivyPatterns.get(0));
+ "path/to/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
+ ivyPatterns.get(0));
FileSystemResolver fsInt2 = (FileSystemResolver) subresolvers.get(1);
assertEquals("default-fs2", fsInt2.getName());
@@ -377,8 +379,8 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals(
- "path/to/secondrep/[organisation]/[module]/[type]s/ivy-[revision].xml",
- ivyPatterns.get(0));
+ "path/to/secondrep/[organisation]/[module]/[type]s/ivy-[revision].xml",
+ ivyPatterns.get(0));
DependencyResolver other = settings.getResolver("other");
assertNotNull(other);
@@ -395,7 +397,7 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals("path/to/secondrep/[module]/[type]s/ivy-[revision].xml",
- ivyPatterns.get(0));
+ ivyPatterns.get(0));
}
@Test
@@ -476,8 +478,8 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals(
- "path/to/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
- ivyPatterns.get(0));
+ "path/to/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
+ ivyPatterns.get(0));
DependencyResolver inc = settings.getResolver("includeworks");
assertNotNull(inc);
@@ -494,8 +496,8 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals(
- "included/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
- ivyPatterns.get(0));
+ "included/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
+ ivyPatterns.get(0));
// properties defined in included file should be available to including file (IVY-780)
assertEquals("myvalue", settings.getVariable("ivy.test.prop"));
@@ -543,8 +545,8 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals(
- "path/to/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
- ivyPatterns.get(0));
+ "path/to/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
+ ivyPatterns.get(0));
DependencyResolver inc = settings.getResolver("includeworks");
assertNotNull(inc);
@@ -561,8 +563,8 @@ public class XmlSettingsParserTest {
assertNotNull(ivyPatterns);
assertEquals(1, ivyPatterns.size());
assertLocationEquals(
- "included/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
- ivyPatterns.get(0));
+ "included/myrep/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]",
+ ivyPatterns.get(0));
// properties defined in included file should be available to including file (IVY-780)
assertEquals("myvalue", settings.getVariable("ivy.test.prop"));
@@ -584,7 +586,7 @@ public class XmlSettingsParserTest {
XmlSettingsParser parser = new XmlSettingsParser(settings);
parser.parse(XmlSettingsParserTest.class.getResource("ivysettings-parser.xml"));
assertEquals(ModuleDescriptorParserRegistryTest.MyParser.class.getName(),
- ModuleDescriptorParserRegistry.getInstance().getParsers()[0].getClass().getName());
+ ModuleDescriptorParserRegistry.getInstance().getParsers()[0].getClass().getName());
}
@Test
@@ -633,14 +635,14 @@ public class XmlSettingsParserTest {
settings.setBaseDir(new File("test/base/dir"));
assertEquals(new File("test/base/dir").getAbsolutePath(), settings.getVariable("basedir"));
assertEquals(new File("test/base/dir").getAbsolutePath(),
- settings.getVariable("ivy.basedir"));
+ settings.getVariable("ivy.basedir"));
settings = new IvySettings();
settings.setVariable("basedir", new File("other/base/dir").getAbsolutePath());
settings.setBaseDir(new File("test/base/dir"));
assertEquals(new File("other/base/dir").getAbsolutePath(), settings.getVariable("basedir"));
assertEquals(new File("test/base/dir").getAbsolutePath(),
- settings.getVariable("ivy.basedir"));
+ settings.getVariable("ivy.basedir"));
}
/**
@@ -668,9 +670,79 @@ public class XmlSettingsParserTest {
assertEquals("Unexpected ttl for module " + module2 + " on cache manager", 60000, module2SpecificTTL);
}
+ /**
+ * Tests that the <code>timeout-constraint</code> elements in a Ivy settings file are parsed correctly
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testTimeoutConstraints() throws Exception {
+ final IvySettings settings = new IvySettings();
+ settings.setBaseDir(new File("test/base/dir"));
+ final XmlSettingsParser parser = new XmlSettingsParser(settings);
+ parser.parse(XmlSettingsParserTest.class.getResource("ivysettings-timeout-constraints.xml"));
+
+ final TimeoutConstraint timeout1 = settings.getTimeoutConstraint("test-timeout-1");
+ assertNotNull("test-timeout-1 timeout constraint is missing", timeout1);
+ assertEquals("Unexpected connection timeout " + timeout1.getConnectionTimeout() + " on time constraint test-timeout-1", 100, timeout1.getConnectionTimeout());
+ assertEquals("Unexpected read timeout " + timeout1.getReadTimeout() + " on time constraint test-timeout-1", 500, timeout1.getReadTimeout());
+
+
+ final TimeoutConstraint timeout2 = settings.getTimeoutConstraint("test-timeout-2");
+ assertNotNull("test-timeout-2 timeout constraint is missing", timeout2);
+ assertEquals("Unexpected connection timeout " + timeout2.getConnectionTimeout() + " on time constraint test-timeout-2", -1, timeout2.getConnectionTimeout());
+ assertEquals("Unexpected read timeout " + timeout2.getReadTimeout() + " on time constraint test-timeout-2", 20, timeout2.getReadTimeout());
+
+
+ final TimeoutConstraint timeout3 = settings.getTimeoutConstraint("test-timeout-3");
+ assertNotNull("test-timeout-3 timeout constraint is missing", timeout3);
+ assertEquals("Unexpected connection timeout " + timeout3.getConnectionTimeout() + " on time constraint test-timeout-3", 400, timeout3.getConnectionTimeout());
+ assertEquals("Unexpected read timeout " + timeout3.getReadTimeout() + " on time constraint test-timeout-3", -1, timeout3.getReadTimeout());
+
+ final TimeoutConstraint timeout4 = settings.getTimeoutConstraint("test-timeout-4");
+ assertNotNull("test-timeout-4 timeout constraint is missing", timeout4);
+ assertEquals("Unexpected connection timeout " + timeout4.getConnectionTimeout() + " on time constraint test-timeout-4", -1, timeout4.getConnectionTimeout());
+ assertEquals("Unexpected read timeout " + timeout4.getReadTimeout() + " on time constraint test-timeout-4", -1, timeout4.getReadTimeout());
+
+ }
+
+ /**
+ * Tests that timeout constraints referenced by resolvers, in an ivy settings file, are processed correctly and the
+ * corresponding resolvers use the right timeout constraints
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testResolverTimeoutConstraintRefs() throws Exception {
+ final IvySettings settings = new IvySettings();
+ settings.setBaseDir(new File("test/base/dir"));
+ final XmlSettingsParser parser = new XmlSettingsParser(settings);
+ parser.parse(XmlSettingsParserTest.class.getResource("ivysettings-timeout-constraints.xml"));
+
+ final URLResolver resolver1 = (URLResolver) settings.getResolver("urlresolver-1");
+ assertNotNull("Missing resolver urlresolver-1", resolver1);
+ final TimeoutConstraint resolver1Timeouts = resolver1.getTimeoutConstraint();
+ assertNotNull("Timeout constraint missing on resolver " + resolver1.getName(), resolver1Timeouts);
+ assertEquals("Unexpected connection timeout " + resolver1Timeouts.getConnectionTimeout() + " on resolver " + resolver1.getName(), 400, resolver1Timeouts.getConnectionTimeout());
+ assertEquals("Unexpected read timeout " + resolver1Timeouts.getReadTimeout() + " on resolver " + resolver1.getName(), -1, resolver1Timeouts.getReadTimeout());
+
+ final IBiblioResolver resolver2 = (IBiblioResolver) settings.getResolver("ibiblio-resolver");
+ assertNotNull("Missing resolver ibiblio-resolver", resolver2);
+ final TimeoutConstraint resolver2Timeouts = resolver2.getTimeoutConstraint();
+ assertNotNull("Timeout constraint missing on resolver " + resolver2.getName(), resolver2Timeouts);
+ assertEquals("Unexpected connection timeout " + resolver2Timeouts.getConnectionTimeout() + " on resolver " + resolver2.getName(), 100, resolver2Timeouts.getConnectionTimeout());
+ assertEquals("Unexpected read timeout " + resolver2Timeouts.getReadTimeout() + " on resolver " + resolver2.getName(), 500, resolver2Timeouts.getReadTimeout());
+
+ final FileSystemResolver resolver3 = (FileSystemResolver) settings.getResolver("fs");
+ assertNotNull("Missing resolver fs", resolver3);
+ final TimeoutConstraint resolver3Timeouts = resolver3.getTimeoutConstraint();
+ assertNull("No timeout was expected on resolver " + resolver3.getName(), resolver3Timeouts);
+
+ }
+
public static class MyOutputter implements ReportOutputter {
public void output(ResolveReport report, ResolutionCacheManager cacheMgr,
- ResolveOptions options) {
+ ResolveOptions options) {
}
public String getName() {
@@ -691,6 +763,6 @@ public class XmlSettingsParserTest {
private void assertLocationEquals(String expected, Object pattern) throws IOException {
assertEquals(new File(expected).getCanonicalFile(),
- new File((String) pattern).getCanonicalFile());
+ new File((String) pattern).getCanonicalFile());
}
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/core/settings/ivysettings-timeout-constraints.xml
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/core/settings/ivysettings-timeout-constraints.xml b/test/java/org/apache/ivy/core/settings/ivysettings-timeout-constraints.xml
new file mode 100644
index 0000000..e7ba18a
--- /dev/null
+++ b/test/java/org/apache/ivy/core/settings/ivysettings-timeout-constraints.xml
@@ -0,0 +1,30 @@
+<!--
+ ~ 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.
+ -->
+<ivysettings>
+ <timeout-constraints>
+ <timeout-constraint name="test-timeout-1" connectionTimeout="100" readTimeout="500"/>
+ <timeout-constraint name="test-timeout-2" readTimeout="20"/>
+ <timeout-constraint name="test-timeout-3" connectionTimeout="400"/>
+ <timeout-constraint name="test-timeout-4"/>
+ </timeout-constraints>
+
+ <resolvers>
+ <url name="urlresolver-1" timeoutConstraint="test-timeout-3"/>
+ <ibiblio name="ibiblio-resolver" timeoutConstraint="test-timeout-1"/>
+ <filesystem name="fs"/>
+ </resolvers>
+</ivysettings>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoaderTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoaderTest.java b/test/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoaderTest.java
index c41c80a..f6ed927 100644
--- a/test/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoaderTest.java
+++ b/test/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoaderTest.java
@@ -53,7 +53,7 @@ public class UpdateSiteLoaderTest {
cache.mkdirs();
ivySettings.setDefaultCache(cache);
CacheResourceOptions options = new CacheResourceOptions();
- loader = new UpdateSiteLoader(ivySettings.getDefaultRepositoryCacheManager(), null, options);
+ loader = new UpdateSiteLoader(ivySettings.getDefaultRepositoryCacheManager(), null, options, null);
}
@After
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParserTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParserTest.java b/test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParserTest.java
index 2291722..d000006 100644
--- a/test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParserTest.java
+++ b/test/java/org/apache/ivy/plugins/parser/xml/XmlModuleDescriptorParserTest.java
@@ -1396,7 +1396,7 @@ public class XmlModuleDescriptorParserTest extends AbstractModuleDescriptorParse
assertTrue(resolveRoot.exists() || resolveRoot.mkdirs());
FileUtil.copy(getClass().getResource("test-extends-parent.xml"), new File(resolveRoot,
- "myorg/myparent/ivy.xml"), null);
+ "myorg/myparent/ivy.xml"), null, null);
FileSystemResolver resolver = new FileSystemResolver();
resolver.setSettings(settings);
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/plugins/resolver/URLResolverTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/plugins/resolver/URLResolverTest.java b/test/java/org/apache/ivy/plugins/resolver/URLResolverTest.java
index a7ad5ec..f894598 100644
--- a/test/java/org/apache/ivy/plugins/resolver/URLResolverTest.java
+++ b/test/java/org/apache/ivy/plugins/resolver/URLResolverTest.java
@@ -17,10 +17,6 @@
*/
package org.apache.ivy.plugins.resolver;
-import java.io.File;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.core.event.EventManager;
@@ -28,6 +24,7 @@ import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
import org.apache.ivy.core.module.descriptor.DefaultIncludeRule;
+import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.id.ArtifactId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
@@ -39,15 +36,30 @@ import org.apache.ivy.core.resolve.ResolveEngine;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.settings.IvySettings;
+import org.apache.ivy.core.settings.NamedTimeoutConstraint;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.core.sort.SortEngine;
import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import java.io.File;
+import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
/**
* Tests URLResolver. Http tests are based upon ibiblio site.
@@ -367,4 +379,130 @@ public class URLResolverTest extends AbstractDependencyResolverTest {
assertEquals(artifact, ar.getArtifact());
assertEquals(DownloadStatus.NO, ar.getDownloadStatus());
}
+
+ /**
+ * Tests that the timeout constraint set on the URL resolver is used correctly by the resolver
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testTimeoutConstraint() throws Exception {
+ final NamedTimeoutConstraint highTimeout = new NamedTimeoutConstraint("test-high-timeout");
+ highTimeout.setConnectionTimeout(60000);
+ settings.addConfigured(highTimeout);
+ final NamedTimeoutConstraint extremelyLowTimeout = new NamedTimeoutConstraint("test-extremely-low-timeout");
+ extremelyLowTimeout.setConnectionTimeout(10);
+ extremelyLowTimeout.setReadTimeout(20);
+ settings.addConfigured(extremelyLowTimeout);
+
+ // setup a HTTP backed repo
+ // TODO: Right now the port is hard coded, but we need to find a "available" port to which can be bind to.
+ // Else this can lead to occasional bind failures
+ final InetSocketAddress fastServerBindAddr = new InetSocketAddress("localhost", 12345);
+ final String contextRoot = "/testTimeouts";
+ final Path repoRoot = new File("test/repositories/1").toPath();
+ assertTrue(repoRoot + " is not a directory", Files.isDirectory(repoRoot));
+ final DependencyDescriptor dependency = new DefaultDependencyDescriptor(ModuleRevisionId.newInstance("org1", "mod1.1", "2.0"), false);
+ try (final AutoCloseable httpServer = TestHelper.createHttpServerBackedRepository(fastServerBindAddr, contextRoot, repoRoot)) {
+ final String ivyPattern = "http://" + fastServerBindAddr.getHostName() + ":" + fastServerBindAddr.getPort() +
+ "/testTimeouts/[organisation]/[module]/ivys/ivy-[revision].xml";
+ final String artifactPattern = "http://" + fastServerBindAddr.getHostName() + ":" + fastServerBindAddr.getPort() +
+ "/testTimeouts/[organisation]/[module]/[type]s/[artifact]-[revision].[type]";
+ // first use a resolver with a high timeout to make sure it can actually fetch the resources
+ final URLResolver highTimeoutResolver = new URLResolver();
+ highTimeoutResolver.setName("high-timeout-resolver");
+ highTimeoutResolver.setAllownomd(false);
+ highTimeoutResolver.setTimeoutConstraint("test-high-timeout");
+ highTimeoutResolver.setSettings(settings);
+ highTimeoutResolver.setIvyPatterns(Collections.singletonList(ivyPattern));
+ highTimeoutResolver.setArtifactPatterns(Collections.singletonList(artifactPattern));
+ highTimeoutResolver.validate();
+
+ final TimeoutConstraint resolverTimeoutConstraint = highTimeoutResolver.getTimeoutConstraint();
+ assertNotNull("Timeout constraint is missing on resolver " + highTimeoutResolver.getName(), resolverTimeoutConstraint);
+ assertEquals("Unexpected connection timeout on resolver", 60000, resolverTimeoutConstraint.getConnectionTimeout());
+ assertEquals("Unexpected read timeout on resolver", -1, resolverTimeoutConstraint.getReadTimeout());
+
+ // do the fetch (expected to work fine)
+ final ResolvedModuleRevision resolvedModule = highTimeoutResolver.getDependency(dependency, data);
+ assertNotNull("Dependency wasn't resolved by resolver " + highTimeoutResolver.getName(), resolvedModule);
+ assertEquals("Unexpected dependency resolved by resolver " + highTimeoutResolver.getName(), dependency.getDependencyRevisionId(), resolvedModule.getId());
+ }
+
+ // now test this whole fetch using a resolver with a very low connection timeout and by starting the repo server
+ // with a delay so that the connection request can timeout
+
+ // clean the cache before testing to ensure the resource isn't fetched from cache
+ settings.getDefaultRepositoryCacheManager().clean();
+ settings.getResolutionCacheManager().clean();
+
+ final InetSocketAddress slowServerAddr = new InetSocketAddress("localhost", 23456);
+ final String ivyPattern = "http://" + slowServerAddr.getHostName() + ":" + slowServerAddr.getPort() +
+ "/testTimeouts/[organisation]/[module]/ivys/ivy-[revision].xml";
+ final String artifactPattern = "http://" + slowServerAddr.getHostName() + ":" + slowServerAddr.getPort() +
+ "/testTimeouts/[organisation]/[module]/[type]s/[artifact]-[revision].[type]";
+ final URLResolver lowTimeoutResolver = new URLResolver();
+ lowTimeoutResolver.setAllownomd(false);
+ lowTimeoutResolver.setName("low-timeout-resolver");
+ lowTimeoutResolver.setTimeoutConstraint("test-extremely-low-timeout");
+ lowTimeoutResolver.setSettings(settings);
+ lowTimeoutResolver.setIvyPatterns(Collections.singletonList(ivyPattern));
+ lowTimeoutResolver.setArtifactPatterns(Collections.singletonList(artifactPattern));
+ lowTimeoutResolver.validate();
+
+ final TimeoutConstraint lowTimeoutConstraint = lowTimeoutResolver.getTimeoutConstraint();
+ assertNotNull("Timeout constraint is missing on resolver " + lowTimeoutResolver.getName(), lowTimeoutConstraint);
+ assertEquals("Unexpected connection timeout on resolver", 10, lowTimeoutConstraint.getConnectionTimeout());
+ assertEquals("Unexpected read timeout on resolver", 20, lowTimeoutConstraint.getReadTimeout());
+
+ final ExecutorService executor = Executors.newSingleThreadExecutor();
+ final long serverStartupDelayInMillis = 500;
+ final Future<AutoCloseable> httpServer = executor.submit(new ServerManager(slowServerAddr, contextRoot, repoRoot, serverStartupDelayInMillis));
+ try {
+ // do the fetch (resolution *isn't* expected to return resolved module)
+ final ResolvedModuleRevision resolvedModuleFromLowTimeouts = lowTimeoutResolver.getDependency(dependency, data);
+ assertNull("Dependency wasn't expected to be resolved by resolver " + lowTimeoutResolver.getName(), resolvedModuleFromLowTimeouts);
+ } finally {
+ try {
+ // stop the server
+ httpServer.get().close();
+ } catch (Exception e) {
+ // ignore
+ // TODO: Better log it too. But I don't see usage of loggers in test cases currently. So need to get to this later
+ }
+ try {
+ executor.shutdownNow();
+ } catch (Exception e) {
+ // ignore
+ // TODO: Better log it too. But I don't see usage of loggers in test cases currently. So need to get to this later
+ }
+ }
+ }
+
+ private final class ServerManager implements Callable<AutoCloseable> {
+
+ private final InetSocketAddress serverBindAddress;
+ private final long startupDelayInMillis;
+ private final String contextRoot;
+ private final Path localRepoRoot;
+
+ ServerManager(final InetSocketAddress serverBindAddress, final String contextRoot,
+ final Path localRepoRoot, final long startupDelayInMillis) {
+ this.serverBindAddress = serverBindAddress;
+ this.contextRoot = contextRoot;
+ this.localRepoRoot = localRepoRoot;
+ this.startupDelayInMillis = startupDelayInMillis;
+ }
+
+ @Override
+ public AutoCloseable call() throws Exception {
+ if (startupDelayInMillis <= 0) {
+ return TestHelper.createHttpServerBackedRepository(serverBindAddress, contextRoot, localRepoRoot);
+ }
+ // wait for the specified amount of startup delay
+ Thread.sleep(startupDelayInMillis);
+ // start the server
+ return TestHelper.createHttpServerBackedRepository(serverBindAddress, contextRoot, localRepoRoot);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/util/url/AbstractURLHandlerTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/util/url/AbstractURLHandlerTest.java b/test/java/org/apache/ivy/util/url/AbstractURLHandlerTest.java
index a13467d..d30f1dd 100644
--- a/test/java/org/apache/ivy/util/url/AbstractURLHandlerTest.java
+++ b/test/java/org/apache/ivy/util/url/AbstractURLHandlerTest.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.util.CopyProgressListener;
import org.junit.Test;
@@ -74,6 +75,11 @@ public class AbstractURLHandlerTest {
throw new UnsupportedOperationException();
}
+ @Override
+ public void download(final URL src, final File dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
public URLInfo getURLInfo(URL url) {
throw new UnsupportedOperationException();
}
@@ -82,13 +88,28 @@ public class AbstractURLHandlerTest {
throw new UnsupportedOperationException();
}
+ @Override
+ public URLInfo getURLInfo(final URL url, final TimeoutConstraint timeoutConstraint) {
+ throw new UnsupportedOperationException();
+ }
+
public InputStream openStream(URL url) throws IOException {
throw new UnsupportedOperationException();
}
+ @Override
+ public InputStream openStream(final URL url, final TimeoutConstraint timeoutConstraint) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
public void upload(File src, URL dest, CopyProgressListener l) throws IOException {
throw new UnsupportedOperationException();
}
+ @Override
+ public void upload(final File src, final URL dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
}
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/test/java/org/apache/ivy/util/url/BasicURLHandlerTest.java
----------------------------------------------------------------------
diff --git a/test/java/org/apache/ivy/util/url/BasicURLHandlerTest.java b/test/java/org/apache/ivy/util/url/BasicURLHandlerTest.java
index 65269fa..7355b08 100644
--- a/test/java/org/apache/ivy/util/url/BasicURLHandlerTest.java
+++ b/test/java/org/apache/ivy/util/url/BasicURLHandlerTest.java
@@ -62,7 +62,7 @@ public class BasicURLHandlerTest {
// to test ftp we should know of an anonymous ftp site... !
// assertTrue(handler.isReachable(new URL("ftp://ftp.mozilla.org/pub/dir.sizes")));
- assertFalse(handler.isReachable(new URL("ftp://ftp.mozilla.org/unknown.file"), connectionTimeoutInMillis));
+ assertFalse(handler.isReachable(new URL("ftp://ftp.mozilla.org/unknown.file"), 5000));
}
@Test
[2/2] ant-ivy git commit: IVY-735 Support timeouts on resolvers
Posted by ja...@apache.org.
IVY-735 Support timeouts on resolvers
This closes #54 pull request at github/apache/ant-ivy
Project: http://git-wip-us.apache.org/repos/asf/ant-ivy/repo
Commit: http://git-wip-us.apache.org/repos/asf/ant-ivy/commit/6607bdcb
Tree: http://git-wip-us.apache.org/repos/asf/ant-ivy/tree/6607bdcb
Diff: http://git-wip-us.apache.org/repos/asf/ant-ivy/diff/6607bdcb
Branch: refs/heads/master
Commit: 6607bdcb3ba69d2ab4f41be6292cc5a6df6365ba
Parents: 6920717
Author: Jaikiran Pai <ja...@apache.org>
Authored: Mon Jul 10 10:20:38 2017 +0530
Committer: Jaikiran Pai <ja...@apache.org>
Committed: Mon Jul 24 11:07:38 2017 +0530
----------------------------------------------------------------------
asciidoc/settings/resolvers.adoc | 10 +-
asciidoc/settings/timeout-constraint.adoc | 61 ++++++
asciidoc/settings/timeout-constraints.adoc | 54 +++++
asciidoc/toc.json | 13 ++
.../cache/DefaultResolutionCacheManager.java | 6 +
.../ivy/core/cache/ParserSettingsMonitor.java | 6 +
.../apache/ivy/core/settings/IvySettings.java | 57 ++++--
.../core/settings/NamedTimeoutConstraint.java | 80 ++++++++
.../ivy/core/settings/TimeoutConstraint.java | 46 +++++
.../ivy/core/settings/XmlSettingsParser.java | 5 +-
.../apache/ivy/core/settings/typedef.properties | 3 +
.../org/apache/ivy/osgi/obr/OBRResolver.java | 2 +-
.../ivy/osgi/repo/AbstractOSGiResolver.java | 2 +-
.../ivy/osgi/repo/RelativeURLRepository.java | 18 +-
.../ivy/osgi/updatesite/UpdateSiteLoader.java | 19 +-
.../ivy/osgi/updatesite/UpdateSiteResolver.java | 4 +-
.../ivy/plugins/parser/ParserSettings.java | 14 +-
.../plugins/repository/AbstractRepository.java | 15 ++
.../plugins/repository/jar/JarRepository.java | 9 +
.../plugins/repository/sftp/SFTPRepository.java | 5 +
.../ssh/AbstractSshBasedRepository.java | 5 +
.../plugins/repository/ssh/SshRepository.java | 9 +
.../plugins/repository/url/URLRepository.java | 14 +-
.../ivy/plugins/repository/url/URLResource.java | 13 +-
.../plugins/repository/vfs/VfsRepository.java | 5 +
.../repository/vsftp/VsftpRepository.java | 9 +
.../ivy/plugins/resolver/AbstractResolver.java | 29 +++
.../ivy/plugins/resolver/BasicResolver.java | 2 +-
.../ivy/plugins/resolver/JarResolver.java | 4 +-
.../plugins/resolver/LazyTimeoutConstraint.java | 47 +++++
.../plugins/resolver/MirroredURLResolver.java | 6 +-
.../ivy/plugins/resolver/SFTPResolver.java | 2 +-
.../ivy/plugins/resolver/SshResolver.java | 2 +-
.../ivy/plugins/resolver/URLResolver.java | 3 +-
.../ivy/plugins/resolver/VfsResolver.java | 2 +-
.../ivy/plugins/resolver/VsftpResolver.java | 2 +-
src/java/org/apache/ivy/util/FileUtil.java | 11 +-
src/java/org/apache/ivy/util/StringUtils.java | 14 ++
.../apache/ivy/util/url/AbstractURLHandler.java | 59 ++++--
.../apache/ivy/util/url/BasicURLHandler.java | 121 +++++++----
.../apache/ivy/util/url/HttpClientHandler.java | 126 ++++++++----
.../org/apache/ivy/util/url/URLHandler.java | 201 +++++++++++++++----
.../ivy/util/url/URLHandlerDispatcher.java | 110 +++++++---
.../org/apache/ivy/LocalFileRepoOverHttp.java | 91 +++++++++
test/java/org/apache/ivy/TestHelper.java | 58 ++++--
.../apache/ivy/core/resolve/ResolveTest.java | 2 +-
.../core/settings/XmlSettingsParserTest.java | 158 +++++++++++----
.../ivysettings-timeout-constraints.xml | 30 +++
.../osgi/updatesite/UpdateSiteLoaderTest.java | 2 +-
.../xml/XmlModuleDescriptorParserTest.java | 2 +-
.../ivy/plugins/resolver/URLResolverTest.java | 146 +++++++++++++-
.../ivy/util/url/AbstractURLHandlerTest.java | 21 ++
.../ivy/util/url/BasicURLHandlerTest.java | 2 +-
53 files changed, 1454 insertions(+), 283 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/asciidoc/settings/resolvers.adoc
----------------------------------------------------------------------
diff --git a/asciidoc/settings/resolvers.adoc b/asciidoc/settings/resolvers.adoc
index b1fe1aa..14703dd 100644
--- a/asciidoc/settings/resolvers.adoc
+++ b/asciidoc/settings/resolvers.adoc
@@ -104,6 +104,13 @@ Any standard resolver can be used in `force` mode, which is used mainly to handl
By using such a resolver at the beginning of a chain, you can be sure that Ivy will pick up whatever module is available in this resolver (usually a private local build) instead of the real requested revision. This allows to handle use case like a developer working on modules `A` and `C`, where `A -> B -> C`, and pick up the local build for `C` without having to publish a local version of `B`.
*__since 2.0__*
+==== timeoutConstraint
+
+*__since 2.5__*
+
+All standard resolvers support the `timeoutConstraint` attribute. The value for this attribute is the name of the link:timeout-constraint.html[timeout-constraint] that's been defined in the Ivy settings.
+
+Resolvers can be optionally configured to use a `timeoutConstraint` so that the timeouts defined on that constraint dictate how the resolvers behave when it comes to dealing with timeouts while establishing connections and reading content, during module descriptor and artifact resolutions.
==== Maven
@@ -130,12 +137,13 @@ And setting the property `ivy.maven.lookup.javadoc` to `false` disable the looku
|namespace|The name of the namespace to which this resolver belongs *__since 1.3__*|No, defaults to 'system'|Yes|Yes
|checkconsistency|true to check consistency of module descriptors found by this resolver, false to avoid consistency check *__since 1.3__*|No, defaults to true|No|Yes
|descriptor|'optional' if a module descriptor (usually an ivy file) is optional for this resolver, 'required' to refuse modules without module descriptor *__since 2.0__*|No, defaults to 'optional'|No (except dual)|Yes
-|allownomd|_DEPRECATED. Use descriptor="required | optional" instead._
+|allownomd|_DEPRECATED. Use descriptor="required \| optional" instead._
true if the absence of module descriptor (usually an ivy file) is authorised for this resolver, false to refuse modules without module descriptor *__since 1.4__*|No, defaults to true|No (except dual)|Yes
|checksums|a comma separated list of link:../concept.html#checksum[checksum algorithms] to use both for publication and checking *__since 1.4__*|No, defaults to ${ivy.checksums}|No|Yes
|latest|The name of the latest strategy to use.|No, defaults to 'default'|Yes|Yes
|cache|The name of the cache manager to use.|No, defaults to the value of the default attribute of caches|No|Yes
|signer|The name of the link:../settings/signers.html[detached signature generator] to use when publishing artifacts. *__(since 2.2)__*|No, by default published artifacts will not get signed by Ivy.|No|Yes
+|timeoutConstraint|The name of the link:timeout-constraint.html[timeout-constraint] to use for the resolver. *__(since 2.5)__*|No. In the absence of a `timeoutConstraint`, the resolver's behaviour with timeouts is implementation specific.|No|Yes
|=======
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/asciidoc/settings/timeout-constraint.adoc
----------------------------------------------------------------------
diff --git a/asciidoc/settings/timeout-constraint.adoc b/asciidoc/settings/timeout-constraint.adoc
new file mode 100644
index 0000000..ace99ea
--- /dev/null
+++ b/asciidoc/settings/timeout-constraint.adoc
@@ -0,0 +1,61 @@
+////
+ 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.
+////
+
+= timeout-constraint
+
+*Tag:* timeout-constraint
+
+Defines a named timeout constraint that can then be referenced from other places of the Ivy settings file, like the link:resolvers.html[resolvers].
+
+== Attributes
+
+
+[options="header",cols="15%,50%,35%"]
+|=======
+|Attribute|Description|Required
+|name|name of timeout constraint|Yes
+|connectionTimeout|An integer value, in milli seconds, that will be used as the timeout while establishing a connection. +
+A value greater than `0` is used literally as the timeout. +
+A value of `0` indicates no timeout and typically translates to wait-forever kind of semantics. +
+A value lesser than `0` lets the users of this timeout constraint decide what semantics to use. That effectively, implies implementation specific semantics|No, defaults to `-1`
+|readTimeout|An integer value, in milli seconds, that will be used as the timeout while reading content from a resource to which an connection has been established. +
+A value greater than `0` is used literally as the timeout. +
+A value of `0` indicates no timeout and typically translates to wait-forever kind of semantics. +
+A value lesser than `0` lets the users of this timeout constraint decide what semantics to use. That effectively, implies implementation specific semantics|No, defaults to `-1`
+|=======
+
+== Examples
+
+[source, xml]
+----
+ <timeout-constraints>
+ <timeout-constraint name="test-timeout-1" connectionTimeout="100" readTimeout="500"/>
+ <timeout-constraint name="test-timeout-2" readTimeout="20"/>
+ <timeout-constraint name="test-timeout-3" connectionTimeout="400"/>
+ <timeout-constraint name="test-timeout-4"/>
+ </timeout-constraints>
+----
+Here we see 4 timeout constraints defined:
+
+ - `test-timeout-1` uses a connection timeout of 200 milli seconds and read timeout of 500 milli seconds.
+ - `test-timeout-2` uses a read timeout of 20 milli seconds and lets the connection timeout default to -1.
+ - `test-timeout-3` uses a connection timeout of 400 milli seconds and lets the read timeout default to -1.
+ - `test-timeout-4` lets both the connection timeout and read timeout default to -1.
+
+
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/asciidoc/settings/timeout-constraints.adoc
----------------------------------------------------------------------
diff --git a/asciidoc/settings/timeout-constraints.adoc b/asciidoc/settings/timeout-constraints.adoc
new file mode 100644
index 0000000..e331500
--- /dev/null
+++ b/asciidoc/settings/timeout-constraints.adoc
@@ -0,0 +1,54 @@
+////
+ 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.
+////
+
+= timeout-constraints
+
+*__since 2.5__*
+
+Ivy, internally, communicates with various remote systems for dealing with module descriptors and artifacts. This is done through various link:../concept.html[dependency resolvers] that are configured in the Ivy settings. This communication typically involves opening a connection to the target system and reading content from those systems. As with all remote communication, certain systems can sometimes be slow or even unavailable on some occasions. `timeout-constraints` in Ivy settings allows you to configure timeouts that can then be used by Ivy while communicating with remote systems.
+
+NOTE: Although, timeouts are most likely to be used by dependency resolvers, the setting up of timeouts through the use of `timeout-constraints` doesn't really bother about where those timeouts are used. As such, it's _not_ an error to have `timeout-constraints` within a Ivy settings file which may never be referred to by any resolver.
+
+== Child elements
+
+
+[options="header"]
+|=======
+|Element|Description|Cardinality
+|link:../settings/timeout-constraint.html[timeout-constraint]|defines a new timeout-constraint|0..n
+|=======
+
+
+== Examples
+
+
+[source, xml]
+----
+
+<timeout-constraints>
+ <timeout-constraint name="test-timeout-1" connectionTimeout="100" readTimeout="500"/>
+ <timeout-constraint name="test-timeout-2" readTimeout="20"/>
+ <timeout-constraint name="test-timeout-3" connectionTimeout="400"/>
+ <timeout-constraint name="test-timeout-4"/>
+</timeout-constraints>
+
+----
+
+Defines 4 `timeout-constraint`, each with a name and values for `connectionTimeout` and `readTimeout`. More details about the `timeout-constraint` element is explained in link:../settings/timeout-constraint.html[its documentation].
+
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/asciidoc/toc.json
----------------------------------------------------------------------
diff --git a/asciidoc/toc.json b/asciidoc/toc.json
index 63408ce..20615dd 100644
--- a/asciidoc/toc.json
+++ b/asciidoc/toc.json
@@ -479,6 +479,19 @@
"children": [
]
+ },
+ {
+ "id":"settings/timeout-constraints",
+ "title":"timeout-constraints",
+ "children": [
+ {
+ "id":"settings/timeout-constraint",
+ "title":"timeout-constraint",
+ "children": [
+
+ ]
+ }
+ ]
}
]
},
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/core/cache/DefaultResolutionCacheManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/core/cache/DefaultResolutionCacheManager.java b/src/java/org/apache/ivy/core/cache/DefaultResolutionCacheManager.java
index 2d08c44..21e0858 100644
--- a/src/java/org/apache/ivy/core/cache/DefaultResolutionCacheManager.java
+++ b/src/java/org/apache/ivy/core/cache/DefaultResolutionCacheManager.java
@@ -36,6 +36,7 @@ import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.module.status.StatusManager;
import org.apache.ivy.core.settings.IvySettings;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.IvySettingsAware;
import org.apache.ivy.plugins.conflict.ConflictManager;
import org.apache.ivy.plugins.matcher.PatternMatcher;
@@ -283,6 +284,11 @@ public class DefaultResolutionCacheManager implements ResolutionCacheManager, Iv
public String getVariable(String value) {
return delegate.getVariable(value);
}
+
+ @Override
+ public TimeoutConstraint getTimeoutConstraint(final String name) {
+ return this.delegate.getTimeoutConstraint(name);
+ }
}
private static final class MapURLResolver extends RelativeUrlResolver {
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/core/cache/ParserSettingsMonitor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/core/cache/ParserSettingsMonitor.java b/src/java/org/apache/ivy/core/cache/ParserSettingsMonitor.java
index f383578..426ca27 100644
--- a/src/java/org/apache/ivy/core/cache/ParserSettingsMonitor.java
+++ b/src/java/org/apache/ivy/core/cache/ParserSettingsMonitor.java
@@ -26,6 +26,7 @@ import org.apache.ivy.core.RelativeUrlResolver;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.module.status.StatusManager;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.conflict.ConflictManager;
import org.apache.ivy.plugins.matcher.PatternMatcher;
import org.apache.ivy.plugins.namespace.Namespace;
@@ -148,5 +149,10 @@ class ParserSettingsMonitor {
public String getVariable(String value) {
return delegatedSettings.getVariable(value);
}
+
+ @Override
+ public TimeoutConstraint getTimeoutConstraint(final String name) {
+ return delegatedSettings.getTimeoutConstraint(name);
+ }
};
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/core/settings/IvySettings.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/core/settings/IvySettings.java b/src/java/org/apache/ivy/core/settings/IvySettings.java
index adaa188..8e9af4b 100644
--- a/src/java/org/apache/ivy/core/settings/IvySettings.java
+++ b/src/java/org/apache/ivy/core/settings/IvySettings.java
@@ -17,26 +17,6 @@
*/
package org.apache.ivy.core.settings;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Field;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.security.AccessControlException;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.Collection;
-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;
-
import org.apache.ivy.Ivy;
import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.NormalRelativeUrlResolver;
@@ -110,9 +90,30 @@ import org.apache.ivy.plugins.version.VersionRangeMatcher;
import org.apache.ivy.util.Checks;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.Message;
+import org.apache.ivy.util.StringUtils;
import org.apache.ivy.util.filter.Filter;
import org.apache.ivy.util.url.URLHandlerRegistry;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessControlException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collection;
+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;
+
public class IvySettings implements SortEngineSettings, PublishEngineSettings, ParserSettings,
DeliverEngineSettings, CheckEngineSettings, InstallEngineSettings, ResolverSettings,
ResolveEngineSettings, RetrieveEngineSettings, RepositoryManagementEngineSettings {
@@ -212,6 +213,8 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
private AbstractWorkspaceResolver workspaceResolver;
+ private final Map<String, TimeoutConstraint> timeoutConstraints = new HashMap<>();
+
public IvySettings() {
this(new IvyVariableContainerImpl());
}
@@ -1074,6 +1077,20 @@ public class IvySettings implements SortEngineSettings, PublishEngineSettings, P
namespaces.put(ns.getName(), ns);
}
+ public void addConfigured(final NamedTimeoutConstraint timeoutConstraint) {
+ if (timeoutConstraint == null) {
+ return;
+ }
+ final String name = timeoutConstraint.getName();
+ StringUtils.assertNotNullNotEmpty(name, "Name of a timeout constraint cannot be null or empty string");
+ this.timeoutConstraints.put(name, timeoutConstraint);
+ }
+
+ @Override
+ public TimeoutConstraint getTimeoutConstraint(final String name) {
+ return this.timeoutConstraints.get(name);
+ }
+
public synchronized void addConfigured(PatternMatcher m) {
addMatcher(m);
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/core/settings/NamedTimeoutConstraint.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/core/settings/NamedTimeoutConstraint.java b/src/java/org/apache/ivy/core/settings/NamedTimeoutConstraint.java
new file mode 100644
index 0000000..40cdad5
--- /dev/null
+++ b/src/java/org/apache/ivy/core/settings/NamedTimeoutConstraint.java
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+package org.apache.ivy.core.settings;
+
+import org.apache.ivy.util.StringUtils;
+
+/**
+ * An implementation of {@link TimeoutConstraint} which can be identified by a name
+ */
+public class NamedTimeoutConstraint implements TimeoutConstraint {
+
+
+ private String name;
+
+ private int connectionTimeout = -1;
+
+ private int readTimeout = -1;
+
+ public NamedTimeoutConstraint() {
+
+ }
+
+ public NamedTimeoutConstraint(final String name) {
+ StringUtils.assertNotNullNotEmpty(name, "Name of a timeout constraint cannot be null or empty string");
+ this.name = name;
+ }
+
+ public void setName(final String name) {
+ StringUtils.assertNotNullNotEmpty(name, "Name of a timeout constraint cannot be null or empty string");
+ this.name = name;
+ }
+
+ /**
+ * @return Returns the name of the timeout constraint
+ */
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public int getConnectionTimeout() {
+ return this.connectionTimeout;
+ }
+
+ @Override
+ public int getReadTimeout() {
+ return this.readTimeout;
+ }
+
+ /**
+ * Sets the connection timeout of this timeout constraint
+ * @param connectionTimeout The connection timeout in milli seconds.
+ */
+ public void setConnectionTimeout(final int connectionTimeout) {
+ this.connectionTimeout = connectionTimeout;
+ }
+
+ /**
+ * Sets the read timeout of this timeout constraint
+ * @param readTimeout The read timeout in milli seconds.
+ */
+ public void setReadTimeout(final int readTimeout) {
+ this.readTimeout = readTimeout;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/core/settings/TimeoutConstraint.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/core/settings/TimeoutConstraint.java b/src/java/org/apache/ivy/core/settings/TimeoutConstraint.java
new file mode 100644
index 0000000..fecf99b
--- /dev/null
+++ b/src/java/org/apache/ivy/core/settings/TimeoutConstraint.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package org.apache.ivy.core.settings;
+
+/**
+ * Represents the timeouts that are applicable while dealing with resources.
+ * <p>
+ * An example of its usage is {@link org.apache.ivy.plugins.resolver.DependencyResolver dependency resolvers}
+ * when they are resolving module descriptor and/or are downloading the artifacts.
+ */
+public interface TimeoutConstraint {
+
+ /**
+ * @return Returns the timeout, in milli seconds, that's to be used while establishing a connection to a resource.
+ * A value greater than zero indicates the specific timeout to be used. A value of 0 indicates no timeout
+ * and essentially translates to wait-forever semantics. A value lesser than 0 lets the users of this {@link TimeoutConstraint}
+ * decide what kind of timeout semantics to use while establishing a connection (for example, some implementations
+ * can decide to use some default value).
+ */
+ int getConnectionTimeout();
+
+ /**
+ * @return Returns the timeout, in milli seconds, that's to be used while reading content from a resource.
+ * A value greater than zero indicates the specific timeout to be used. A value of 0 indicates no timeout
+ * and essentially translates to wait-forever semantics. A value lesser than 0 lets the users of this {@link TimeoutConstraint}
+ * decide what kind of timeout semantics to use reading from the resource (for example, some implementations
+ * can decide to use some default value).
+ */
+ int getReadTimeout();
+
+}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java b/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
index f245b49..e749337 100644
--- a/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
+++ b/src/java/org/apache/ivy/core/settings/XmlSettingsParser.java
@@ -105,7 +105,7 @@ public class XmlSettingsParser extends DefaultHandler {
private List<String> configuratorTags = Arrays.asList("resolvers", "namespaces", "parsers",
"latest-strategies", "conflict-managers", "outputters", "version-matchers", "statuses",
- "circular-dependency-strategies", "triggers", "lock-strategies", "caches", "signers");
+ "circular-dependency-strategies", "triggers", "lock-strategies", "caches", "signers", "timeout-constraints");
private IvySettings ivy;
@@ -180,6 +180,7 @@ public class XmlSettingsParser extends DefaultHandler {
doParse(configuration);
}
+ @Override
public void startElement(String uri, String localName, String qName, Attributes att)
throws SAXException {
// we first copy attributes in a Map to be able to modify them
@@ -596,6 +597,7 @@ public class XmlSettingsParser extends DefaultHandler {
}
}
+ @Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (configurator.getCurrent() != null) {
if (configuratorTags.contains(qName) && configurator.getDepth() == 1) {
@@ -610,6 +612,7 @@ public class XmlSettingsParser extends DefaultHandler {
}
}
+ @Override
public void endDocument() throws SAXException {
if (defaultResolver != null) {
ivy.setDefaultResolver(ivy.substitute(defaultResolver));
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/core/settings/typedef.properties
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/core/settings/typedef.properties b/src/java/org/apache/ivy/core/settings/typedef.properties
index ba140d2..4e3eb8e 100644
--- a/src/java/org/apache/ivy/core/settings/typedef.properties
+++ b/src/java/org/apache/ivy/core/settings/typedef.properties
@@ -65,3 +65,6 @@ cache = org.apache.ivy.core.cache.DefaultRepositoryCacheManager
pgp = org.apache.ivy.plugins.signer.bouncycastle.OpenPGPSignatureGenerator
osgi-manifest-parser = org.apache.ivy.osgi.core.OSGiManifestParser
+
+timeout-constraint = org.apache.ivy.core.settings.NamedTimeoutConstraint
+
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/osgi/obr/OBRResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/osgi/obr/OBRResolver.java b/src/java/org/apache/ivy/osgi/obr/OBRResolver.java
index c1e3bb5..477f258 100644
--- a/src/java/org/apache/ivy/osgi/obr/OBRResolver.java
+++ b/src/java/org/apache/ivy/osgi/obr/OBRResolver.java
@@ -85,7 +85,7 @@ public class OBRResolver extends AbstractOSGiResolver {
if (eventManager != null) {
getRepository().addTransferListener(eventManager);
}
- Resource obrResource = new URLResource(url);
+ final Resource obrResource = new URLResource(url, this.getTimeoutConstraint());
CacheResourceOptions options = new CacheResourceOptions();
if (metadataTtl != null) {
options.setTtl(metadataTtl);
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/osgi/repo/AbstractOSGiResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/osgi/repo/AbstractOSGiResolver.java b/src/java/org/apache/ivy/osgi/repo/AbstractOSGiResolver.java
index 08e762c..f469264 100644
--- a/src/java/org/apache/ivy/osgi/repo/AbstractOSGiResolver.java
+++ b/src/java/org/apache/ivy/osgi/repo/AbstractOSGiResolver.java
@@ -296,7 +296,7 @@ public abstract class AbstractOSGiResolver extends BasicResolver {
}
Message.verbose("\tusing url for " + artifact + ": " + url);
logArtifactAttempt(artifact, url.toExternalForm());
- Resource resource = new URLResource(url);
+ final Resource resource = new URLResource(url, this.getTimeoutConstraint());
return new ResolvedResource(resource, artifact.getModuleRevisionId().getRevision());
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/osgi/repo/RelativeURLRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/osgi/repo/RelativeURLRepository.java b/src/java/org/apache/ivy/osgi/repo/RelativeURLRepository.java
index 03b6860..8ab90cb 100644
--- a/src/java/org/apache/ivy/osgi/repo/RelativeURLRepository.java
+++ b/src/java/org/apache/ivy/osgi/repo/RelativeURLRepository.java
@@ -24,6 +24,7 @@ import java.net.URL;
import java.util.HashMap;
import java.util.Map;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.url.URLRepository;
import org.apache.ivy.plugins.repository.url.URLResource;
@@ -37,11 +38,22 @@ public class RelativeURLRepository extends URLRepository {
baseUrl = null;
}
+ /**
+ *
+ * @param baseUrl
+ * @deprecated Since 2.5. Use {@link #RelativeURLRepository(URL, TimeoutConstraint)} instead
+ */
+ @Deprecated
public RelativeURLRepository(URL baseUrl) {
- super();
+ this(baseUrl, null);
+ }
+
+ public RelativeURLRepository(final URL baseUrl, final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
this.baseUrl = baseUrl;
}
+
private Map<String, Resource> resourcesCache = new HashMap<>();
public Resource getResource(String source) throws IOException {
@@ -56,9 +68,9 @@ public class RelativeURLRepository extends URLRepository {
uri = null;
}
if (uri == null || uri.isAbsolute()) {
- res = new URLResource(new URL(source));
+ res = new URLResource(new URL(source), getTimeoutConstraint());
} else {
- res = new URLResource(new URL(baseUrl + source));
+ res = new URLResource(new URL(baseUrl + source), getTimeoutConstraint());
}
resourcesCache.put(source, res);
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java b/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java
index dd0c227..c88be4d 100644
--- a/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java
+++ b/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteLoader.java
@@ -32,6 +32,7 @@ import org.apache.ivy.core.cache.RepositoryCacheManager;
import org.apache.ivy.core.event.EventManager;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.DownloadStatus;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.osgi.core.ExecutionEnvironmentProfileProvider;
import org.apache.ivy.osgi.p2.P2ArtifactParser;
import org.apache.ivy.osgi.p2.P2CompositeParser;
@@ -57,12 +58,16 @@ public class UpdateSiteLoader {
private final CacheResourceOptions options;
+ private final TimeoutConstraint timeoutConstraint;
+
private int logLevel = Message.MSG_INFO;
- public UpdateSiteLoader(RepositoryCacheManager repositoryCacheManager,
- EventManager eventManager, CacheResourceOptions options) {
+ public UpdateSiteLoader(final RepositoryCacheManager repositoryCacheManager,
+ final EventManager eventManager, final CacheResourceOptions options,
+ final TimeoutConstraint timeoutConstraint) {
this.repositoryCacheManager = repositoryCacheManager;
this.options = options;
+ this.timeoutConstraint = timeoutConstraint;
if (eventManager != null) {
urlRepository.addTransferListener(eventManager);
}
@@ -177,7 +182,7 @@ public class UpdateSiteLoader {
InputStream readIn = null; // the input stream from which the xml should be read
URL contentUrl = repoUri.resolve(baseName + ".jar").toURL();
- URLResource res = new URLResource(contentUrl);
+ URLResource res = new URLResource(contentUrl, this.timeoutConstraint);
ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
baseName, baseName, "jar", options, urlRepository);
@@ -185,7 +190,7 @@ public class UpdateSiteLoader {
if (report.getDownloadStatus() == DownloadStatus.FAILED) {
// no jar file, try the xml one
contentUrl = repoUri.resolve(baseName + ".xml").toURL();
- res = new URLResource(contentUrl);
+ res = new URLResource(contentUrl, this.timeoutConstraint);
report = repositoryCacheManager.downloadRepositoryResource(res, baseName, baseName,
"xml", options, urlRepository);
@@ -226,7 +231,7 @@ public class UpdateSiteLoader {
URI siteUri = normalizeSiteUri(repoUri, null);
URL u = siteUri.resolve("site.xml").toURL();
- URLResource res = new URLResource(u);
+ final URLResource res = new URLResource(u, this.timeoutConstraint);
ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
"site", "updatesite", "xml", options, urlRepository);
if (report.getDownloadStatus() == DownloadStatus.FAILED) {
@@ -272,7 +277,7 @@ public class UpdateSiteLoader {
URL digest = digestBaseUri.resolve("digest.zip").toURL();
Message.verbose("\tReading " + digest);
- URLResource res = new URLResource(digest);
+ final URLResource res = new URLResource(digest, this.timeoutConstraint);
ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
"digest", "digest", "zip", options, urlRepository);
if (report.getDownloadStatus() == DownloadStatus.FAILED) {
@@ -294,7 +299,7 @@ public class UpdateSiteLoader {
for (EclipseFeature feature : site.getFeatures()) {
URL url = site.getUri().resolve(feature.getUrl()).toURL();
- URLResource res = new URLResource(url);
+ final URLResource res = new URLResource(url, this.timeoutConstraint);
ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
feature.getId(), "feature", "jar", options, urlRepository);
if (report.getDownloadStatus() == DownloadStatus.FAILED) {
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteResolver.java b/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteResolver.java
index f6dde81..8e3d653 100644
--- a/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteResolver.java
+++ b/src/java/org/apache/ivy/osgi/updatesite/UpdateSiteResolver.java
@@ -115,8 +115,8 @@ public class UpdateSiteResolver extends AbstractOSGiResolver {
}
}
});
- UpdateSiteLoader loader = new UpdateSiteLoader(getRepositoryCacheManager(),
- getEventManager(), options);
+ final UpdateSiteLoader loader = new UpdateSiteLoader(getRepositoryCacheManager(),
+ getEventManager(), options, this.getTimeoutConstraint());
loader.setLogLevel(log);
RepoDescriptor repoDescriptor;
try {
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/parser/ParserSettings.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/parser/ParserSettings.java b/src/java/org/apache/ivy/plugins/parser/ParserSettings.java
index 8294547..49e5333 100644
--- a/src/java/org/apache/ivy/plugins/parser/ParserSettings.java
+++ b/src/java/org/apache/ivy/plugins/parser/ParserSettings.java
@@ -17,19 +17,20 @@
*/
package org.apache.ivy.plugins.parser;
-import java.io.File;
-import java.util.Map;
-
import org.apache.ivy.core.RelativeUrlResolver;
import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.module.status.StatusManager;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.conflict.ConflictManager;
import org.apache.ivy.plugins.matcher.PatternMatcher;
import org.apache.ivy.plugins.namespace.Namespace;
import org.apache.ivy.plugins.resolver.DependencyResolver;
+import java.io.File;
+import java.util.Map;
+
public interface ParserSettings {
String substitute(String value);
@@ -60,4 +61,11 @@ public interface ParserSettings {
Namespace getContextNamespace();
String getVariable(String string);
+
+ /**
+ * @param name The name of the {@link TimeoutConstraint}
+ * @return Returns a {@link TimeoutConstraint} which is identified by the passed <code>name</code>. Returns null
+ * if no such {@link TimeoutConstraint} exists
+ */
+ TimeoutConstraint getTimeoutConstraint(String name);
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/AbstractRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/AbstractRepository.java b/src/java/org/apache/ivy/plugins/repository/AbstractRepository.java
index f5419bc..9149050 100644
--- a/src/java/org/apache/ivy/plugins/repository/AbstractRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/AbstractRepository.java
@@ -24,6 +24,7 @@ import java.util.Arrays;
import javax.swing.event.EventListenerList;
import org.apache.ivy.core.module.descriptor.Artifact;
+import org.apache.ivy.core.settings.TimeoutConstraint;
public abstract class AbstractRepository implements Repository {
private EventListenerList listeners = new EventListenerList();
@@ -32,6 +33,16 @@ public abstract class AbstractRepository implements Repository {
private TransferEvent evt;
+ private final TimeoutConstraint timeoutConstraint;
+
+ public AbstractRepository() {
+ this(null);
+ }
+
+ protected AbstractRepository(final TimeoutConstraint timeoutConstraint) {
+ this.timeoutConstraint = timeoutConstraint;
+ }
+
public void addTransferListener(TransferListener listener) {
listeners.add(TransferListener.class, listener);
}
@@ -121,6 +132,10 @@ public abstract class AbstractRepository implements Repository {
this.name = name;
}
+ public TimeoutConstraint getTimeoutConstraint() {
+ return this.timeoutConstraint;
+ }
+
@Override
public String toString() {
return getName();
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/jar/JarRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/jar/JarRepository.java b/src/java/org/apache/ivy/plugins/repository/jar/JarRepository.java
index b3ea9be..937c3d4 100644
--- a/src/java/org/apache/ivy/plugins/repository/jar/JarRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/jar/JarRepository.java
@@ -27,6 +27,7 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.AbstractRepository;
import org.apache.ivy.plugins.repository.RepositoryCopyProgressListener;
import org.apache.ivy.plugins.repository.Resource;
@@ -39,6 +40,14 @@ public class JarRepository extends AbstractRepository {
private JarFile jarFile;
+ public JarRepository() {
+
+ }
+
+ public JarRepository(final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
+ }
+
public void setJarFile(JarFile jarFile) {
this.jarFile = jarFile;
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/sftp/SFTPRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/sftp/SFTPRepository.java b/src/java/org/apache/ivy/plugins/repository/sftp/SFTPRepository.java
index e1d013c..b18e212 100644
--- a/src/java/org/apache/ivy/plugins/repository/sftp/SFTPRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/sftp/SFTPRepository.java
@@ -26,6 +26,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.BasicResource;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.TransferEvent;
@@ -72,6 +73,10 @@ public class SFTPRepository extends AbstractSshBasedRepository {
public SFTPRepository() {
}
+ public SFTPRepository(final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
+ }
+
public Resource getResource(String source) {
return new SFTPResource(this, source);
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/ssh/AbstractSshBasedRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/ssh/AbstractSshBasedRepository.java b/src/java/org/apache/ivy/plugins/repository/ssh/AbstractSshBasedRepository.java
index 3411bd6..7bacf8c 100644
--- a/src/java/org/apache/ivy/plugins/repository/ssh/AbstractSshBasedRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/ssh/AbstractSshBasedRepository.java
@@ -25,6 +25,7 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.AbstractRepository;
import org.apache.ivy.util.Credentials;
import org.apache.ivy.util.CredentialsUtil;
@@ -59,6 +60,10 @@ public abstract class AbstractSshBasedRepository extends AbstractRepository {
super();
}
+ public AbstractSshBasedRepository(final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
+ }
+
/**
* hashmap of user/hosts with credentials. key is hostname, value is Credentials
**/
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/ssh/SshRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/ssh/SshRepository.java b/src/java/org/apache/ivy/plugins/repository/ssh/SshRepository.java
index 46b380c..a839724 100644
--- a/src/java/org/apache/ivy/plugins/repository/ssh/SshRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/ssh/SshRepository.java
@@ -29,6 +29,7 @@ import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.util.Message;
@@ -57,6 +58,14 @@ public class SshRepository extends AbstractSshBasedRepository {
private String publishPermissions = null;
+ public SshRepository() {
+
+ }
+
+ public SshRepository(final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
+ }
+
/**
* create a new resource with lazy initializing
*
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/url/URLRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/url/URLRepository.java b/src/java/org/apache/ivy/plugins/repository/url/URLRepository.java
index d045c60..c2173f0 100644
--- a/src/java/org/apache/ivy/plugins/repository/url/URLRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/url/URLRepository.java
@@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.AbstractRepository;
import org.apache.ivy.plugins.repository.RepositoryCopyProgressListener;
import org.apache.ivy.plugins.repository.Resource;
@@ -40,10 +41,17 @@ public class URLRepository extends AbstractRepository {
private final Map<String, Resource> resourcesCache = new HashMap<>();
+ public URLRepository() {
+ }
+
+ public URLRepository(final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
+ }
+
public Resource getResource(String source) throws IOException {
Resource res = resourcesCache.get(source);
if (res == null) {
- res = new URLResource(new URL(source));
+ res = new URLResource(new URL(source), this.getTimeoutConstraint());
resourcesCache.put(source, res);
}
return res;
@@ -57,7 +65,7 @@ public class URLRepository extends AbstractRepository {
if (totalLength > 0) {
progress.setTotalLength(totalLength);
}
- FileUtil.copy(new URL(source), destination, progress);
+ FileUtil.copy(new URL(source), destination, progress, getTimeoutConstraint());
} catch (IOException | RuntimeException ex) {
fireTransferError(ex);
throw ex;
@@ -77,7 +85,7 @@ public class URLRepository extends AbstractRepository {
if (totalLength > 0) {
progress.setTotalLength(totalLength);
}
- FileUtil.copy(source, new URL(destination), progress);
+ FileUtil.copy(source, new URL(destination), progress, getTimeoutConstraint());
} catch (IOException | RuntimeException ex) {
fireTransferError(ex);
throw ex;
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/url/URLResource.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/url/URLResource.java b/src/java/org/apache/ivy/plugins/repository/url/URLResource.java
index c687308..6a1fb3e 100644
--- a/src/java/org/apache/ivy/plugins/repository/url/URLResource.java
+++ b/src/java/org/apache/ivy/plugins/repository/url/URLResource.java
@@ -24,13 +24,15 @@ import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.LocalizableResource;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.util.url.URLHandler.URLInfo;
import org.apache.ivy.util.url.URLHandlerRegistry;
public class URLResource implements LocalizableResource {
- private URL url;
+ private final URL url;
+ private final TimeoutConstraint timeoutConstraint;
private boolean init = false;
@@ -40,8 +42,13 @@ public class URLResource implements LocalizableResource {
private boolean exists;
- public URLResource(URL url) {
+ public URLResource(final URL url) {
+ this(url, null);
+ }
+
+ public URLResource(final URL url, final TimeoutConstraint timeoutConstraint) {
this.url = url;
+ this.timeoutConstraint = timeoutConstraint;
}
public String getName() {
@@ -65,7 +72,7 @@ public class URLResource implements LocalizableResource {
}
private void init() {
- URLInfo info = URLHandlerRegistry.getDefault().getURLInfo(url);
+ final URLInfo info = URLHandlerRegistry.getDefault().getURLInfo(url, this.timeoutConstraint);
contentLength = info.getContentLength();
lastModified = info.getLastModified();
exists = info.isReachable();
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/vfs/VfsRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/vfs/VfsRepository.java b/src/java/org/apache/ivy/plugins/repository/vfs/VfsRepository.java
index 4706cb6..4eacea6 100644
--- a/src/java/org/apache/ivy/plugins/repository/vfs/VfsRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/vfs/VfsRepository.java
@@ -31,6 +31,7 @@ import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.FileType;
import org.apache.commons.vfs.impl.StandardFileSystemManager;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.AbstractRepository;
import org.apache.ivy.plugins.repository.RepositoryCopyProgressListener;
import org.apache.ivy.plugins.repository.Resource;
@@ -58,6 +59,10 @@ public class VfsRepository extends AbstractRepository {
public VfsRepository() {
}
+ public VfsRepository(final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
+ }
+
private FileSystemManager getVFSManager() throws IOException {
synchronized (this) {
if (manager == null) {
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/repository/vsftp/VsftpRepository.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/repository/vsftp/VsftpRepository.java b/src/java/org/apache/ivy/plugins/repository/vsftp/VsftpRepository.java
index 463facc..f776143 100644
--- a/src/java/org/apache/ivy/plugins/repository/vsftp/VsftpRepository.java
+++ b/src/java/org/apache/ivy/plugins/repository/vsftp/VsftpRepository.java
@@ -34,6 +34,7 @@ import org.apache.ivy.core.IvyThread;
import org.apache.ivy.core.event.IvyEvent;
import org.apache.ivy.core.event.IvyListener;
import org.apache.ivy.core.event.resolve.EndResolveEvent;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.plugins.repository.AbstractRepository;
import org.apache.ivy.plugins.repository.BasicResource;
import org.apache.ivy.plugins.repository.Resource;
@@ -119,6 +120,14 @@ public class VsftpRepository extends AbstractRepository {
private Ivy ivy = null;
+ public VsftpRepository() {
+
+ }
+
+ public VsftpRepository(final TimeoutConstraint timeoutConstraint) {
+ super(timeoutConstraint);
+ }
+
public Resource getResource(String source) throws IOException {
initIvy();
return new VsftpResource(this, source);
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java b/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
index 59148de..7366bfd 100644
--- a/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
@@ -54,6 +54,7 @@ import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.search.ModuleEntry;
import org.apache.ivy.core.search.OrganisationEntry;
import org.apache.ivy.core.search.RevisionEntry;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.core.settings.Validatable;
import org.apache.ivy.plugins.conflict.ConflictManager;
import org.apache.ivy.plugins.latest.ArtifactInfo;
@@ -111,6 +112,9 @@ public abstract class AbstractResolver implements DependencyResolver, HasLatestS
private Boolean checkmodified;
+ private String timeoutConstraintName;
+ private TimeoutConstraint timeoutConstraint;
+
public ResolverSettings getSettings() {
return settings;
}
@@ -205,6 +209,14 @@ public abstract class AbstractResolver implements DependencyResolver, HasLatestS
return getClass().getName();
}
+ public TimeoutConstraint getTimeoutConstraint() {
+ return this.timeoutConstraint;
+ }
+
+ public void setTimeoutConstraint(final String name) {
+ this.timeoutConstraintName = name;
+ }
+
/**
* Default implementation downloads the artifact without taking advantage of its location
*
@@ -412,6 +424,17 @@ public abstract class AbstractResolver implements DependencyResolver, HasLatestS
}
}
+ private void initTimeoutConstraintFromSettings() {
+ if (this.timeoutConstraintName == null) {
+ return;
+ }
+ this.timeoutConstraint = settings.getTimeoutConstraint(this.timeoutConstraintName);
+ if (this.timeoutConstraint == null) {
+ throw new IllegalStateException("Unknown timeout constraint '" + this.timeoutConstraintName + "' " +
+ "on resolver '" + this.name + "'");
+ }
+ }
+
public void setRepositoryCacheManager(RepositoryCacheManager repositoryCacheManager) {
this.cacheManagerName = repositoryCacheManager.getName();
this.repositoryCacheManager = repositoryCacheManager;
@@ -429,10 +452,12 @@ public abstract class AbstractResolver implements DependencyResolver, HasLatestS
return eventManager;
}
+ @Override
public void validate() {
initRepositoryCacheManagerFromSettings();
initNamespaceFromSettings();
initLatestStrategyFromSettings();
+ initTimeoutConstraintFromSettings();
}
protected CacheMetadataOptions getCacheOptions(ResolveData data) {
@@ -617,5 +642,9 @@ public abstract class AbstractResolver implements DependencyResolver, HasLatestS
return AbstractResolver.this.getSettings().getVariable(value);
}
+ @Override
+ public TimeoutConstraint getTimeoutConstraint(final String name) {
+ return AbstractResolver.this.getSettings().getTimeoutConstraint(name);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java b/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java
index 780cc05..e759764 100644
--- a/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/BasicResolver.java
@@ -1037,7 +1037,7 @@ public abstract class BasicResolver extends AbstractResolver {
}
resource = new FileResource(new FileRepository(), f);
} else {
- resource = new URLResource(url);
+ resource = new URLResource(url, this.getTimeoutConstraint());
}
ret = new ResolvedResource(resource, artifact.getModuleRevisionId().getRevision());
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/JarResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/JarResolver.java b/src/java/org/apache/ivy/plugins/resolver/JarResolver.java
index 623a5f5..b02830b 100644
--- a/src/java/org/apache/ivy/plugins/resolver/JarResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/JarResolver.java
@@ -37,7 +37,7 @@ public class JarResolver extends RepositoryResolver {
private URL url;
public JarResolver() {
- setRepository(new JarRepository());
+ setRepository(new JarRepository(new LazyTimeoutConstraint(this)));
}
@Override
@@ -84,7 +84,7 @@ public class JarResolver extends RepositoryResolver {
if (eventManager != null) {
getRepository().addTransferListener(eventManager);
}
- Resource jarResource = new URLResource(url);
+ Resource jarResource = new URLResource(url, this.getTimeoutConstraint());
CacheResourceOptions options = new CacheResourceOptions();
report = getRepositoryCacheManager().downloadRepositoryResource(jarResource,
"jarrepository", "jar", "jar", options, new URLRepository());
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/LazyTimeoutConstraint.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/LazyTimeoutConstraint.java b/src/java/org/apache/ivy/plugins/resolver/LazyTimeoutConstraint.java
new file mode 100644
index 0000000..aec17e2
--- /dev/null
+++ b/src/java/org/apache/ivy/plugins/resolver/LazyTimeoutConstraint.java
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+package org.apache.ivy.plugins.resolver;
+
+import org.apache.ivy.core.settings.TimeoutConstraint;
+
+/**
+ * A {@link TimeoutConstraint} which determines the timeouts by invoking the {@link AbstractResolver underlying resolver}'s
+ * {@link AbstractResolver#getTimeoutConstraint()}, whenever the timeouts are requested for.
+ * This class can be used when the {@link TimeoutConstraint} is to be created but the underlying resolver, which decides the timeouts,
+ * hasn't yet been fully initialized
+ */
+final class LazyTimeoutConstraint implements TimeoutConstraint {
+
+ private final AbstractResolver resolver;
+
+ public LazyTimeoutConstraint(final AbstractResolver resolver) {
+ this.resolver = resolver;
+ }
+
+ @Override
+ public int getConnectionTimeout() {
+ final TimeoutConstraint resolverTimeoutConstraint = resolver.getTimeoutConstraint();
+ return resolverTimeoutConstraint == null ? -1 : resolverTimeoutConstraint.getConnectionTimeout();
+ }
+
+ @Override
+ public int getReadTimeout() {
+ final TimeoutConstraint resolverTimeoutConstraint = resolver.getTimeoutConstraint();
+ return resolverTimeoutConstraint == null ? -1 : resolverTimeoutConstraint.getReadTimeout();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java b/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java
index eeb3339..947c826 100644
--- a/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/MirroredURLResolver.java
@@ -67,7 +67,7 @@ public class MirroredURLResolver extends RepositoryResolver {
+ ", an incorrect url has been found and will then not be used: " + baseUrl);
}
if (url != null) {
- RelativeURLRepository repo = new RelativeURLRepository(url);
+ final RelativeURLRepository repo = new RelativeURLRepository(url, this.getTimeoutConstraint());
repositories.add(repo);
}
}
@@ -75,11 +75,11 @@ public class MirroredURLResolver extends RepositoryResolver {
}
private File downloadMirrorList() {
- URLRepository urlRepository = new URLRepository();
+ final URLRepository urlRepository = new URLRepository(this.getTimeoutConstraint());
if (getEventManager() != null) {
urlRepository.addTransferListener(getEventManager());
}
- URLResource mirrorResource = new URLResource(mirrorListUrl);
+ final URLResource mirrorResource = new URLResource(mirrorListUrl, this.getTimeoutConstraint());
CacheResourceOptions options = new CacheResourceOptions();
ArtifactDownloadReport report = getRepositoryCacheManager().downloadRepositoryResource(
mirrorResource, "mirrorlist", "text", "txt", options, urlRepository);
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/SFTPResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/SFTPResolver.java b/src/java/org/apache/ivy/plugins/resolver/SFTPResolver.java
index 096df8d..d06d3fc 100644
--- a/src/java/org/apache/ivy/plugins/resolver/SFTPResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/SFTPResolver.java
@@ -28,7 +28,7 @@ import org.apache.ivy.plugins.repository.sftp.SFTPRepository;
public class SFTPResolver extends AbstractSshBasedResolver {
public SFTPResolver() {
- setRepository(new SFTPRepository());
+ setRepository(new SFTPRepository(new LazyTimeoutConstraint(this)));
}
@Override
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/SshResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/SshResolver.java b/src/java/org/apache/ivy/plugins/resolver/SshResolver.java
index 3c68dcc..afb0dcb 100644
--- a/src/java/org/apache/ivy/plugins/resolver/SshResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/SshResolver.java
@@ -25,7 +25,7 @@ import org.apache.ivy.plugins.repository.ssh.SshRepository;
public class SshResolver extends AbstractSshBasedResolver {
public SshResolver() {
- setRepository(new SshRepository());
+ setRepository(new SshRepository(new LazyTimeoutConstraint(this)));
}
/**
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/URLResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/URLResolver.java b/src/java/org/apache/ivy/plugins/resolver/URLResolver.java
index d34ad33..3900845 100644
--- a/src/java/org/apache/ivy/plugins/resolver/URLResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/URLResolver.java
@@ -25,11 +25,12 @@ import org.apache.ivy.plugins.repository.url.URLRepository;
*/
public class URLResolver extends RepositoryResolver {
public URLResolver() {
- setRepository(new URLRepository());
+ setRepository(new URLRepository(new LazyTimeoutConstraint(this)));
}
@Override
public String getTypeName() {
return "url";
}
+
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/VfsResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/VfsResolver.java b/src/java/org/apache/ivy/plugins/resolver/VfsResolver.java
index 931b704..6df0753 100644
--- a/src/java/org/apache/ivy/plugins/resolver/VfsResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/VfsResolver.java
@@ -31,7 +31,7 @@ public class VfsResolver extends RepositoryResolver {
private static final int PASSWORD_GROUP = 2;
public VfsResolver() {
- setRepository(new VfsRepository());
+ setRepository(new VfsRepository(new LazyTimeoutConstraint(this)));
}
@Override
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/plugins/resolver/VsftpResolver.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/plugins/resolver/VsftpResolver.java b/src/java/org/apache/ivy/plugins/resolver/VsftpResolver.java
index 0ccbacf..9bb8e7f 100644
--- a/src/java/org/apache/ivy/plugins/resolver/VsftpResolver.java
+++ b/src/java/org/apache/ivy/plugins/resolver/VsftpResolver.java
@@ -25,7 +25,7 @@ import org.apache.ivy.plugins.repository.vsftp.VsftpRepository;
*/
public class VsftpResolver extends RepositoryResolver {
public VsftpResolver() {
- setRepository(new VsftpRepository());
+ setRepository(new VsftpRepository(new LazyTimeoutConstraint(this)));
}
@Override
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/util/FileUtil.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/FileUtil.java b/src/java/org/apache/ivy/util/FileUtil.java
index 56ada7e..5446e9d 100644
--- a/src/java/org/apache/ivy/util/FileUtil.java
+++ b/src/java/org/apache/ivy/util/FileUtil.java
@@ -45,6 +45,7 @@ import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import java.util.zip.ZipInputStream;
+import org.apache.ivy.core.settings.TimeoutConstraint;
import org.apache.ivy.util.url.URLHandlerRegistry;
/**
@@ -271,12 +272,14 @@ public final class FileUtil {
return true;
}
- public static void copy(URL src, File dest, CopyProgressListener l) throws IOException {
- URLHandlerRegistry.getDefault().download(src, dest, l);
+ public static void copy(final URL src, final File dest, final CopyProgressListener listener,
+ final TimeoutConstraint timeoutConstraint) throws IOException {
+ URLHandlerRegistry.getDefault().download(src, dest, listener, timeoutConstraint);
}
- public static void copy(File src, URL dest, CopyProgressListener l) throws IOException {
- URLHandlerRegistry.getDefault().upload(src, dest, l);
+ public static void copy(final File src, final URL dest, final CopyProgressListener listener,
+ final TimeoutConstraint timeoutConstraint) throws IOException {
+ URLHandlerRegistry.getDefault().upload(src, dest, listener, timeoutConstraint);
}
public static void copy(InputStream src, File dest, CopyProgressListener l) throws IOException {
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/util/StringUtils.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/StringUtils.java b/src/java/org/apache/ivy/util/StringUtils.java
index 6e4931a..5c596d4 100644
--- a/src/java/org/apache/ivy/util/StringUtils.java
+++ b/src/java/org/apache/ivy/util/StringUtils.java
@@ -189,4 +189,18 @@ public final class StringUtils {
return sb.toString();
}
+ /**
+ * Asserts that the passed <code>value</code> is not null and not an empty {@link String}. The implementation
+ * of this method {@link String#trim() trims} the (non-null) <code>value</code> to check whether the value is an
+ * empty string. If the <code>value</code> is either null or empty, then this method throws an {@link IllegalArgumentException}
+ * with the passed <code>errorMessage</code> as the message in the exception.
+ *
+ * @param value The value to check for
+ * @param errorMessage The error message
+ */
+ public static void assertNotNullNotEmpty(final String value, final String errorMessage) {
+ if (value == null || value.trim().isEmpty()) {
+ throw new IllegalArgumentException(errorMessage);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/util/url/AbstractURLHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/url/AbstractURLHandler.java b/src/java/org/apache/ivy/util/url/AbstractURLHandler.java
index 2029724..a1184d2 100644
--- a/src/java/org/apache/ivy/util/url/AbstractURLHandler.java
+++ b/src/java/org/apache/ivy/util/url/AbstractURLHandler.java
@@ -31,6 +31,7 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import org.apache.ivy.Ivy;
+import org.apache.ivy.core.settings.TimeoutConstraint;
public abstract class AbstractURLHandler implements URLHandler {
@@ -39,28 +40,49 @@ public abstract class AbstractURLHandler implements URLHandler {
// the request method to use. TODO: don't use a static here
private static int requestMethod = REQUEST_METHOD_HEAD;
- public boolean isReachable(URL url) {
- return getURLInfo(url).isReachable();
+ @Override
+ public boolean isReachable(final URL url) {
+ return this.isReachable(url, null);
}
- public boolean isReachable(URL url, int timeout) {
- return getURLInfo(url, timeout).isReachable();
+ @Override
+ public boolean isReachable(final URL url, final int timeout) {
+ return this.isReachable(url, createTimeoutConstraints(timeout));
}
- public long getContentLength(URL url) {
- return getURLInfo(url).getContentLength();
+ @Override
+ public boolean isReachable(final URL url, final TimeoutConstraint timeoutConstraint) {
+ return this.getURLInfo(url, timeoutConstraint).isReachable();
}
- public long getContentLength(URL url, int timeout) {
- return getURLInfo(url, timeout).getContentLength();
+ @Override
+ public long getContentLength(final URL url) {
+ return this.getContentLength(url, null);
}
- public long getLastModified(URL url) {
- return getURLInfo(url).getLastModified();
+ @Override
+ public long getContentLength(final URL url, final int timeout) {
+ return this.getContentLength(url, createTimeoutConstraints(timeout));
}
- public long getLastModified(URL url, int timeout) {
- return getURLInfo(url, timeout).getLastModified();
+ @Override
+ public long getContentLength(final URL url, final TimeoutConstraint timeoutConstraint) {
+ return this.getURLInfo(url, timeoutConstraint).getContentLength();
+ }
+
+ @Override
+ public long getLastModified(final URL url) {
+ return this.getLastModified(url, null);
+ }
+
+ @Override
+ public long getLastModified(final URL url, final int timeout) {
+ return this.getLastModified(url, createTimeoutConstraints(timeout));
+ }
+
+ @Override
+ public long getLastModified(final URL url, final TimeoutConstraint timeoutConstraint) {
+ return this.getURLInfo(url, timeoutConstraint).getLastModified();
}
protected String getUserAgent() {
@@ -173,4 +195,17 @@ public abstract class AbstractURLHandler implements URLHandler {
return result;
}
+ protected static TimeoutConstraint createTimeoutConstraints(final int connectionTimeout) {
+ return new TimeoutConstraint() {
+ @Override
+ public int getConnectionTimeout() {
+ return connectionTimeout;
+ }
+
+ @Override
+ public int getReadTimeout() {
+ return -1;
+ }
+ };
+ }
}
http://git-wip-us.apache.org/repos/asf/ant-ivy/blob/6607bdcb/src/java/org/apache/ivy/util/url/BasicURLHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/ivy/util/url/BasicURLHandler.java b/src/java/org/apache/ivy/util/url/BasicURLHandler.java
index 97ee90f..342ad04 100644
--- a/src/java/org/apache/ivy/util/url/BasicURLHandler.java
+++ b/src/java/org/apache/ivy/util/url/BasicURLHandler.java
@@ -17,6 +17,11 @@
*/
package org.apache.ivy.util.url;
+import org.apache.ivy.core.settings.TimeoutConstraint;
+import org.apache.ivy.util.CopyProgressListener;
+import org.apache.ivy.util.FileUtil;
+import org.apache.ivy.util.Message;
+
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
@@ -29,10 +34,6 @@ import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
-import org.apache.ivy.util.CopyProgressListener;
-import org.apache.ivy.util.FileUtil;
-import org.apache.ivy.util.Message;
-
/**
*
*/
@@ -49,28 +50,37 @@ public class BasicURLHandler extends AbstractURLHandler {
}
}
- public URLInfo getURLInfo(URL url) {
- return getURLInfo(url, 0);
+ @Override
+ public URLInfo getURLInfo(final URL url) {
+ return this.getURLInfo(url, null);
+ }
+
+ @Override
+ public URLInfo getURLInfo(final URL url, final int timeout) {
+ return this.getURLInfo(url, createTimeoutConstraints(timeout));
}
- public URLInfo getURLInfo(URL url, int timeout) {
+ @Override
+ public URLInfo getURLInfo(final URL url, final TimeoutConstraint timeoutConstraint) {
// Install the IvyAuthenticator
if ("http".equals(url.getProtocol()) || "https".equals(url.getProtocol())) {
IvyAuthenticator.install();
}
-
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
+ final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
URLConnection con = null;
try {
- url = normalizeToURL(url);
- con = url.openConnection();
- con.setConnectTimeout(timeout);
+ final URL normalizedURL = normalizeToURL(url);
+ con = normalizedURL.openConnection();
+ con.setConnectTimeout(connectionTimeout);
+ con.setReadTimeout(readTimeout);
con.setRequestProperty("User-Agent", getUserAgent());
if (con instanceof HttpURLConnection) {
HttpURLConnection httpCon = (HttpURLConnection) con;
if (getRequestMethod() == URLHandler.REQUEST_METHOD_HEAD) {
httpCon.setRequestMethod("HEAD");
}
- if (checkStatusCode(url, httpCon)) {
+ if (checkStatusCode(normalizedURL, httpCon)) {
String bodyCharset = getCharSetFromContentType(con.getContentType());
return new URLInfo(true, httpCon.getContentLength(), con.getLastModified(),
bodyCharset);
@@ -101,8 +111,7 @@ public class BasicURLHandler extends AbstractURLHandler {
* Extract the charset from the Content-Type header string, or default to ISO-8859-1 as per
* rfc2616-sec3.html#sec3.7.1 .
*
- * @param contentType
- * the Content-Type header string
+ * @param contentType the Content-Type header string
* @return the charset as specified in the content type, or ISO-8859-1 if unspecified.
*/
public static String getCharSetFromContentType(String contentType) {
@@ -148,27 +157,37 @@ public class BasicURLHandler extends AbstractURLHandler {
return false;
}
- public InputStream openStream(URL url) throws IOException {
+ @Override
+ public InputStream openStream(final URL url) throws IOException {
+ return this.openStream(url, null);
+ }
+
+ @Override
+ public InputStream openStream(final URL url, final TimeoutConstraint timeoutConstraint) throws IOException {
// Install the IvyAuthenticator
if ("http".equals(url.getProtocol()) || "https".equals(url.getProtocol())) {
IvyAuthenticator.install();
}
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
+ final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
URLConnection conn = null;
try {
- url = normalizeToURL(url);
- conn = url.openConnection();
+ final URL normalizedURL = normalizeToURL(url);
+ conn = normalizedURL.openConnection();
+ conn.setConnectTimeout(connectionTimeout);
+ conn.setReadTimeout(readTimeout);
conn.setRequestProperty("User-Agent", getUserAgent());
conn.setRequestProperty("Accept-Encoding", "gzip,deflate");
if (conn instanceof HttpURLConnection) {
HttpURLConnection httpCon = (HttpURLConnection) conn;
- if (!checkStatusCode(url, httpCon)) {
- throw new IOException("The HTTP response code for " + url
+ if (!checkStatusCode(normalizedURL, httpCon)) {
+ throw new IOException("The HTTP response code for " + normalizedURL
+ " did not indicate a success." + " See log for more detail.");
}
}
InputStream inStream = getDecodingInputStream(conn.getContentEncoding(),
- conn.getInputStream());
+ conn.getInputStream());
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[BUFFER_SIZE];
@@ -182,30 +201,42 @@ public class BasicURLHandler extends AbstractURLHandler {
}
}
- public void download(URL src, File dest, CopyProgressListener l) throws IOException {
+ @Override
+ public void download(final URL src, final File dest, final CopyProgressListener l) throws IOException {
+ this.download(src, dest, l, null);
+ }
+
+ @Override
+ public void download(final URL src, final File dest, final CopyProgressListener listener,
+ final TimeoutConstraint timeoutConstraint) throws IOException {
+
// Install the IvyAuthenticator
if ("http".equals(src.getProtocol()) || "https".equals(src.getProtocol())) {
IvyAuthenticator.install();
}
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
+ final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
URLConnection srcConn = null;
try {
- src = normalizeToURL(src);
- srcConn = src.openConnection();
+ final URL normalizedURL = normalizeToURL(src);
+ srcConn = normalizedURL.openConnection();
+ srcConn.setConnectTimeout(connectionTimeout);
+ srcConn.setReadTimeout(readTimeout);
srcConn.setRequestProperty("User-Agent", getUserAgent());
srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate");
if (srcConn instanceof HttpURLConnection) {
HttpURLConnection httpCon = (HttpURLConnection) srcConn;
- if (!checkStatusCode(src, httpCon)) {
- throw new IOException("The HTTP response code for " + src
+ if (!checkStatusCode(normalizedURL, httpCon)) {
+ throw new IOException("The HTTP response code for " + normalizedURL
+ " did not indicate a success." + " See log for more detail.");
}
}
// do the download
InputStream inStream = getDecodingInputStream(srcConn.getContentEncoding(),
- srcConn.getInputStream());
- FileUtil.copy(inStream, dest, l);
+ srcConn.getInputStream());
+ FileUtil.copy(inStream, dest, listener);
// check content length only if content was not encoded
if (srcConn.getContentEncoding() == null) {
@@ -213,7 +244,7 @@ public class BasicURLHandler extends AbstractURLHandler {
if (contentLength != -1 && dest.length() != contentLength) {
dest.delete();
throw new IOException(
- "Downloaded file size doesn't match expected Content Length for " + src
+ "Downloaded file size doesn't match expected Content Length for " + normalizedURL
+ ". Please retry.");
}
}
@@ -228,7 +259,15 @@ public class BasicURLHandler extends AbstractURLHandler {
}
}
- public void upload(File source, URL dest, CopyProgressListener l) throws IOException {
+ @Override
+ public void upload(final File source, final URL dest, final CopyProgressListener l) throws IOException {
+ this.upload(source, dest, l);
+ }
+
+ @Override
+ public void upload(final File src, final URL dest, final CopyProgressListener listener,
+ final TimeoutConstraint timeoutConstraint) throws IOException {
+
if (!"http".equals(dest.getProtocol()) && !"https".equals(dest.getProtocol())) {
throw new UnsupportedOperationException(
"URL repository only support HTTP PUT at the moment");
@@ -237,32 +276,28 @@ public class BasicURLHandler extends AbstractURLHandler {
// Install the IvyAuthenticator
IvyAuthenticator.install();
+ final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
HttpURLConnection conn = null;
try {
- dest = normalizeToURL(dest);
- conn = (HttpURLConnection) dest.openConnection();
+ final URL normalizedDestURL = normalizeToURL(dest);
+ conn = (HttpURLConnection) normalizedDestURL.openConnection();
conn.setDoOutput(true);
+ conn.setConnectTimeout(connectionTimeout);
conn.setRequestMethod("PUT");
conn.setRequestProperty("User-Agent", getUserAgent());
conn.setRequestProperty("Content-type", "application/octet-stream");
- conn.setRequestProperty("Content-length", Long.toString(source.length()));
+ conn.setRequestProperty("Content-length", Long.toString(src.length()));
conn.setInstanceFollowRedirects(true);
- InputStream in = new FileInputStream(source);
- try {
- OutputStream os = conn.getOutputStream();
- FileUtil.copy(in, os, l);
- } finally {
- try {
- in.close();
- } catch (IOException e) {
- /* ignored */
- }
+ try (final InputStream in = new FileInputStream(src);) {
+ final OutputStream os = conn.getOutputStream();
+ FileUtil.copy(in, os, listener);
}
- validatePutStatusCode(dest, conn.getResponseCode(), conn.getResponseMessage());
+ validatePutStatusCode(normalizedDestURL, conn.getResponseCode(), conn.getResponseMessage());
} finally {
disconnect(conn);
}
+
}
private void disconnect(URLConnection con) {