mirror of https://github.com/apache/jclouds.git
fixed NPE when httpresponseexception is caused by an io exception
This commit is contained in:
parent
a168683851
commit
d884978a98
|
@ -18,6 +18,12 @@
|
|||
*/
|
||||
package org.jclouds.aws.s3.functions;
|
||||
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.base.Throwables.getCausalChain;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
import static com.google.common.collect.Iterables.size;
|
||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||
import static org.jclouds.util.Utils.propagateOrNull;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -26,11 +32,8 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.aws.AWSResponseException;
|
||||
import org.jclouds.blobstore.ContainerNotFoundException;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -40,28 +43,21 @@ import com.google.common.collect.Iterables;
|
|||
public class ReturnTrueOn404OrNotFoundFalseIfNotEmpty implements Function<Exception, Boolean> {
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
List<Throwable> throwables = Throwables.getCausalChain(from);
|
||||
List<Throwable> throwables = getCausalChain(from);
|
||||
|
||||
Iterable<AWSResponseException> matchingAWSResponseException = Iterables.filter(throwables,
|
||||
AWSResponseException.class);
|
||||
if (Iterables.size(matchingAWSResponseException) >= 1) {
|
||||
if (Iterables.get(matchingAWSResponseException, 0).getError().getCode().equals(
|
||||
"BucketNotEmpty"))
|
||||
Iterable<AWSResponseException> matchingAWSResponseException = filter(throwables, AWSResponseException.class);
|
||||
if (size(matchingAWSResponseException) >= 1 && get(matchingAWSResponseException, 0).getError() != null) {
|
||||
if (get(matchingAWSResponseException, 0).getError().getCode().equals("BucketNotEmpty"))
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterable<ContainerNotFoundException> matchingContainerNotFoundException = Iterables.filter(
|
||||
throwables, ContainerNotFoundException.class);
|
||||
if (Iterables.size(matchingContainerNotFoundException) >= 1) {
|
||||
Iterable<ContainerNotFoundException> matchingContainerNotFoundException = filter(throwables,
|
||||
ContainerNotFoundException.class);
|
||||
if (size(matchingContainerNotFoundException) >= 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Iterable<HttpResponseException> matchingHttpResponseException = Iterables.filter(throwables,
|
||||
HttpResponseException.class);
|
||||
if (Iterables.size(matchingHttpResponseException) >= 1) {
|
||||
if (Iterables.get(matchingHttpResponseException, 0).getResponse().getStatusCode() == 404)
|
||||
if (returnValueOnCodeOrNull(from, true, equalTo(404)) != null)
|
||||
return true;
|
||||
}
|
||||
|
||||
return Boolean.class.cast(propagateOrNull(from));
|
||||
}
|
||||
|
|
|
@ -20,8 +20,12 @@ package org.jclouds.http;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Throwables.getCausalChain;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static com.google.common.collect.Iterables.any;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
import static com.google.common.collect.Iterables.size;
|
||||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static com.google.common.collect.Sets.newTreeSet;
|
||||
import static com.google.common.io.ByteStreams.toByteArray;
|
||||
|
@ -562,4 +566,13 @@ public class HttpUtils {
|
|||
"After wiring, the request has neither chunked encoding nor content length: " + request);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> T returnValueOnCodeOrNull(Exception from, T value, Predicate<Integer> codePredicate) {
|
||||
Iterable<HttpResponseException> throwables = filter(getCausalChain(from), HttpResponseException.class);
|
||||
if (size(throwables) >= 1 && get(throwables, 0).getResponse() != null
|
||||
&& codePredicate.apply(get(throwables, 0).getResponse().getStatusCode())) {
|
||||
return value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
*/
|
||||
package org.jclouds.http.functions;
|
||||
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||
import static org.jclouds.util.Utils.propagateOrNull;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
/**
|
||||
|
@ -34,13 +34,8 @@ import com.google.common.base.Function;
|
|||
public class ReturnFalseOn404 implements Function<Exception, Boolean> {
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
if (from instanceof HttpResponseException) {
|
||||
HttpResponseException responseException = (HttpResponseException) from;
|
||||
if (responseException.getResponse().getStatusCode() == 404) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Boolean.class.cast(propagateOrNull(from));
|
||||
Boolean returnVal = returnValueOnCodeOrNull(from, false, equalTo(404));
|
||||
return returnVal != null ? returnVal : Boolean.class.cast(propagateOrNull(from));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,27 +18,20 @@
|
|||
*/
|
||||
package org.jclouds.http.functions;
|
||||
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||
import static org.jclouds.util.Utils.propagateOrNull;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
@Singleton
|
||||
public class ReturnTrueOn404 implements Function<Exception, Boolean> {
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
Iterable<HttpResponseException> throwables = Iterables.filter(
|
||||
Throwables.getCausalChain(from), HttpResponseException.class);
|
||||
if (Iterables.size(throwables) >= 1
|
||||
&& Iterables.get(throwables, 0).getResponse().getStatusCode() == 404) {
|
||||
return true;
|
||||
}
|
||||
return Boolean.class.cast(propagateOrNull(from));
|
||||
Boolean returnVal = returnValueOnCodeOrNull(from, true, equalTo(404));
|
||||
return returnVal != null ? returnVal : Boolean.class.cast(propagateOrNull(from));
|
||||
}
|
||||
|
||||
}
|
|
@ -67,14 +67,17 @@ import com.google.inject.name.Names;
|
|||
import com.google.inject.util.Types;
|
||||
|
||||
/**
|
||||
* Creates {@link RestContext} or {@link Injector} instances based on the most commonly requested
|
||||
* arguments.
|
||||
* Creates {@link RestContext} or {@link Injector} instances based on the most
|
||||
* commonly requested arguments.
|
||||
* <p/>
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
|
||||
* Note that Threadsafe objects will be bound as singletons to the Injector or
|
||||
* Context provided.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
|
||||
* If no <code>Module</code>s are specified, the default
|
||||
* {@link JDKLoggingModule logging} and
|
||||
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be
|
||||
* installed.
|
||||
*
|
||||
* @author Adrian Cole, Andrew Newdigate
|
||||
* @see RestContext
|
||||
|
@ -97,20 +100,16 @@ public class RestContextBuilder<S, A> {
|
|||
bind(String.class).annotatedWith(Provider.class).toInstance(
|
||||
checkNotNull(toBind.getProperty(PROPERTY_PROVIDER), PROPERTY_PROVIDER));
|
||||
bind(URI.class).annotatedWith(Provider.class).toInstance(
|
||||
URI.create(checkNotNull(toBind.getProperty(PROPERTY_ENDPOINT),
|
||||
PROPERTY_ENDPOINT)));
|
||||
URI.create(checkNotNull(toBind.getProperty(PROPERTY_ENDPOINT), PROPERTY_ENDPOINT)));
|
||||
if (toBind.containsKey(PROPERTY_API))
|
||||
bind(String.class).annotatedWith(Api.class).toInstance(
|
||||
toBind.getProperty(PROPERTY_API));
|
||||
bind(String.class).annotatedWith(Api.class).toInstance(toBind.getProperty(PROPERTY_API));
|
||||
if (toBind.containsKey(PROPERTY_API_VERSION))
|
||||
bind(String.class).annotatedWith(ApiVersion.class).toInstance(
|
||||
toBind.getProperty(PROPERTY_API_VERSION));
|
||||
bind(String.class).annotatedWith(ApiVersion.class).toInstance(toBind.getProperty(PROPERTY_API_VERSION));
|
||||
if (toBind.containsKey(PROPERTY_IDENTITY))
|
||||
bind(String.class).annotatedWith(Identity.class).toInstance(
|
||||
checkNotNull(toBind.getProperty(PROPERTY_IDENTITY), PROPERTY_IDENTITY));
|
||||
if (toBind.containsKey(PROPERTY_CREDENTIAL))
|
||||
bind(String.class).annotatedWith(Credential.class).toInstance(
|
||||
toBind.getProperty(PROPERTY_CREDENTIAL));
|
||||
bind(String.class).annotatedWith(Credential.class).toInstance(toBind.getProperty(PROPERTY_CREDENTIAL));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -120,8 +119,7 @@ public class RestContextBuilder<S, A> {
|
|||
protected Class<S> syncClientType;
|
||||
|
||||
@Inject
|
||||
public RestContextBuilder(Class<S> syncClientClass, Class<A> asyncClientClass,
|
||||
Properties properties) {
|
||||
public RestContextBuilder(Class<S> syncClientClass, Class<A> asyncClientClass, Properties properties) {
|
||||
this.asyncClientType = checkNotNull(asyncClientClass, "asyncClientType");
|
||||
this.syncClientType = checkNotNull(syncClientClass, "syncClientType");
|
||||
this.properties = checkNotNull(properties, "properties");
|
||||
|
@ -184,10 +182,10 @@ public class RestContextBuilder<S, A> {
|
|||
@Override
|
||||
protected void configure() {
|
||||
bind(
|
||||
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContext.class,
|
||||
syncClientType, asyncClientType))).to(
|
||||
TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class,
|
||||
syncClientType, asyncClientType))).in(Scopes.SINGLETON);
|
||||
(TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContext.class, syncClientType,
|
||||
asyncClientType))).to(
|
||||
TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, syncClientType, asyncClientType)))
|
||||
.in(Scopes.SINGLETON);
|
||||
|
||||
}
|
||||
|
||||
|
@ -260,9 +258,9 @@ public class RestContextBuilder<S, A> {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public RestContext<S, A> buildContext() {
|
||||
public <T extends RestContext<S, A>> T buildContext() {
|
||||
Injector injector = buildInjector();
|
||||
return (RestContext<S, A>) injector.getInstance(Key.get(Types.newParameterizedType(
|
||||
RestContext.class, syncClientType, asyncClientType)));
|
||||
return (T) injector.getInstance(Key.get(Types.newParameterizedType(RestContext.class, syncClientType,
|
||||
asyncClientType)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,10 +27,10 @@ import javax.inject.Inject;
|
|||
import org.jclouds.lifecycle.Closer;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RestContext;
|
||||
import org.jclouds.rest.Utils;
|
||||
import org.jclouds.rest.annotations.ApiVersion;
|
||||
import org.jclouds.rest.annotations.Identity;
|
||||
import org.jclouds.rest.annotations.Provider;
|
||||
import org.jclouds.rest.Utils;
|
||||
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
|
@ -55,9 +55,9 @@ public class RestContextImpl<S, A> implements RestContext<S, A> {
|
|||
private final Utils utils;
|
||||
|
||||
@Inject
|
||||
RestContextImpl(Closer closer, Utils utils, Injector injector, TypeLiteral<S> syncApi,
|
||||
TypeLiteral<A> asyncApi, @Provider URI endpoint, @Provider String provider,
|
||||
@Identity String identity, @ApiVersion String apiVersion) {
|
||||
protected RestContextImpl(Closer closer, Utils utils, Injector injector, TypeLiteral<S> syncApi,
|
||||
TypeLiteral<A> asyncApi, @Provider URI endpoint, @Provider String provider, @Identity String identity,
|
||||
@ApiVersion String apiVersion) {
|
||||
this.utils = utils;
|
||||
this.asyncApi = injector.getInstance(Key.get(asyncApi));
|
||||
this.syncApi = injector.getInstance(Key.get(syncApi));
|
||||
|
@ -168,7 +168,7 @@ public class RestContextImpl<S, A> implements RestContext<S, A> {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RestContextImpl [provider=" + provider + ", endpoint=" + endpoint + ", apiVersion="
|
||||
+ apiVersion + ", identity=" + identity + "]";
|
||||
return "RestContextImpl [provider=" + provider + ", endpoint=" + endpoint + ", apiVersion=" + apiVersion
|
||||
+ ", identity=" + identity + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,13 @@
|
|||
*/
|
||||
package org.jclouds.util;
|
||||
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.classextension.EasyMock.createMock;
|
||||
import static org.easymock.classextension.EasyMock.replay;
|
||||
import static org.jclouds.http.HttpUtils.changeSchemeHostAndPortTo;
|
||||
import static org.jclouds.http.HttpUtils.parseQueryToMap;
|
||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.net.URI;
|
||||
|
@ -35,6 +37,8 @@ import javax.ws.rs.core.UriBuilder;
|
|||
import org.jboss.resteasy.specimpl.UriBuilderImpl;
|
||||
import org.jclouds.PerformanceTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -77,24 +81,21 @@ public class HttpUtilsTest extends PerformanceTest {
|
|||
assert parsedMap.keySet().size() == 1 : "Expected 1 key, found: " + parsedMap.keySet().size();
|
||||
assert parsedMap.keySet().contains("v") : "Expected v to be a part of the keys";
|
||||
String valueForV = Iterables.getOnlyElement(parsedMap.get("v"));
|
||||
assert valueForV.equals("1.3") : "Expected the value for 'v' to be '1.3', found: "
|
||||
+ valueForV;
|
||||
assert valueForV.equals("1.3") : "Expected the value for 'v' to be '1.3', found: " + valueForV;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseQueryToMapMultiParam() {
|
||||
Multimap<String, String> parsedMap = parseQueryToMap("v=1.3&sig=123");
|
||||
assert parsedMap.keySet().size() == 2 : "Expected 2 keys, found: "
|
||||
+ parsedMap.keySet().size();
|
||||
assert parsedMap.keySet().size() == 2 : "Expected 2 keys, found: " + parsedMap.keySet().size();
|
||||
assert parsedMap.keySet().contains("v") : "Expected v to be a part of the keys";
|
||||
assert parsedMap.keySet().contains("sig") : "Expected sig to be a part of the keys";
|
||||
String valueForV = Iterables.getOnlyElement(parsedMap.get("v"));
|
||||
assert valueForV.equals("1.3") : "Expected the value for 'v' to be '1.3', found: "
|
||||
+ valueForV;
|
||||
assert valueForV.equals("1.3") : "Expected the value for 'v' to be '1.3', found: " + valueForV;
|
||||
String valueForSig = Iterables.getOnlyElement(parsedMap.get("sig"));
|
||||
assert valueForSig.equals("123") : "Expected the value for 'v' to be '123', found: "
|
||||
+ valueForSig;
|
||||
assert valueForSig.equals("123") : "Expected the value for 'v' to be '123', found: " + valueForSig;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChangeSchemeHostAndPortTo() {
|
||||
HttpRequest request = createMock(HttpRequest.class);
|
||||
|
@ -125,17 +126,13 @@ public class HttpUtilsTest extends PerformanceTest {
|
|||
}
|
||||
|
||||
public void testAtmos() {
|
||||
URI creds = HttpUtils
|
||||
.createUri("compute://domain/user:Base64==@azureblob/container-hyphen/prefix");
|
||||
assertEquals(creds, URI
|
||||
.create("compute://domain%2Fuser:Base64%3D%3D@azureblob/container-hyphen/prefix"));
|
||||
URI creds = HttpUtils.createUri("compute://domain/user:Base64==@azureblob/container-hyphen/prefix");
|
||||
assertEquals(creds, URI.create("compute://domain%2Fuser:Base64%3D%3D@azureblob/container-hyphen/prefix"));
|
||||
}
|
||||
|
||||
public void testAzure() {
|
||||
URI creds = HttpUtils
|
||||
.createUri("compute://identity:Base64==@azureblob/container-hyphen/prefix");
|
||||
assertEquals(creds, URI
|
||||
.create("compute://identity:Base64==@azureblob/container-hyphen/prefix"));
|
||||
URI creds = HttpUtils.createUri("compute://identity:Base64==@azureblob/container-hyphen/prefix");
|
||||
assertEquals(creds, URI.create("compute://identity:Base64==@azureblob/container-hyphen/prefix"));
|
||||
}
|
||||
|
||||
public void testHosting() {
|
||||
|
@ -181,13 +178,18 @@ public class HttpUtilsTest extends PerformanceTest {
|
|||
}
|
||||
|
||||
public void testPercent() {
|
||||
URI creds = HttpUtils
|
||||
.createUri("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%.txt");
|
||||
URI creds = HttpUtils.createUri("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%.txt");
|
||||
|
||||
assertEquals(
|
||||
creds,
|
||||
URI
|
||||
.create("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%25.txt"));
|
||||
assertEquals(creds, URI.create("https://jclouds.blob.core.windows.net/jclouds-getpath/write-tests/file1%25.txt"));
|
||||
|
||||
}
|
||||
|
||||
public void test404() {
|
||||
Exception from = new HttpResponseException("message", null, new HttpResponse(404, "not found", null));
|
||||
assertEquals(returnValueOnCodeOrNull(from, true, equalTo(404)), Boolean.TRUE);
|
||||
}
|
||||
public void testNullResponse() {
|
||||
Exception from = new HttpResponseException("message", null, null);
|
||||
assertEquals(returnValueOnCodeOrNull(from, true, equalTo(404)), null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,23 +18,20 @@
|
|||
*/
|
||||
package org.jclouds.rackspace.cloudfiles.functions;
|
||||
|
||||
import static com.google.common.base.Predicates.in;
|
||||
import static com.google.common.collect.ImmutableSet.of;
|
||||
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
|
||||
import static org.jclouds.util.Utils.propagateOrNull;
|
||||
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
@Singleton
|
||||
public class ReturnTrueOn404FalseOn409 implements Function<Exception, Boolean> {
|
||||
|
||||
public Boolean apply(Exception from) {
|
||||
if (from instanceof HttpResponseException) {
|
||||
HttpResponseException responseException = (HttpResponseException) from;
|
||||
if (responseException.getResponse().getStatusCode() == 404) {
|
||||
return true;
|
||||
} else if (responseException.getResponse().getStatusCode() == 409) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return Boolean.class.cast(propagateOrNull(from));
|
||||
Boolean returnVal = returnValueOnCodeOrNull(from, true, in(of(404, 409)));
|
||||
return returnVal != null ? returnVal : Boolean.class.cast(propagateOrNull(from));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue