mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of git://github.com/jclouds/jclouds
This commit is contained in:
commit
25dbce571d
18
README.txt
18
README.txt
|
@ -19,22 +19,26 @@
|
||||||
|
|
||||||
Overview:
|
Overview:
|
||||||
|
|
||||||
jclouds is an open source framework that helps you get started in the cloud
|
jclouds is an open source library that helps you get started in the cloud
|
||||||
and reuse your java and clojure development skills. Our api allows you to
|
and reuse your java and clojure development skills. Our api allows you to
|
||||||
freedom to use portable abstractions or cloud-specific features.
|
freedom to use portable abstractions or cloud-specific features. We have
|
||||||
|
two abstractions at the moment: compute and blobstore. compute helps you
|
||||||
|
bootstrap machines in the cloud. blobstore helps you manage key-value
|
||||||
|
data.
|
||||||
|
|
||||||
our current version is 1.0-beta-7
|
our current version is 1.0-beta-7
|
||||||
our dev version is 1.0-SNAPSHOT
|
our dev version is 1.0-SNAPSHOT
|
||||||
|
|
||||||
our compute api supports: ec2, gogrid, rackspace, rimuhosting, vcloud, trmk-ecloud,
|
our compute api supports: ec2, gogrid, cloudservers (rackspace), rimuhosting, vcloud,
|
||||||
trmk-vcloudexpress, eucalyptus, bluelock-vclouddirector,
|
trmk-ecloud, trmk-vcloudexpress, eucalyptus,
|
||||||
bluelock-vcloudexpress, slicehost, stub (in-memory)
|
bluelock-vclouddirector, slicehost, stub (in-memory)
|
||||||
|
|
||||||
* note * the pom dependency org.jclouds/jclouds-allcompute gives you access to
|
* note * the pom dependency org.jclouds/jclouds-allcompute gives you access to
|
||||||
to all of these providers
|
to all of these providers
|
||||||
|
|
||||||
our blobstore api supports: s3, rackspace, azure, atmos online, att synaptic,
|
our blobstore api supports: s3, cloudfiles (rackspace), azurestorage, atmosonline,
|
||||||
walrus, googlestorage, transient (in-memory), filesystem (on-disk)
|
synaptic, peer1-storage, walrus, googlestorage,
|
||||||
|
transient (in-memory), filesystem (on-disk)
|
||||||
|
|
||||||
* note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
|
* note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to
|
||||||
to all of these providers
|
to all of these providers
|
||||||
|
|
|
@ -36,6 +36,10 @@
|
||||||
<test.atmosonline.apiversion>1.3.0</test.atmosonline.apiversion>
|
<test.atmosonline.apiversion>1.3.0</test.atmosonline.apiversion>
|
||||||
<test.atmosonline.identity>FIXME</test.atmosonline.identity>
|
<test.atmosonline.identity>FIXME</test.atmosonline.identity>
|
||||||
<test.atmosonline.credential>FIXME</test.atmosonline.credential>
|
<test.atmosonline.credential>FIXME</test.atmosonline.credential>
|
||||||
|
<test.peer1-storage.endpoint>https://cloudonestorage.peer1.com</test.peer1-storage.endpoint>
|
||||||
|
<test.peer1-storage.apiversion>1.3.0</test.peer1-storage.apiversion>
|
||||||
|
<test.peer1-storage.identity>FIXME</test.peer1-storage.identity>
|
||||||
|
<test.peer1-storage.credential>FIXME</test.peer1-storage.credential>
|
||||||
<test.synaptic.endpoint>https://storage.synaptic.att.com</test.synaptic.endpoint>
|
<test.synaptic.endpoint>https://storage.synaptic.att.com</test.synaptic.endpoint>
|
||||||
<test.synaptic.apiversion>1.3.0</test.synaptic.apiversion>
|
<test.synaptic.apiversion>1.3.0</test.synaptic.apiversion>
|
||||||
<test.synaptic.identity>FIXME</test.synaptic.identity>
|
<test.synaptic.identity>FIXME</test.synaptic.identity>
|
||||||
|
@ -107,6 +111,22 @@
|
||||||
<name>test.atmosonline.credential</name>
|
<name>test.atmosonline.credential</name>
|
||||||
<value>${test.atmosonline.credential}</value>
|
<value>${test.atmosonline.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.peer1-storage.endpoint</name>
|
||||||
|
<value>${test.peer1-storage.endpoint}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.peer1-storage.apiversion</name>
|
||||||
|
<value>${test.peer1-storage.apiversion}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.peer1-storage.identity</name>
|
||||||
|
<value>${test.peer1-storage.identity}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.peer1-storage.credential</name>
|
||||||
|
<value>${test.peer1-storage.credential}</value>
|
||||||
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>test.synaptic.endpoint</name>
|
<name>test.synaptic.endpoint</name>
|
||||||
<value>${test.synaptic.endpoint}</value>
|
<value>${test.synaptic.endpoint}</value>
|
||||||
|
|
|
@ -29,6 +29,7 @@ import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.atmosonline.saas.binders.BindMetadataToHeaders;
|
import org.jclouds.atmosonline.saas.binders.BindMetadataToHeaders;
|
||||||
|
@ -103,6 +104,7 @@ public interface AtmosStorageAsyncClient {
|
||||||
@POST
|
@POST
|
||||||
@Path("/{directoryName}/")
|
@Path("/{directoryName}/")
|
||||||
@ExceptionParser(ReturnEndpointIfAlreadyExists.class)
|
@ExceptionParser(ReturnEndpointIfAlreadyExists.class)
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
@Consumes(MediaType.WILDCARD)
|
@Consumes(MediaType.WILDCARD)
|
||||||
ListenableFuture<URI> createDirectory(@PathParam("directoryName") String directoryName);
|
ListenableFuture<URI> createDirectory(@PathParam("directoryName") String directoryName);
|
||||||
|
|
||||||
|
|
|
@ -148,7 +148,7 @@ public class SignRequest implements HttpRequestFilter {
|
||||||
// TreeSet == Sort the headers alphabetically.
|
// TreeSet == Sort the headers alphabetically.
|
||||||
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
|
Set<String> headers = new TreeSet<String>(request.getHeaders().keySet());
|
||||||
for (String header : headers) {
|
for (String header : headers) {
|
||||||
if (header.startsWith("x-emc-")) {
|
if (header.startsWith("x-emc-") && !header.equals(AtmosStorageHeaders.SIGNATURE)) {
|
||||||
// Convert all header names to lowercase.
|
// Convert all header names to lowercase.
|
||||||
toSign.append(header.toLowerCase()).append(":");
|
toSign.append(header.toLowerCase()).append(":");
|
||||||
// For headers with values that span multiple lines, convert them into one line by
|
// For headers with values that span multiple lines, convert them into one line by
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class AtmosStorageAsyncClientTest extends RestClientTest<AtmosStorageAsyn
|
||||||
|
|
||||||
assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1");
|
assertRequestLineEquals(request, "POST https://accesspoint.atmosonline.com/rest/namespace/dir/ HTTP/1.1");
|
||||||
assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
|
assertNonPayloadHeadersEqual(request, HttpHeaders.ACCEPT + ": */*\n");
|
||||||
assertPayloadEquals(request, null, null, false);
|
assertPayloadEquals(request, "", "application/octet-stream", false);
|
||||||
|
|
||||||
assertResponseParserClassEquals(method, request, ParseURIFromListOrLocationHeaderIf20x.class);
|
assertResponseParserClassEquals(method, request, ParseURIFromListOrLocationHeaderIf20x.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
|
|
@ -89,7 +89,6 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
||||||
exception = new AuthorizationException(command.getRequest(), message);
|
exception = new AuthorizationException(command.getRequest(), message);
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
|
|
||||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||||
String path = command.getRequest().getEndpoint().getPath();
|
String path = command.getRequest().getEndpoint().getPath();
|
||||||
Matcher matcher = CONTAINER_PATH.matcher(path);
|
Matcher matcher = CONTAINER_PATH.matcher(path);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import static org.easymock.classextension.EasyMock.verify;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
import org.easymock.IArgumentMatcher;
|
import org.easymock.IArgumentMatcher;
|
||||||
|
import org.jclouds.azure.storage.AzureStorageResponseException;
|
||||||
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
|
import org.jclouds.azure.storage.filters.SharedKeyLiteAuthentication;
|
||||||
import org.jclouds.http.HttpCommand;
|
import org.jclouds.http.HttpCommand;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
@ -54,6 +55,14 @@ public class ParseAzureErrorFromXmlContentTest {
|
||||||
"Length Required", "text/html; charset=us-ascii", "<HTML><HEAD><TITLE>Length Required</TITLE>\r\n",
|
"Length Required", "text/html; charset=us-ascii", "<HTML><HEAD><TITLE>Length Required</TITLE>\r\n",
|
||||||
IllegalArgumentException.class);
|
IllegalArgumentException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test412WithTextHtmlHttpResponseException() {
|
||||||
|
assertCodeMakes("GET", URI
|
||||||
|
.create("https://jclouds.blob.core.windows.net/adriancole-blobstore2?restype=container&comp=list&prefix=apps/apps/apps/&include=metadata"), 412,
|
||||||
|
"HTTP/1.1 412 The condition specified using HTTP conditional header(s) is not met.", "application/xml", "<?xml version=\"1.0\" encoding=\"utf-8\"?><Error><Code>ConditionNotMet</Code><Message>The condition specified using HTTP conditional header(s) is not met.\nRequestId:921efcad-84bc-4e0a-863d-24810d1096e1\nTime:2010-11-04T15:03:07.8694513Z</Message></Error>",
|
||||||
|
AzureStorageResponseException.class);
|
||||||
|
}
|
||||||
|
|
||||||
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
|
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
|
||||||
String content, Class<? extends Exception> expected) {
|
String content, Class<? extends Exception> expected) {
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
"A clojure binding for the jclouds BlobStore.
|
"A clojure binding for the jclouds BlobStore.
|
||||||
|
|
||||||
Current supported services are:
|
Current supported services are:
|
||||||
[transient, filesystem, s3, azureblob, atmos, cloudfiles, walrus, googlestorage]
|
[transient, filesystem, s3, azureblob, atmos, cloudfiles, walrus,
|
||||||
|
googlestorage, synaptic, peer1-storage]
|
||||||
|
|
||||||
Here's a quick example of how to viewresources in rackspace
|
Here's a quick example of how to viewresources in rackspace
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
import org.jclouds.internal.ClassMethodArgs;
|
import org.jclouds.internal.ClassMethodArgs;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
import org.jclouds.rest.ResourceNotFoundException;
|
||||||
|
@ -57,7 +58,7 @@ public class SyncProxy implements InvocationHandler {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T proxy(Class<T> clazz, SyncProxy proxy) throws IllegalArgumentException, SecurityException,
|
public static <T> T proxy(Class<T> clazz, SyncProxy proxy) throws IllegalArgumentException, SecurityException,
|
||||||
NoSuchMethodException {
|
NoSuchMethodException {
|
||||||
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, proxy);
|
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class<?>[] { clazz }, proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,8 +73,8 @@ public class SyncProxy implements InvocationHandler {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public SyncProxy(Class<?> declaring, Object async,
|
public SyncProxy(Class<?> declaring, Object async,
|
||||||
@Named("sync") ConcurrentMap<ClassMethodArgs, Object> delegateMap, Map<Class<?>, Class<?>> sync2Async)
|
@Named("sync") ConcurrentMap<ClassMethodArgs, Object> delegateMap, Map<Class<?>, Class<?>> sync2Async)
|
||||||
throws SecurityException, NoSuchMethodException {
|
throws SecurityException, NoSuchMethodException {
|
||||||
this.delegateMap = delegateMap;
|
this.delegateMap = delegateMap;
|
||||||
this.delegate = async;
|
this.delegate = async;
|
||||||
this.declaring = declaring;
|
this.declaring = declaring;
|
||||||
|
@ -92,7 +93,7 @@ public class SyncProxy implements InvocationHandler {
|
||||||
Method delegatedMethod = delegate.getClass().getMethod(method.getName(), method.getParameterTypes());
|
Method delegatedMethod = delegate.getClass().getMethod(method.getName(), method.getParameterTypes());
|
||||||
if (!Arrays.equals(delegatedMethod.getExceptionTypes(), method.getExceptionTypes()))
|
if (!Arrays.equals(delegatedMethod.getExceptionTypes(), method.getExceptionTypes()))
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(String.format(
|
||||||
"method %s has different typed exceptions than delegated method %s", method, delegatedMethod));
|
"method %s has different typed exceptions than delegated method %s", method, delegatedMethod));
|
||||||
if (delegatedMethod.getReturnType().isAssignableFrom(ListenableFuture.class)) {
|
if (delegatedMethod.getReturnType().isAssignableFrom(ListenableFuture.class)) {
|
||||||
if (method.isAnnotationPresent(Timeout.class)) {
|
if (method.isAnnotationPresent(Timeout.class)) {
|
||||||
Timeout methodTimeout = method.getAnnotation(Timeout.class);
|
Timeout methodTimeout = method.getAnnotation(Timeout.class);
|
||||||
|
@ -124,7 +125,7 @@ public class SyncProxy implements InvocationHandler {
|
||||||
} else if (method.isAnnotationPresent(Delegate.class)) {
|
} else if (method.isAnnotationPresent(Delegate.class)) {
|
||||||
Class<?> asyncClass = sync2Async.get(method.getReturnType());
|
Class<?> asyncClass = sync2Async.get(method.getReturnType());
|
||||||
checkState(asyncClass != null, "please configure corresponding async class for " + method.getReturnType()
|
checkState(asyncClass != null, "please configure corresponding async class for " + method.getReturnType()
|
||||||
+ " in your RestClientModule");
|
+ " in your RestClientModule");
|
||||||
Object returnVal = delegateMap.get(new ClassMethodArgs(asyncClass, method, args));
|
Object returnVal = delegateMap.get(new ClassMethodArgs(asyncClass, method, args));
|
||||||
return returnVal;
|
return returnVal;
|
||||||
} else if (syncMethodMap.containsKey(method)) {
|
} else if (syncMethodMap.containsKey(method)) {
|
||||||
|
@ -132,7 +133,7 @@ public class SyncProxy implements InvocationHandler {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
return ((ListenableFuture<?>) methodMap.get(method).invoke(delegate, args)).get(timeoutMap.get(method),
|
return ((ListenableFuture<?>) methodMap.get(method).invoke(delegate, args)).get(timeoutMap.get(method),
|
||||||
TimeUnit.NANOSECONDS);
|
TimeUnit.NANOSECONDS);
|
||||||
} catch (ProvisionException e) {
|
} catch (ProvisionException e) {
|
||||||
throw throwTypedExceptionOrCause(method.getExceptionTypes(), e);
|
throw throwTypedExceptionOrCause(method.getExceptionTypes(), e);
|
||||||
} catch (ExecutionException e) {
|
} catch (ExecutionException e) {
|
||||||
|
@ -143,6 +144,7 @@ public class SyncProxy implements InvocationHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note this needs to be kept up-to-date with all top-level exceptions jclouds works against
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static Exception throwTypedExceptionOrCause(Class[] exceptionTypes, Exception exception) throws Exception {
|
public static Exception throwTypedExceptionOrCause(Class[] exceptionTypes, Exception exception) throws Exception {
|
||||||
for (Class type : exceptionTypes) {
|
for (Class type : exceptionTypes) {
|
||||||
|
@ -154,6 +156,7 @@ public class SyncProxy implements InvocationHandler {
|
||||||
Throwables.propagateIfInstanceOf(exception, IllegalStateException.class);
|
Throwables.propagateIfInstanceOf(exception, IllegalStateException.class);
|
||||||
Throwables.propagateIfInstanceOf(exception, AuthorizationException.class);
|
Throwables.propagateIfInstanceOf(exception, AuthorizationException.class);
|
||||||
Throwables.propagateIfInstanceOf(exception, ResourceNotFoundException.class);
|
Throwables.propagateIfInstanceOf(exception, ResourceNotFoundException.class);
|
||||||
|
Throwables.propagateIfInstanceOf(exception, HttpResponseException.class);
|
||||||
Throwables.throwCause(exception, true);
|
Throwables.throwCause(exception, true);
|
||||||
return exception;
|
return exception;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,10 @@ import static com.google.common.io.Closeables.closeQuietly;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
import org.jclouds.rest.InvocationContext;
|
import org.jclouds.rest.InvocationContext;
|
||||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
@ -41,6 +39,7 @@ import org.xml.sax.XMLReader;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This object will parse the body of an HttpResponse and return the result of type <T> back to the
|
* This object will parse the body of an HttpResponse and return the result of type <T> back to the
|
||||||
|
@ -52,8 +51,6 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
||||||
|
|
||||||
private final XMLReader parser;
|
private final XMLReader parser;
|
||||||
private final HandlerWithResult<T> handler;
|
private final HandlerWithResult<T> handler;
|
||||||
@Resource
|
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
private HttpRequest request;
|
private HttpRequest request;
|
||||||
|
|
||||||
public static interface Factory {
|
public static interface Factory {
|
||||||
|
@ -71,7 +68,7 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
||||||
checkNotNull(from, "http response");
|
checkNotNull(from, "http response");
|
||||||
checkNotNull(from.getPayload(), "payload in " + from);
|
checkNotNull(from.getPayload(), "payload in " + from);
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
return addRequestDetailsToException(e);
|
return addDetailsAndPropagate(from, e);
|
||||||
}
|
}
|
||||||
if (from.getStatusCode() >= 300)
|
if (from.getStatusCode() >= 300)
|
||||||
return convertStreamToStringAndParse(from);
|
return convertStreamToStringAndParse(from);
|
||||||
|
@ -82,7 +79,7 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
||||||
try {
|
try {
|
||||||
return parse(Utils.toStringAndClose(from.getPayload().getInput()));
|
return parse(Utils.toStringAndClose(from.getPayload().getInput()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return addRequestDetailsToException(e);
|
return addDetailsAndPropagate(from, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +88,7 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
||||||
checkNotNull(from, "xml string");
|
checkNotNull(from, "xml string");
|
||||||
checkArgument(from.indexOf('<') >= 0, String.format("not an xml document [%s] ", from));
|
checkArgument(from.indexOf('<') >= 0, String.format("not an xml document [%s] ", from));
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
return addRequestDetailsToException(e);
|
return addDetailsAndPropagate(null, e);
|
||||||
}
|
}
|
||||||
return parse(new InputSource(new StringReader(from)));
|
return parse(new InputSource(new StringReader(from)));
|
||||||
}
|
}
|
||||||
|
@ -113,31 +110,39 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
|
||||||
parser.parse(from);
|
parser.parse(from);
|
||||||
return getHandler().getResult();
|
return getHandler().getResult();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return addRequestDetailsToException(e);
|
return addDetailsAndPropagate(null, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private T addRequestDetailsToException(Exception e) {
|
public T addDetailsAndPropagate(HttpResponse response, Exception e) {
|
||||||
String exceptionMessage = e.getMessage();
|
StringBuilder message = new StringBuilder();
|
||||||
|
if (request != null) {
|
||||||
|
message.append("request: ").append(request.getRequestLine());
|
||||||
|
}
|
||||||
|
if (response != null) {
|
||||||
|
if (message.length() != 0)
|
||||||
|
message.append("; ");
|
||||||
|
message.append("response: ").append(response.getStatusLine());
|
||||||
|
}
|
||||||
if (e instanceof SAXParseException) {
|
if (e instanceof SAXParseException) {
|
||||||
SAXParseException parseException = (SAXParseException) e;
|
SAXParseException parseException = (SAXParseException) e;
|
||||||
String systemId = parseException.getSystemId();
|
String systemId = parseException.getSystemId();
|
||||||
if (systemId == null) {
|
if (systemId == null) {
|
||||||
systemId = "";
|
systemId = "";
|
||||||
}
|
}
|
||||||
exceptionMessage = String.format("Error on line %d of document %s: %s", systemId, parseException
|
if (message.length() != 0)
|
||||||
.getLineNumber(), parseException.getMessage());
|
message.append("; ");
|
||||||
|
message.append(String.format("error at %d:%d in document %s", parseException.getColumnNumber(),
|
||||||
|
parseException.getLineNumber(), systemId));
|
||||||
}
|
}
|
||||||
if (request != null) {
|
if (message.length() != 0) {
|
||||||
StringBuilder message = new StringBuilder();
|
message.append("; cause: ").append(e.toString());
|
||||||
message.append("Error parsing input for ").append(request.getRequestLine()).append(": ");
|
|
||||||
message.append(exceptionMessage);
|
|
||||||
logger.error(e, message.toString());
|
|
||||||
throw new RuntimeException(message.toString(), e);
|
throw new RuntimeException(message.toString(), e);
|
||||||
} else {
|
} else {
|
||||||
logger.error(e, exceptionMessage.toString());
|
Throwables.propagate(e);
|
||||||
throw new RuntimeException(exceptionMessage.toString(), e);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HandlerWithResult<T> getHandler() {
|
public HandlerWithResult<T> getHandler() {
|
||||||
|
|
|
@ -33,7 +33,7 @@ import static com.google.common.collect.Sets.difference;
|
||||||
import static com.google.common.collect.Sets.newHashSet;
|
import static com.google.common.collect.Sets.newHashSet;
|
||||||
import static com.google.common.collect.Sets.newTreeSet;
|
import static com.google.common.collect.Sets.newTreeSet;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static javax.ws.rs.core.HttpHeaders.ACCEPT;
|
import static javax.ws.rs.core.HttpHeaders.*;
|
||||||
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
|
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
|
||||||
import static javax.ws.rs.core.HttpHeaders.HOST;
|
import static javax.ws.rs.core.HttpHeaders.HOST;
|
||||||
import static org.jclouds.http.HttpUtils.makeQueryLine;
|
import static org.jclouds.http.HttpUtils.makeQueryLine;
|
||||||
|
@ -128,6 +128,7 @@ import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.LinkedHashMultimap;
|
import com.google.common.collect.LinkedHashMultimap;
|
||||||
import com.google.common.collect.LinkedListMultimap;
|
import com.google.common.collect.LinkedListMultimap;
|
||||||
import com.google.common.collect.MapMaker;
|
import com.google.common.collect.MapMaker;
|
||||||
|
@ -470,6 +471,9 @@ public class RestAnnotationProcessor<T> {
|
||||||
payload = new MultipartForm(BOUNDARY, parts);
|
payload = new MultipartForm(BOUNDARY, parts);
|
||||||
} else if (formParams.size() > 0) {
|
} else if (formParams.size() > 0) {
|
||||||
payload = Payloads.newUrlEncodedFormPayload(formParams, skips);
|
payload = Payloads.newUrlEncodedFormPayload(formParams, skips);
|
||||||
|
} else if (headers.containsKey(CONTENT_TYPE)) {
|
||||||
|
payload = Payloads.newByteArrayPayload(new byte[]{});
|
||||||
|
payload.getContentMetadata().setContentType(Iterables.get(headers.get(CONTENT_TYPE),0));
|
||||||
}
|
}
|
||||||
if (payload != null) {
|
if (payload != null) {
|
||||||
request.setPayload(payload);
|
request.setPayload(payload);
|
||||||
|
|
|
@ -104,7 +104,11 @@ synaptic.contextbuilder=org.jclouds.atmosonline.saas.AtmosStorageContextBuilder
|
||||||
synaptic.endpoint=https://storage.synaptic.att.com
|
synaptic.endpoint=https://storage.synaptic.att.com
|
||||||
synaptic.apiversion=1.3.0
|
synaptic.apiversion=1.3.0
|
||||||
|
|
||||||
# TODO peer1 and hostedsolutions use atmos
|
peer1-storage.contextbuilder=org.jclouds.atmosonline.saas.AtmosStorageContextBuilder
|
||||||
|
peer1-storage.endpoint=https://storage.synaptic.att.com
|
||||||
|
peer1-storage.apiversion=1.3.0
|
||||||
|
|
||||||
|
# TODO hostedsolutions use atmos
|
||||||
|
|
||||||
cloudfiles.contextbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesContextBuilder
|
cloudfiles.contextbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesContextBuilder
|
||||||
cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder
|
cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder
|
||||||
|
|
|
@ -373,10 +373,22 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
|
||||||
@POST
|
@POST
|
||||||
@Path("")
|
@Path("")
|
||||||
public void post(HttpRequestOptions options);
|
public void post(HttpRequestOptions options);
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("")
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
public void post();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testHttpRequestOptionsPayloadParam() throws SecurityException, NoSuchMethodException, IOException {
|
public void testHttpRequestOptionsPayloadParam() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
|
Method method = TestPayloadParamVarargs.class.getMethod("post");
|
||||||
|
HttpRequest request = factory(TestQuery.class).createRequest(method);
|
||||||
|
assertRequestLineEquals(request, "POST http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1");
|
||||||
|
assertNonPayloadHeadersEqual(request, "");
|
||||||
|
assertPayloadEquals(request, "", "application/octet-stream", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testHttpRequestWithOnlyContentType() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
Method method = TestPayloadParamVarargs.class.getMethod("post", HttpRequestOptions.class);
|
Method method = TestPayloadParamVarargs.class.getMethod("post", HttpRequestOptions.class);
|
||||||
verifyTestPostOptions(method);
|
verifyTestPostOptions(method);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,9 +33,10 @@
|
||||||
<properties>
|
<properties>
|
||||||
<!-- when instances are hung, open a ticket and add here -->
|
<!-- when instances are hung, open a ticket and add here -->
|
||||||
<jclouds.compute.blacklist.nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist.nodes>
|
<jclouds.compute.blacklist.nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist.nodes>
|
||||||
<test.servermanager-compute.endpoint>https://servermanager-compute.com</test.servermanager-compute.endpoint>
|
<test.servermanager.identity>FIXME</test.servermanager.identity>
|
||||||
<test.servermanager-compute.apiversion>1.0</test.servermanager-compute.apiversion>
|
<test.servermanager.endpoint>https://servermanager.com</test.servermanager.endpoint>
|
||||||
<test.servermanager-compute.identity>FIXME</test.servermanager-compute.identity>
|
<test.servermanager.apiversion>1.0</test.servermanager.apiversion>
|
||||||
|
<test.servermanager.identity>FIXME</test.servermanager.identity>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -95,16 +96,16 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
<property>
|
||||||
<name>test.servermanager-compute.endpoint</name>
|
<name>test.servermanager.endpoint</name>
|
||||||
<value>${test.servermanager-compute.endpoint}</value>
|
<value>${test.servermanager.endpoint}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>test.servermanager-compute.apiversion</name>
|
<name>test.servermanager.apiversion</name>
|
||||||
<value>${test.servermanager-compute.apiversion}</value>
|
<value>${test.servermanager.apiversion}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>test.servermanager-compute.identity</name>
|
<name>test.servermanager.identity</name>
|
||||||
<value>${test.servermanager-compute.identity}</value>
|
<value>${test.servermanager.identity}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>jclouds.compute.blacklist.nodes</name>
|
<name>jclouds.compute.blacklist.nodes</name>
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.util.Properties;
|
||||||
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
|
||||||
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
import org.jclouds.logging.jdk.config.JDKLoggingModule;
|
||||||
import org.jclouds.vcloud.VCloudExpressContextBuilder;
|
import org.jclouds.vcloud.VCloudExpressContextBuilder;
|
||||||
import org.jclouds.vcloud.terremark.compute.config.TerremarkVCloudComputeServiceContextModule;
|
import org.jclouds.vcloud.terremark.compute.config.TerremarkECloudComputeServiceContextModule;
|
||||||
import org.jclouds.vcloud.terremark.config.TerremarkECloudRestClientModule;
|
import org.jclouds.vcloud.terremark.config.TerremarkECloudRestClientModule;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
@ -52,7 +52,7 @@ public class TerremarkECloudContextBuilder extends VCloudExpressContextBuilder {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addContextModule(List<Module> modules) {
|
protected void addContextModule(List<Module> modules) {
|
||||||
modules.add(new TerremarkVCloudComputeServiceContextModule());
|
modules.add(new TerremarkECloudComputeServiceContextModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.vcloud.terremark;
|
||||||
|
|
||||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
|
import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED;
|
||||||
import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_NAME;
|
import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_NAME;
|
||||||
import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_VERSION;
|
import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_VERSION;
|
||||||
|
|
||||||
|
@ -39,6 +40,8 @@ public class TerremarkECloudPropertiesBuilder extends TerremarkVCloudPropertiesB
|
||||||
properties.setProperty(PROPERTY_ENDPOINT, "https://services.enterprisecloud.terremark.com/api");
|
properties.setProperty(PROPERTY_ENDPOINT, "https://services.enterprisecloud.terremark.com/api");
|
||||||
properties.setProperty(PROPERTY_TERREMARK_EXTENSION_NAME, "eCloudExtensions");
|
properties.setProperty(PROPERTY_TERREMARK_EXTENSION_NAME, "eCloudExtensions");
|
||||||
properties.setProperty(PROPERTY_TERREMARK_EXTENSION_VERSION, "2.5");
|
properties.setProperty(PROPERTY_TERREMARK_EXTENSION_VERSION, "2.5");
|
||||||
|
// for some reason the centos template is very slow to deploy
|
||||||
|
properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED, 720l * 1000l + "");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed 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.jclouds.vcloud.terremark.compute.config;
|
||||||
|
|
||||||
|
import static org.jclouds.compute.domain.OsFamily.CENTOS;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class TerremarkECloudComputeServiceContextModule extends TerremarkVCloudComputeServiceContextModule {
|
||||||
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
|
return template.osFamily(CENTOS);
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,9 +44,9 @@ import org.testng.annotations.Test;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", enabled = false, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest")
|
@Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest")
|
||||||
public class TerremarkECloudComputeServiceLiveTestDisabled extends BaseComputeServiceLiveTest {
|
public class TerremarkECloudComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
public TerremarkECloudComputeServiceLiveTestDisabled() {
|
public TerremarkECloudComputeServiceLiveTest() {
|
||||||
provider = "trmk-ecloud";
|
provider = "trmk-ecloud";
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue