mirror of https://github.com/apache/jclouds.git
Merge branch 'master' of github.com:jclouds/jclouds
This commit is contained in:
commit
8b716a06d8
24
README.txt
24
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-8
|
||||||
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
|
||||||
|
@ -98,13 +102,13 @@ Compute Example (Clojure):
|
||||||
(run-nodes "mycluster" 2))
|
(run-nodes "mycluster" 2))
|
||||||
|
|
||||||
Downloads:
|
Downloads:
|
||||||
* distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-7.zip
|
* distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-8.zip
|
||||||
* maven repo: http://jclouds.googlecode.com/svn/repo
|
* maven repo: http://jclouds.googlecode.com/svn/repo
|
||||||
* snapshot repo: http://jclouds.rimuhosting.com/maven2/snapshots
|
* snapshot repo: http://jclouds.rimuhosting.com/maven2/snapshots
|
||||||
|
|
||||||
Links:
|
Links:
|
||||||
* project page: http://code.google.com/p/jclouds/
|
* project page: http://code.google.com/p/jclouds/
|
||||||
* javadocs (1.0-beta-7): http://jclouds.rimuhosting.com/apidocs/
|
* javadocs (1.0-beta-8): http://jclouds.rimuhosting.com/apidocs/
|
||||||
* javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/
|
* javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/
|
||||||
* community: http://code.google.com/p/jclouds/wiki/AppsThatUseJClouds
|
* community: http://code.google.com/p/jclouds/wiki/AppsThatUseJClouds
|
||||||
* user group: http://groups.google.com/group/jclouds
|
* user group: http://groups.google.com/group/jclouds
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
|
|
@ -64,44 +64,51 @@ public class ParseAtmosStorageErrorFromXmlContent implements HttpErrorHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Pattern DIRECTORY_PATH = Pattern.compile("^/rest/namespace/?([^/]+)/$");
|
public static final Pattern DIRECTORY_PATH = Pattern.compile("^/rest/namespace/?([^/]+)/$");
|
||||||
public static final Pattern DIRECTORY_KEY_PATH = Pattern
|
public static final Pattern DIRECTORY_KEY_PATH = Pattern.compile("^/rest/namespace/?([^/]+)/(.*)");
|
||||||
.compile("^/rest/namespace/?([^/]+)/(.*)");
|
|
||||||
|
|
||||||
public void handleError(HttpCommand command, HttpResponse response) {
|
public void handleError(HttpCommand command, HttpResponse response) {
|
||||||
Exception exception = new HttpResponseException(command, response);
|
Exception exception = new HttpResponseException(command, response);
|
||||||
try {
|
try {
|
||||||
AtmosStorageError error = parseErrorFromContentOrNull(command, response);
|
AtmosStorageError error = null;
|
||||||
|
if (response.getPayload() != null) {
|
||||||
|
try {
|
||||||
|
String content = Utils.toStringAndClose(response.getPayload().getInput());
|
||||||
|
if (content != null && content.indexOf('<') >= 0) {
|
||||||
|
error = utils.parseAtmosStorageErrorFromContent(command, response, Utils.toInputStream(content));
|
||||||
|
} else {
|
||||||
|
exception = content != null ? new HttpResponseException(command, response, content) : exception;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn(e, "exception reading error from response", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (error != null && error.getCode() == 1016) {
|
if (error != null && error.getCode() == 1016) {
|
||||||
File file = new File(command.getRequest().getEndpoint().getPath());
|
File file = new File(command.getRequest().getEndpoint().getPath());
|
||||||
exception = new KeyAlreadyExistsException(file.getParentFile().getAbsolutePath(), file
|
exception = new KeyAlreadyExistsException(file.getParentFile().getAbsolutePath(), file.getName());
|
||||||
.getName());
|
|
||||||
} else {
|
} else {
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
case 401:
|
case 401:
|
||||||
exception = new AuthorizationException(command.getRequest(),
|
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||||
error != null ? error.getMessage() : response.getStatusLine());
|
break;
|
||||||
break;
|
case 404:
|
||||||
case 404:
|
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
String message = error != null ? error.getMessage() : String.format("%s -> %s", command.getRequest()
|
||||||
String message = error != null ? error.getMessage() : String.format(
|
.getRequestLine(), response.getStatusLine());
|
||||||
"%s -> %s", command.getRequest().getRequestLine(), response
|
String path = command.getRequest().getEndpoint().getPath();
|
||||||
.getStatusLine());
|
Matcher matcher = DIRECTORY_PATH.matcher(path);
|
||||||
String path = command.getRequest().getEndpoint().getPath();
|
if (matcher.find()) {
|
||||||
Matcher matcher = DIRECTORY_PATH.matcher(path);
|
exception = new ContainerNotFoundException(matcher.group(1), message);
|
||||||
|
} else {
|
||||||
|
matcher = DIRECTORY_KEY_PATH.matcher(path);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
exception = new ContainerNotFoundException(matcher.group(1), message);
|
exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message);
|
||||||
} else {
|
|
||||||
matcher = DIRECTORY_KEY_PATH.matcher(path);
|
|
||||||
if (matcher.find()) {
|
|
||||||
exception = new KeyNotFoundException(matcher.group(1), matcher.group(2),
|
|
||||||
message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default:
|
break;
|
||||||
exception = error != null ? new AtmosStorageResponseException(command, response,
|
default:
|
||||||
error) : new HttpResponseException(command, response);
|
exception = error != null ? new AtmosStorageResponseException(command, response, error)
|
||||||
|
: new HttpResponseException(command, response);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,17 +118,4 @@ public class ParseAtmosStorageErrorFromXmlContent implements HttpErrorHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AtmosStorageError parseErrorFromContentOrNull(HttpCommand command, HttpResponse response) {
|
|
||||||
if (response.getPayload() != null) {
|
|
||||||
try {
|
|
||||||
String content = Utils.toStringAndClose(response.getPayload().getInput());
|
|
||||||
if (content != null && content.indexOf('<') >= 0)
|
|
||||||
return utils.parseAtmosStorageErrorFromContent(command, response, Utils
|
|
||||||
.toInputStream(content));
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.warn(e, "exception reading error from response", response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -42,6 +42,8 @@ public class Region {
|
||||||
* consistency for PUTS of new objects in your Amazon S3 bucket and eventual
|
* consistency for PUTS of new objects in your Amazon S3 bucket and eventual
|
||||||
* consistency for overwrite PUTS and DELETES.
|
* consistency for overwrite PUTS and DELETES.
|
||||||
*/
|
*/
|
||||||
|
public static final String EU = "EU";
|
||||||
|
|
||||||
public static final String EU_WEST_1 = "eu-west-1";
|
public static final String EU_WEST_1 = "eu-west-1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -85,8 +87,8 @@ public class Region {
|
||||||
*/
|
*/
|
||||||
public static final String AP_SOUTHEAST_1 = "ap-southeast-1";
|
public static final String AP_SOUTHEAST_1 = "ap-southeast-1";
|
||||||
|
|
||||||
public static Set<String> ALL_S3 = ImmutableSet.of("EU", US_STANDARD,
|
public static Set<String> ALL_S3 = ImmutableSet.of(EU, US_STANDARD,
|
||||||
US_EAST_1, US_WEST_1, AP_SOUTHEAST_1);
|
US_WEST_1, AP_SOUTHEAST_1);
|
||||||
public static Set<String> ALL_SQS = ImmutableSet.of(EU_WEST_1, US_STANDARD,
|
public static Set<String> ALL_SQS = ImmutableSet.of(EU_WEST_1, US_STANDARD,
|
||||||
US_EAST_1, US_WEST_1, AP_SOUTHEAST_1);
|
US_EAST_1, US_WEST_1, AP_SOUTHEAST_1);
|
||||||
}
|
}
|
|
@ -26,6 +26,7 @@ import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs;
|
||||||
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_ELB_ENDPOINT;
|
import static org.jclouds.aws.ec2.reference.EC2Constants.PROPERTY_ELB_ENDPOINT;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
||||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
||||||
|
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_NODE_SUSPENDED;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@ -49,11 +50,15 @@ public class EC2PropertiesBuilder extends PropertiesBuilder {
|
||||||
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "137112412989,063491364108,099720109477,411009282317");
|
properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "137112412989,063491364108,099720109477,411009282317");
|
||||||
// amis that work with the cluster instances
|
// amis that work with the cluster instances
|
||||||
properties.setProperty(PROPERTY_EC2_CC_AMIs, "us-east-1/ami-7ea24a17");
|
properties.setProperty(PROPERTY_EC2_CC_AMIs, "us-east-1/ami-7ea24a17");
|
||||||
|
// sometimes, like in ec2, stop takes a very long time, perhaps
|
||||||
|
// due to volume management. one example spent 2 minutes moving
|
||||||
|
// from stopping->stopped state on an ec2 micro
|
||||||
|
properties.setProperty(PROPERTY_TIMEOUT_NODE_SUSPENDED, 120 * 1000 + "");
|
||||||
// auth fail sometimes happens in EC2, as the rc.local script that injects the
|
// auth fail sometimes happens in EC2, as the rc.local script that injects the
|
||||||
// authorized key executes after ssh has started
|
// authorized key executes after ssh has started
|
||||||
properties.setProperty("jclouds.ssh.max_retries", "7");
|
properties.setProperty("jclouds.ssh.max_retries", "7");
|
||||||
properties.setProperty("jclouds.ssh.retryable_messages",
|
properties.setProperty("jclouds.ssh.retryable_messages",
|
||||||
"Auth fail,invalid data,End of IO Stream Read,Connection reset,socket is not established");
|
"Auth fail,invalid data,End of IO Stream Read,Connection reset,socket is not established");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ import static org.jclouds.aws.ec2.util.EC2Utils.parseHandle;
|
||||||
import static org.jclouds.util.Utils.checkNotEmpty;
|
import static org.jclouds.util.Utils.checkNotEmpty;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -55,12 +55,13 @@ import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||||
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
|
||||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||||
|
import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy;
|
||||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||||
import org.jclouds.compute.util.ComputeUtils;
|
import org.jclouds.compute.util.ComputeUtils;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.http.HttpResponseException;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
|
@ -80,23 +81,23 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected EC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
protected EC2ComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||||
GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy,
|
||||||
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy,
|
||||||
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy,
|
||||||
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
Provider<TemplateBuilder> templateBuilderProvider, Provider<TemplateOptions> templateOptionsProvider,
|
||||||
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
@Named("NODE_RUNNING") Predicate<NodeMetadata> nodeRunning,
|
||||||
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
@Named("NODE_TERMINATED") Predicate<NodeMetadata> nodeTerminated,
|
||||||
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended, ComputeUtils utils, Timeouts timeouts,
|
@Named("NODE_SUSPENDED") Predicate<NodeMetadata> nodeSuspended, ComputeUtils utils, Timeouts timeouts,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client,
|
||||||
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
Map<RegionAndName, KeyPair> credentialsMap, @Named("SECURITY") Map<RegionAndName, String> securityGroupMap,
|
||||||
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
@Named("PLACEMENT") Map<RegionAndName, String> placementGroupMap,
|
||||||
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
@Named("DELETED") Predicate<PlacementGroup> placementGroupDeleted) {
|
||||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
|
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy,
|
||||||
stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, utils,
|
||||||
nodeSuspended, utils, timeouts, executor);
|
timeouts, executor);
|
||||||
this.ec2Client = ec2Client;
|
this.ec2Client = ec2Client;
|
||||||
this.credentialsMap = credentialsMap;
|
this.credentialsMap = credentialsMap;
|
||||||
this.securityGroupMap = securityGroupMap;
|
this.securityGroupMap = securityGroupMap;
|
||||||
|
@ -108,21 +109,28 @@ public class EC2ComputeService extends BaseComputeService {
|
||||||
void deletePlacementGroup(String region, String tag) {
|
void deletePlacementGroup(String region, String tag) {
|
||||||
checkNotEmpty(tag, "tag");
|
checkNotEmpty(tag, "tag");
|
||||||
String group = String.format("jclouds#%s#%s", tag, region);
|
String group = String.format("jclouds#%s#%s", tag, region);
|
||||||
if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) {
|
try {
|
||||||
logger.debug(">> deleting placementGroup(%s)", group);
|
if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) {
|
||||||
try {
|
logger.debug(">> deleting placementGroup(%s)", group);
|
||||||
ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group);
|
try {
|
||||||
checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)), String
|
ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group);
|
||||||
.format("placementGroup region(%s) name(%s) failed to delete", region, group));
|
checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)),
|
||||||
placementGroupMap.remove(new RegionAndName(region, tag));
|
String.format("placementGroup region(%s) name(%s) failed to delete", region, group));
|
||||||
logger.debug("<< deleted placementGroup(%s)", group);
|
placementGroupMap.remove(new RegionAndName(region, tag));
|
||||||
} catch (AWSResponseException e) {
|
logger.debug("<< deleted placementGroup(%s)", group);
|
||||||
if (e.getError().getCode().equals("InvalidPlacementGroup.InUse")) {
|
} catch (AWSResponseException e) {
|
||||||
logger.debug("<< inUse placementGroup(%s)", group);
|
if (e.getError().getCode().equals("InvalidPlacementGroup.InUse")) {
|
||||||
} else {
|
logger.debug("<< inUse placementGroup(%s)", group);
|
||||||
throw e;
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (HttpResponseException e) {
|
||||||
|
// Eucalyptus does not support placement groups yet.
|
||||||
|
if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider()
|
||||||
|
.equals("eucalyptus")))
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ package org.jclouds.aws.ec2.compute.config;
|
||||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||||
import static org.jclouds.compute.domain.OsFamily.AMZN_LINUX;
|
import static org.jclouds.compute.domain.OsFamily.AMZN_LINUX;
|
||||||
import static org.jclouds.compute.domain.OsFamily.CENTOS;
|
import static org.jclouds.compute.domain.OsFamily.CENTOS;
|
||||||
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -65,12 +64,12 @@ public class EC2ComputeServiceContextModule extends BaseComputeServiceContextMod
|
||||||
@Override
|
@Override
|
||||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
String provider = injector.getInstance(Key.get(String.class, Provider.class));
|
String provider = injector.getInstance(Key.get(String.class, Provider.class));
|
||||||
if ("eucalyptus".equals(provider))
|
if ("ec2".equals(provider))
|
||||||
return template.osFamily(CENTOS);
|
|
||||||
else if ("nova".equals(provider))
|
|
||||||
return template.osFamily(UBUNTU);
|
|
||||||
else
|
|
||||||
return template.osFamily(AMZN_LINUX).os64Bit(true);
|
return template.osFamily(AMZN_LINUX).os64Bit(true);
|
||||||
|
else if ("nova".equals(provider))
|
||||||
|
return super.provideTemplate(injector, template);
|
||||||
|
else
|
||||||
|
return template.osFamily(CENTOS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
@ -21,8 +21,8 @@ package org.jclouds.aws.ec2.compute.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrNull;
|
import static org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrNull;
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.parseVersionOrReturnEmptyString;
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
@ -42,6 +42,7 @@ import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||||
|
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.domain.internal.LocationImpl;
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
|
@ -72,32 +73,35 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
||||||
// amzn-ami-us-east-1/amzn-ami-0.9.7-beta.x86_64.manifest.xml
|
// amzn-ami-us-east-1/amzn-ami-0.9.7-beta.x86_64.manifest.xml
|
||||||
// amzn-ami-us-east-1/amzn-ami-0.9.7-beta.i386.manifest.xml
|
// amzn-ami-us-east-1/amzn-ami-0.9.7-beta.i386.manifest.xml
|
||||||
public static final Pattern AMZN_PATTERN = Pattern
|
public static final Pattern AMZN_PATTERN = Pattern
|
||||||
.compile(".*/amzn-ami-(.*)\\.(i386|x86_64)(-ebs|\\.manifest.xml)?");
|
.compile(".*/amzn-ami-(.*)\\.(i386|x86_64)(-ebs|\\.manifest.xml)?");
|
||||||
|
|
||||||
public static final Pattern CANONICAL_PATTERN = Pattern.compile(".*/([^-]*)-([^-]*)-.*-(.*)(\\.manifest.xml)?");
|
public static final Pattern CANONICAL_PATTERN = Pattern.compile(".*/([^-]*)-([^-]*)-.*-(.*)(\\.manifest.xml)?");
|
||||||
|
|
||||||
// ex rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml
|
// ex rightscale-us-east/CentOS_5.4_x64_v4.4.10.manifest.xml
|
||||||
public static final Pattern RIGHTSCALE_PATTERN = Pattern
|
public static final Pattern RIGHTSCALE_PATTERN = Pattern
|
||||||
.compile("[^/]*/([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");
|
.compile("[^/]*/([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");
|
||||||
|
|
||||||
// ex 411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha
|
// ex 411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha
|
||||||
|
// 411009282317/RightImage_Windows_2008_x64_v5.5.5
|
||||||
public static final Pattern RIGHTIMAGE_PATTERN = Pattern
|
public static final Pattern RIGHTIMAGE_PATTERN = Pattern
|
||||||
.compile("[^/]*/RightImage_([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");
|
.compile("[^/]*/RightImage[_ ]([^_]*)_([^_]*)_[^vV]*[vV](.*)(\\.manifest.xml)?");
|
||||||
|
|
||||||
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
|
private final PopulateDefaultLoginCredentialsForImageStrategy credentialProvider;
|
||||||
private final Supplier<Set<? extends Location>> locations;
|
private final Supplier<Set<? extends Location>> locations;
|
||||||
|
|
||||||
private final Supplier<Location> defaultLocation;
|
private final Supplier<Location> defaultLocation;
|
||||||
private final String provider;
|
private final String provider;
|
||||||
|
private final Map<OsFamily, Map<String, String>> osVersionMap;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
|
ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider,
|
||||||
@Memoized Supplier<Set<? extends Location>> locations, Supplier<Location> defaultLocation,
|
Map<OsFamily, Map<String, String>> osVersionMap, @Memoized Supplier<Set<? extends Location>> locations,
|
||||||
@Provider String provider) {
|
Supplier<Location> defaultLocation, @Provider String provider) {
|
||||||
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
|
this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider");
|
||||||
this.locations = checkNotNull(locations, "locations");
|
this.locations = checkNotNull(locations, "locations");
|
||||||
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
|
this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation");
|
||||||
this.provider = checkNotNull(provider, "provider");
|
this.provider = checkNotNull(provider, "provider");
|
||||||
|
this.osVersionMap = checkNotNull(osVersionMap, "utils");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -111,12 +115,13 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
||||||
builder.id(from.getRegion() + "/" + from.getId());
|
builder.id(from.getRegion() + "/" + from.getId());
|
||||||
builder.description(from.getDescription() != null ? from.getDescription() : from.getImageLocation());
|
builder.description(from.getDescription() != null ? from.getDescription() : from.getImageLocation());
|
||||||
builder.userMetadata(ImmutableMap.<String, String> of("owner", from.getImageOwnerId(), "rootDeviceType", from
|
builder.userMetadata(ImmutableMap.<String, String> of("owner", from.getImageOwnerId(), "rootDeviceType", from
|
||||||
.getRootDeviceType().toString()));
|
.getRootDeviceType().toString()));
|
||||||
|
|
||||||
OsFamily osFamily = parseOsFamilyOrNull(provider, from.getImageLocation());
|
OsFamily osFamily = parseOsFamilyOrNull(provider, from.getImageLocation());
|
||||||
String osName = null;
|
String osName = null;
|
||||||
String osArch = from.getVirtualizationType();
|
String osArch = from.getVirtualizationType();
|
||||||
String osVersion = parseVersionOrReturnEmptyString(osFamily, from.getImageLocation());
|
String osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, from.getImageLocation(),
|
||||||
|
osVersionMap);
|
||||||
String osDescription = from.getImageLocation();
|
String osDescription = from.getImageLocation();
|
||||||
boolean is64Bit = from.getArchitecture() == Architecture.X86_64;
|
boolean is64Bit = from.getArchitecture() == Architecture.X86_64;
|
||||||
try {
|
try {
|
||||||
|
@ -126,10 +131,10 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
||||||
osVersion = matcher.group(1);
|
osVersion = matcher.group(1);
|
||||||
builder.version(osVersion);
|
builder.version(osVersion);
|
||||||
} else if (matcher.pattern() == NEBULA_PATTERN) {
|
} else if (matcher.pattern() == NEBULA_PATTERN) {
|
||||||
osVersion = parseVersionOrReturnEmptyString(osFamily, matcher.group(2));
|
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(2), osVersionMap);
|
||||||
} else {
|
} else {
|
||||||
osFamily = OsFamily.fromValue(matcher.group(1));
|
osFamily = OsFamily.fromValue(matcher.group(1));
|
||||||
osVersion = parseVersionOrReturnEmptyString(osFamily, matcher.group(2));
|
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(2), osVersionMap);
|
||||||
builder.version(matcher.group(3).replace(".manifest.xml", ""));
|
builder.version(matcher.group(3).replace(".manifest.xml", ""));
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
@ -152,7 +157,7 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
System.err.printf("unknown region %s for image %s; not in %s", from.getRegion(), from.getId(), locations);
|
System.err.printf("unknown region %s for image %s; not in %s", from.getRegion(), from.getId(), locations);
|
||||||
builder.location(new LocationImpl(LocationScope.REGION, from.getRegion(), from.getRegion(), defaultLocation
|
builder.location(new LocationImpl(LocationScope.REGION, from.getRegion(), from.getRegion(), defaultLocation
|
||||||
.get().getParent()));
|
.get().getParent()));
|
||||||
}
|
}
|
||||||
builder.operatingSystem(new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit));
|
builder.operatingSystem(new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit));
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
@ -165,7 +170,7 @@ public class ImageParser implements Function<org.jclouds.aws.ec2.domain.Image, I
|
||||||
*/
|
*/
|
||||||
private Matcher getMatcherAndFind(String manifest) {
|
private Matcher getMatcherAndFind(String manifest) {
|
||||||
for (Pattern pattern : new Pattern[] { AMZN_PATTERN, NEBULA_PATTERN, CANONICAL_PATTERN, RIGHTIMAGE_PATTERN,
|
for (Pattern pattern : new Pattern[] { AMZN_PATTERN, NEBULA_PATTERN, CANONICAL_PATTERN, RIGHTIMAGE_PATTERN,
|
||||||
RIGHTSCALE_PATTERN }) {
|
RIGHTSCALE_PATTERN }) {
|
||||||
Matcher matcher = pattern.matcher(manifest);
|
Matcher matcher = pattern.matcher(manifest);
|
||||||
if (matcher.find())
|
if (matcher.find())
|
||||||
return matcher;
|
return matcher;
|
||||||
|
|
|
@ -29,7 +29,6 @@ import org.jclouds.aws.ec2.EC2Client;
|
||||||
import org.jclouds.aws.ec2.compute.domain.RegionAndName;
|
import org.jclouds.aws.ec2.compute.domain.RegionAndName;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
@ -55,11 +54,10 @@ public final class RegionAndIdToImage implements Function<RegionAndName, Image>
|
||||||
public Image apply(RegionAndName key) {
|
public Image apply(RegionAndName key) {
|
||||||
try {
|
try {
|
||||||
org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(sync.getAMIServices()
|
org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(sync.getAMIServices()
|
||||||
.describeImagesInRegion(key.getRegion(), imageIds(key.getName())));
|
.describeImagesInRegion(key.getRegion(), imageIds(key.getName())));
|
||||||
return parser.apply(image);
|
return parser.apply(image);
|
||||||
} catch (ResourceNotFoundException e) {
|
} catch (Exception e) {
|
||||||
logger.warn(e, "no image found for %s/%s: %s", key.getRegion(), key.getName(), e
|
logger.warn(e, "could not find image %s/%s: %s", key.getRegion(), key.getName(), e.getMessage());
|
||||||
.getMessage());
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ public class EC2HardwareSupplier implements Supplier<Set<? extends Hardware>> {
|
||||||
sizes.add(cc1_4xlarge().location(location).supportsImageIds(ccAmi).build());
|
sizes.add(cc1_4xlarge().location(location).supportsImageIds(ccAmi).build());
|
||||||
}
|
}
|
||||||
sizes.addAll(ImmutableSet.<Hardware> of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large()
|
sizes.addAll(ImmutableSet.<Hardware> of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large()
|
||||||
.build(), "nova".equals(providerName) ? m1_small().supportsImage(any()).build() : m1_small().build(),
|
.build(), !"ec2".equals(providerName) ? m1_small().supportsImage(any()).build() : m1_small().build(),
|
||||||
m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(), m2_4xlarge().build()));
|
m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(), m2_4xlarge().build()));
|
||||||
return sizes;
|
return sizes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,14 @@ import com.google.common.collect.Sets;
|
||||||
*/
|
*/
|
||||||
public class BaseEC2RequestOptions extends BaseHttpRequestOptions {
|
public class BaseEC2RequestOptions extends BaseHttpRequestOptions {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[formParameters=" + formParameters + "]";
|
||||||
|
}
|
||||||
|
|
||||||
protected void indexFormValuesWithPrefix(String prefix, String... values) {
|
protected void indexFormValuesWithPrefix(String prefix, String... values) {
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
formParameters.put(prefix + "." + (i + 1), checkNotNull(values[i], prefix.toLowerCase()
|
formParameters.put(prefix + "." + (i + 1), checkNotNull(values[i], prefix.toLowerCase() + "s[" + i + "]"));
|
||||||
+ "s[" + i + "]"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
||||||
String message = null;
|
String message = null;
|
||||||
if (response.getPayload() != null) {
|
if (response.getPayload() != null) {
|
||||||
String contentType = response.getPayload().getContentMetadata().getContentType();
|
String contentType = response.getPayload().getContentMetadata().getContentType();
|
||||||
if (contentType != null
|
if (contentType != null && (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)) {
|
||||||
&& (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)) {
|
|
||||||
error = utils.parseAWSErrorFromContent(request, response);
|
error = utils.parseAWSErrorFromContent(request, response);
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
message = error.getMessage();
|
message = error.getMessage();
|
||||||
|
@ -82,40 +81,42 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
message = Utils.toStringAndClose(response.getPayload().getInput());
|
message = Utils.toStringAndClose(response.getPayload().getInput());
|
||||||
|
exception = new HttpResponseException(command, response, message);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message = message != null ? message : String.format("%s -> %s", request.getRequestLine(), response
|
message = message != null ? message : String.format("%s -> %s", request.getRequestLine(),
|
||||||
.getStatusLine());
|
response.getStatusLine());
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
case 400:
|
case 400:
|
||||||
if (error != null && error.getCode() != null
|
if (error != null && error.getCode() != null
|
||||||
&& (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown")))
|
&& (error.getCode().endsWith(".NotFound") || error.getCode().endsWith(".Unknown")))
|
||||||
exception = new ResourceNotFoundException(message, exception);
|
exception = new ResourceNotFoundException(message, exception);
|
||||||
else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error
|
else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error
|
||||||
.getCode().endsWith(".Duplicate")))
|
.getCode().endsWith(".Duplicate"))) || (message != null && message.indexOf("already exists") != -1))
|
||||||
|| (message != null && message.indexOf("already exists") != -1))
|
exception = new IllegalStateException(message, exception);
|
||||||
exception = new IllegalStateException(message, exception);
|
else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure"))
|
||||||
else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure"))
|
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||||
exception = new AuthorizationException(command.getRequest(), message);
|
else if (message != null && message.indexOf("Failed to bind the following fields") != -1)// Nova
|
||||||
else if (message != null && message.indexOf("Failed to bind the following fields") != -1)// Nova
|
exception = new IllegalArgumentException(message, exception);
|
||||||
exception = new IllegalArgumentException(message, exception);
|
break;
|
||||||
break;
|
case 401:
|
||||||
case 401:
|
case 403:
|
||||||
case 403:
|
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||||
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 container = request.getEndpoint().getHost();
|
||||||
String container = request.getEndpoint().getHost();
|
String key = request.getEndpoint().getPath();
|
||||||
String key = request.getEndpoint().getPath();
|
if (key == null || key.equals("/"))
|
||||||
if (key == null || key.equals("/"))
|
exception = new ContainerNotFoundException(container, message);
|
||||||
exception = new ContainerNotFoundException(container, message);
|
else
|
||||||
else
|
exception = new KeyNotFoundException(container, key, message);
|
||||||
exception = new KeyNotFoundException(container, key, message);
|
}
|
||||||
}
|
break;
|
||||||
break;
|
case 409:
|
||||||
|
exception = new IllegalStateException(message, exception);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
releasePayload(response);
|
releasePayload(response);
|
||||||
|
|
|
@ -60,20 +60,15 @@ public class S3PropertiesBuilder extends PropertiesBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties addEndpoints(Properties properties) {
|
protected Properties addEndpoints(Properties properties) {
|
||||||
properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(Region.US_STANDARD,
|
properties.setProperty(PROPERTY_REGIONS,
|
||||||
Region.US_EAST_1, Region.US_WEST_1, "EU", Region.AP_SOUTHEAST_1));
|
Joiner.on(',').join(Region.US_STANDARD, Region.US_WEST_1, "EU", Region.AP_SOUTHEAST_1));
|
||||||
properties.setProperty(PROPERTY_DEFAULT_REGIONS, Joiner.on(',').join(Region.US_STANDARD,
|
properties.setProperty(PROPERTY_DEFAULT_REGIONS, Region.US_STANDARD);
|
||||||
Region.US_EAST_1));
|
|
||||||
properties.setProperty(PROPERTY_ENDPOINT, "https://s3.amazonaws.com");
|
properties.setProperty(PROPERTY_ENDPOINT, "https://s3.amazonaws.com");
|
||||||
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_STANDARD,
|
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_STANDARD, "https://s3.amazonaws.com");
|
||||||
"https://s3.amazonaws.com");
|
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1, "https://s3-us-west-1.amazonaws.com");
|
||||||
properties
|
|
||||||
.setProperty(PROPERTY_ENDPOINT + "." + Region.US_EAST_1, "https://s3.amazonaws.com");
|
|
||||||
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.US_WEST_1,
|
|
||||||
"https://s3-us-west-1.amazonaws.com");
|
|
||||||
properties.setProperty(PROPERTY_ENDPOINT + "." + "EU", "https://s3-eu-west-1.amazonaws.com");
|
properties.setProperty(PROPERTY_ENDPOINT + "." + "EU", "https://s3-eu-west-1.amazonaws.com");
|
||||||
properties.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1,
|
properties
|
||||||
"https://s3-ap-southeast-1.amazonaws.com");
|
.setProperty(PROPERTY_ENDPOINT + "." + Region.AP_SOUTHEAST_1, "https://s3-ap-southeast-1.amazonaws.com");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +87,8 @@ public class S3PropertiesBuilder extends PropertiesBuilder {
|
||||||
|
|
||||||
protected void setMetaPrefix() {
|
protected void setMetaPrefix() {
|
||||||
if (properties.getProperty(PROPERTY_USER_METADATA_PREFIX) == null) {
|
if (properties.getProperty(PROPERTY_USER_METADATA_PREFIX) == null) {
|
||||||
properties.setProperty(PROPERTY_USER_METADATA_PREFIX, String.format("x-%s-meta-",
|
properties.setProperty(PROPERTY_USER_METADATA_PREFIX,
|
||||||
properties.getProperty(PROPERTY_HEADER_TAG)));
|
String.format("x-%s-meta-", properties.getProperty(PROPERTY_HEADER_TAG)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,19 +71,21 @@ public class BucketToResourceMetadata implements Function<BucketMetadata, Storag
|
||||||
|
|
||||||
private Location getLocation(BucketMetadata from) {
|
private Location getLocation(BucketMetadata from) {
|
||||||
try {
|
try {
|
||||||
|
Set<? extends Location> locations = this.locations.get();
|
||||||
final String region = client.getBucketLocation(from.getName());
|
final String region = client.getBucketLocation(from.getName());
|
||||||
|
assert region != null : String.format("could not get region for %s", from.getName());
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
try {
|
try {
|
||||||
return Iterables.find(locations.get(), new Predicate<Location>() {
|
return Iterables.find(locations, new Predicate<Location>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Location input) {
|
public boolean apply(Location input) {
|
||||||
return input.getId().equals(region.toString());
|
return input.getId().equalsIgnoreCase(region.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
logger.error("could not get location for region %s in %s", region, locations.get());
|
logger.error("could not get location for region %s in %s", region, locations);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.error("could not get region for %s", from.getName());
|
logger.error("could not get region for %s", from.getName());
|
||||||
|
|
|
@ -50,8 +50,8 @@ public class LocationConstraintHandler extends ParseSax.HandlerWithResult<String
|
||||||
public static String fromValue(String v) {
|
public static String fromValue(String v) {
|
||||||
if (v.equals(""))
|
if (v.equals(""))
|
||||||
return Region.US_STANDARD;
|
return Region.US_STANDARD;
|
||||||
if (v.equals("EU"))
|
if (v.equals(Region.EU))
|
||||||
return Region.EU_WEST_1;
|
return Region.EU;
|
||||||
else if (v.equals(Region.US_WEST_1))
|
else if (v.equals(Region.US_WEST_1))
|
||||||
return Region.US_WEST_1;
|
return Region.US_WEST_1;
|
||||||
else if (v.equals(Region.AP_SOUTHEAST_1))
|
else if (v.equals(Region.AP_SOUTHEAST_1))
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class ComputeAndBlobStoreTogetherHappilyLiveTest extends BlobStoreAndComp
|
||||||
Statement installOpenJDK = execHttpResponse(signedRequestOfInstallScript);
|
Statement installOpenJDK = execHttpResponse(signedRequestOfInstallScript);
|
||||||
|
|
||||||
// if we want to, we can mix and match batched and ad-hoc commands, such as extracting maven
|
// if we want to, we can mix and match batched and ad-hoc commands, such as extracting maven
|
||||||
String mavenVersion = "3.0-beta-3";
|
String mavenVersion = "3.0";
|
||||||
Statement extractMavenIntoUsrLocal = extractTargzIntoDirectory(
|
Statement extractMavenIntoUsrLocal = extractTargzIntoDirectory(
|
||||||
URI.create("http://mirrors.ibiblio.org/pub/mirrors/apache//maven/binaries/apache-maven-" + mavenVersion
|
URI.create("http://mirrors.ibiblio.org/pub/mirrors/apache//maven/binaries/apache-maven-" + mavenVersion
|
||||||
+ "-bin.tar.gz"), "/usr/local");
|
+ "-bin.tar.gz"), "/usr/local");
|
||||||
|
|
|
@ -77,7 +77,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
public void testImagesResolveCorrectly() {
|
public void testImagesResolveCorrectly() {
|
||||||
Template defaultTemplate = client.templateBuilder().build();
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
assertEquals(defaultTemplate.getImage().getId(), defaultTemplate.getImage().getLocation().getId() + "/"
|
assertEquals(defaultTemplate.getImage().getId(), defaultTemplate.getImage().getLocation().getId() + "/"
|
||||||
+ defaultTemplate.getImage().getProviderId());
|
+ defaultTemplate.getImage().getProviderId());
|
||||||
Template byId = client.templateBuilder().imageId(defaultTemplate.getImage().getId()).build();
|
Template byId = client.templateBuilder().imageId(defaultTemplate.getImage().getId()).build();
|
||||||
assertEquals(byId.getImage(), defaultTemplate.getImage());
|
assertEquals(byId.getImage(), defaultTemplate.getImage());
|
||||||
}
|
}
|
||||||
|
@ -98,13 +98,13 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
||||||
public void testExtendedOptionsAndLogin() throws Exception {
|
public void testExtendedOptionsAndLogin() throws Exception {
|
||||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getSecurityGroupServices();
|
.getSecurityGroupServices();
|
||||||
|
|
||||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getKeyPairServices();
|
.getKeyPairServices();
|
||||||
|
|
||||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getInstanceServices();
|
.getInstanceServices();
|
||||||
|
|
||||||
String tag = this.tag + "optionsandlogin";
|
String tag = this.tag + "optionsandlogin";
|
||||||
|
|
||||||
|
@ -141,17 +141,17 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
checkMonitoringEnabled(before, instance);
|
checkMonitoringEnabled(before, instance);
|
||||||
|
|
||||||
// make sure we made our dummy group and also let in the user's group
|
// make sure we made our dummy group and also let in the user's group
|
||||||
assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet.<String> of("jclouds#" + tag + "#"
|
assertEquals(Sets.newTreeSet(instance.getGroupIds()),
|
||||||
+ instance.getRegion(), tag));
|
ImmutableSortedSet.<String> of("jclouds#" + tag + "#" + instance.getRegion(), tag));
|
||||||
|
|
||||||
// make sure our dummy group has no rules
|
// make sure our dummy group has no rules
|
||||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null,
|
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null,
|
||||||
"jclouds#" + tag + "#" + instance.getRegion()));
|
"jclouds#" + tag + "#" + instance.getRegion()));
|
||||||
assert group.getIpPermissions().size() == 0 : group;
|
assert group.getIpPermissions().size() == 0 : group;
|
||||||
|
|
||||||
// try to run a script with the original keyPair
|
// try to run a script with the original keyPair
|
||||||
runScriptWithCreds(tag, first.getOperatingSystem(), new Credentials(first.getCredentials().identity, result
|
runScriptWithCreds(tag, first.getOperatingSystem(),
|
||||||
.getKeyMaterial()));
|
new Credentials(first.getCredentials().identity, result.getKeyMaterial()));
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
client.destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
|
@ -168,11 +168,11 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
assertEquals(instance.getMonitoringState(), MonitoringState.ENABLED);
|
assertEquals(instance.getMonitoringState(), MonitoringState.ENABLED);
|
||||||
|
|
||||||
RestContext<CloudWatchClient, CloudWatchAsyncClient> monitoringContext = new RestContextFactory().createContext(
|
RestContext<CloudWatchClient, CloudWatchAsyncClient> monitoringContext = new RestContextFactory().createContext(
|
||||||
"cloudwatch", identity, credential, ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
"cloudwatch", identity, credential, ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Set<Datapoint> datapoints = monitoringContext.getApi().getMetricStatisticsInRegion(instance.getRegion(),
|
Set<Datapoint> datapoints = monitoringContext.getApi().getMetricStatisticsInRegion(instance.getRegion(),
|
||||||
"CPUUtilization", before, new Date(), 60, "Average");
|
"CPUUtilization", before, new Date(), 60, "Average");
|
||||||
assert datapoints != null;
|
assert datapoints != null;
|
||||||
} finally {
|
} finally {
|
||||||
monitoringContext.close();
|
monitoringContext.close();
|
||||||
|
@ -182,13 +182,13 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
@Test(enabled = true, dependsOnMethods = "testCompareSizes")
|
||||||
public void testExtendedOptionsNoKeyPair() throws Exception {
|
public void testExtendedOptionsNoKeyPair() throws Exception {
|
||||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getSecurityGroupServices();
|
.getSecurityGroupServices();
|
||||||
|
|
||||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getKeyPairServices();
|
.getKeyPairServices();
|
||||||
|
|
||||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getInstanceServices();
|
.getInstanceServices();
|
||||||
|
|
||||||
String tag = this.tag + "optionsnokey";
|
String tag = this.tag + "optionsnokey";
|
||||||
|
|
||||||
|
@ -215,12 +215,12 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
assertEquals(instance.getKeyName(), null);
|
assertEquals(instance.getKeyName(), null);
|
||||||
|
|
||||||
// make sure we made our dummy group and also let in the user's group
|
// make sure we made our dummy group and also let in the user's group
|
||||||
assertEquals(instance.getGroupIds(), ImmutableSet.<String> of(tag, String.format("jclouds#%s#%s", tag,
|
assertEquals(Sets.newTreeSet(instance.getGroupIds()),
|
||||||
instance.getRegion())));
|
ImmutableSortedSet.<String> of(tag, String.format("jclouds#%s#%s", tag, instance.getRegion())));
|
||||||
|
|
||||||
// make sure our dummy group has no rules
|
// make sure our dummy group has no rules
|
||||||
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null, String
|
SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null,
|
||||||
.format("jclouds#%s#%s", tag, instance.getRegion())));
|
String.format("jclouds#%s#%s", tag, instance.getRegion())));
|
||||||
assert group.getIpPermissions().size() == 0 : group;
|
assert group.getIpPermissions().size() == 0 : group;
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -242,13 +242,13 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getSecurityGroupServices();
|
.getSecurityGroupServices();
|
||||||
|
|
||||||
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getKeyPairServices();
|
.getKeyPairServices();
|
||||||
|
|
||||||
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi())
|
||||||
.getInstanceServices();
|
.getInstanceServices();
|
||||||
|
|
||||||
String tag = this.tag + "optionswithsubnetid";
|
String tag = this.tag + "optionswithsubnetid";
|
||||||
|
|
||||||
|
@ -295,12 +295,12 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
private RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
private RunningInstance getInstance(InstanceClient instanceClient, String id) {
|
||||||
RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient
|
||||||
.describeInstancesInRegion(null, id)));
|
.describeInstancesInRegion(null, id)));
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String tag)
|
private void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String tag)
|
||||||
throws InterruptedException {
|
throws InterruptedException {
|
||||||
try {
|
try {
|
||||||
for (SecurityGroup group : securityGroupClient.describeSecurityGroupsInRegion(null))
|
for (SecurityGroup group : securityGroupClient.describeSecurityGroupsInRegion(null))
|
||||||
if (group.getName().startsWith("jclouds#" + tag) || group.getName().equals(tag)) {
|
if (group.getName().startsWith("jclouds#" + tag) || group.getName().equals(tag)) {
|
||||||
|
|
|
@ -19,24 +19,24 @@
|
||||||
|
|
||||||
package org.jclouds.aws.ec2.compute;
|
package org.jclouds.aws.ec2.compute;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
|
||||||
import org.jclouds.aws.ec2.domain.InstanceType;
|
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||||
|
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||||
import org.jclouds.compute.ComputeServiceContext;
|
import org.jclouds.compute.ComputeServiceContext;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
|
import org.jclouds.compute.OsFamilyVersion64Bit;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.testng.annotations.BeforeClass;
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
@ -45,147 +45,106 @@ import com.google.inject.Module;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", testName = "ec2.EC2TemplateBuilderLiveTest")
|
@Test(groups = "live", testName = "ec2.EC2TemplateBuilderLiveTest")
|
||||||
public class EC2TemplateBuilderLiveTest {
|
public class EC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
protected String provider = "ec2";
|
|
||||||
protected String identity;
|
|
||||||
protected String credential;
|
|
||||||
protected String endpoint;
|
|
||||||
protected String apiversion;
|
|
||||||
|
|
||||||
@BeforeClass
|
public EC2TemplateBuilderLiveTest() {
|
||||||
protected void setupCredentials() {
|
provider = "ec2";
|
||||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
|
||||||
credential = System.getProperty("test." + provider + ".credential");
|
|
||||||
endpoint = System.getProperty("test." + provider + ".endpoint");
|
|
||||||
apiversion = System.getProperty("test." + provider + ".apiversion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties setupProperties() {
|
@Override
|
||||||
Properties overrides = new Properties();
|
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
return new Predicate<OsFamilyVersion64Bit>() {
|
||||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
|
||||||
overrides.setProperty(provider + ".identity", identity);
|
@Override
|
||||||
if (credential != null)
|
public boolean apply(OsFamilyVersion64Bit input) {
|
||||||
overrides.setProperty(provider + ".credential", credential);
|
return input.family == OsFamily.RHEL || //
|
||||||
if (endpoint != null)
|
(input.family == OsFamily.CENTOS && !input.version.matches("5.[42]")) || //
|
||||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
(input.family == OsFamily.WINDOWS && !input.version.matches("200[38]"));
|
||||||
if (apiversion != null)
|
}
|
||||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
|
||||||
return overrides;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTemplateBuilderM1SMALLWithDescription() {
|
public void testTemplateBuilderM1SMALLWithDescription() {
|
||||||
ComputeServiceContext newContext = null;
|
|
||||||
try {
|
|
||||||
newContext = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
|
||||||
.<Module> of(new Log4JLoggingModule()), setupProperties());
|
|
||||||
|
|
||||||
Template template = newContext.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL)
|
Template template = context.getComputeService().templateBuilder().hardwareId(InstanceType.M1_SMALL)
|
||||||
.osVersionMatches("10.10").imageDescriptionMatches("ubuntu-images").osFamily(OsFamily.UBUNTU).build();
|
.osVersionMatches("10.10").imageDescriptionMatches("ubuntu-images").osFamily(OsFamily.UBUNTU).build();
|
||||||
|
|
||||||
|
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.10");
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().is64Bit(), false);
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
|
assertEquals(template.getImage().getVersion(), "20101106");
|
||||||
|
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
||||||
|
assertEquals(template.getLocation().getId(), "us-east-1");
|
||||||
|
assertEquals(getCores(template.getHardware()), 1.0d);
|
||||||
|
assertEquals(template.getHardware().getId(), InstanceType.M1_SMALL);
|
||||||
|
|
||||||
System.out.println(template.getHardware());
|
|
||||||
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
|
|
||||||
assertEquals(template.getImage().getOperatingSystem().getVersion(), "10.10");
|
|
||||||
assertEquals(template.getImage().getOperatingSystem().is64Bit(), false);
|
|
||||||
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
|
||||||
assertEquals(template.getImage().getVersion(), "20101027");
|
|
||||||
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
|
||||||
assertEquals(template.getLocation().getId(), "us-east-1");
|
|
||||||
assertEquals(getCores(template.getHardware()), 1.0d);
|
|
||||||
assertEquals(template.getHardware().getId(), InstanceType.M1_SMALL);
|
|
||||||
} finally {
|
|
||||||
if (newContext != null)
|
|
||||||
newContext.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTemplateBuilderCanUseImageIdAndhardwareId() {
|
public void testTemplateBuilderCanUseImageIdAndhardwareId() {
|
||||||
ComputeServiceContext newContext = null;
|
|
||||||
try {
|
|
||||||
newContext = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
|
||||||
.<Module> of(new Log4JLoggingModule()), setupProperties());
|
|
||||||
|
|
||||||
Template template = newContext.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5")
|
Template template = context.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5")
|
||||||
.hardwareId(InstanceType.M2_2XLARGE).build();
|
.hardwareId(InstanceType.M2_2XLARGE).build();
|
||||||
|
|
||||||
|
System.out.println(template.getHardware());
|
||||||
|
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4");
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
||||||
|
assertEquals(template.getImage().getVersion(), "4.4.10");
|
||||||
|
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
||||||
|
assertEquals(template.getLocation().getId(), "us-east-1");
|
||||||
|
assertEquals(getCores(template.getHardware()), 4.0d);
|
||||||
|
assertEquals(template.getHardware().getId(), InstanceType.M2_2XLARGE);
|
||||||
|
|
||||||
System.out.println(template.getHardware());
|
|
||||||
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
|
|
||||||
assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4");
|
|
||||||
assertEquals(template.getImage().getOperatingSystem().is64Bit(), true);
|
|
||||||
assertEquals(template.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
|
||||||
assertEquals(template.getImage().getVersion(), "4.4.10");
|
|
||||||
assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store");
|
|
||||||
assertEquals(template.getLocation().getId(), "us-east-1");
|
|
||||||
assertEquals(getCores(template.getHardware()), 4.0d);
|
|
||||||
assertEquals(template.getHardware().getId(), InstanceType.M2_2XLARGE);
|
|
||||||
} finally {
|
|
||||||
if (newContext != null)
|
|
||||||
newContext.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultTemplateBuilder() throws IOException {
|
public void testDefaultTemplateBuilder() throws IOException {
|
||||||
ComputeServiceContext newContext = null;
|
|
||||||
try {
|
|
||||||
newContext = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
|
||||||
.<Module> of(new Log4JLoggingModule()), setupProperties());
|
|
||||||
|
|
||||||
Template defaultTemplate = newContext.getComputeService().templateBuilder().build();
|
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||||
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
|
assert (defaultTemplate.getImage().getProviderId().startsWith("ami-")) : defaultTemplate;
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "0.9.9-beta");
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "0.9.9-beta");
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.AMZN_LINUX);
|
||||||
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
|
assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
|
||||||
assertEquals(defaultTemplate.getLocation().getId(), "us-east-1");
|
assertEquals(defaultTemplate.getLocation().getId(), "us-east-1");
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
|
|
||||||
} finally {
|
|
||||||
if (newContext != null)
|
|
||||||
newContext.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTemplateBuilderMicro() throws IOException {
|
public void testTemplateBuilderMicro() throws IOException {
|
||||||
ComputeServiceContext newContext = null;
|
|
||||||
try {
|
|
||||||
newContext = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
|
||||||
.<Module> of(new Log4JLoggingModule()), setupProperties());
|
|
||||||
|
|
||||||
Template microTemplate = newContext.getComputeService().templateBuilder().hardwareId(InstanceType.T1_MICRO)
|
Template microTemplate = context.getComputeService().templateBuilder().hardwareId(InstanceType.T1_MICRO).build();
|
||||||
.build();
|
|
||||||
System.out.println(microTemplate.getHardware());
|
assert (microTemplate.getImage().getProviderId().startsWith("ami-")) : microTemplate;
|
||||||
|
assertEquals(microTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
|
||||||
|
assertEquals(microTemplate.getImage().getOperatingSystem().is64Bit(), false);
|
||||||
|
assertEquals(microTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
|
assertEquals(microTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
|
||||||
|
assertEquals(microTemplate.getLocation().getId(), "us-east-1");
|
||||||
|
assertEquals(getCores(microTemplate.getHardware()), 1.0d);
|
||||||
|
|
||||||
assert (microTemplate.getImage().getProviderId().startsWith("ami-")) : microTemplate;
|
|
||||||
assertEquals(microTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
|
|
||||||
assertEquals(microTemplate.getImage().getOperatingSystem().is64Bit(), false);
|
|
||||||
assertEquals(microTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
|
||||||
assertEquals(microTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs");
|
|
||||||
assertEquals(microTemplate.getLocation().getId(), "us-east-1");
|
|
||||||
assertEquals(getCores(microTemplate.getHardware()), 1.0d);
|
|
||||||
} finally {
|
|
||||||
if (newContext != null)
|
|
||||||
newContext.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTemplateBuilderWithNoOwnersParsesImageOnDemand() throws IOException {
|
public void testTemplateBuilderWithNoOwnersParsesImageOnDemand() throws IOException {
|
||||||
ComputeServiceContext newContext = null;
|
ComputeServiceContext context = null;
|
||||||
try {
|
try {
|
||||||
Properties overrides = setupProperties();
|
Properties overrides = setupProperties();
|
||||||
// set owners to nothing
|
// set owners to nothing
|
||||||
overrides.setProperty(EC2Constants.PROPERTY_EC2_AMI_OWNERS, "");
|
overrides.setProperty(EC2Constants.PROPERTY_EC2_AMI_OWNERS, "");
|
||||||
|
|
||||||
newContext = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
context = new ComputeServiceContextFactory().createContext(provider,
|
||||||
.<Module> of(new Log4JLoggingModule()), overrides);
|
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides);
|
||||||
|
|
||||||
assertEquals(newContext.getComputeService().listImages().size(), 0);
|
assertEquals(context.getComputeService().listImages().size(), 0);
|
||||||
|
|
||||||
Template template = newContext.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").build();
|
Template template = context.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").build();
|
||||||
System.out.println(template.getHardware());
|
System.out.println(template.getHardware());
|
||||||
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
|
assert (template.getImage().getProviderId().startsWith("ami-")) : template;
|
||||||
assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4");
|
assertEquals(template.getImage().getOperatingSystem().getVersion(), "5.4");
|
||||||
|
@ -199,11 +158,11 @@ public class EC2TemplateBuilderLiveTest {
|
||||||
// is 64bit
|
// is 64bit
|
||||||
|
|
||||||
// ensure we cache the new image for next time
|
// ensure we cache the new image for next time
|
||||||
assertEquals(newContext.getComputeService().listImages().size(), 1);
|
assertEquals(context.getComputeService().listImages().size(), 1);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (newContext != null)
|
if (context != null)
|
||||||
newContext.close();
|
context.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,14 @@ import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Disabled until we have an environment with enough room to run a few nodes simultaneously.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", sequential = true, testName = "ec2.EucalyptusComputeServiceLiveTest")
|
@Test(groups = "live", enabled = true, sequential = true, testName = "ec2.EucalyptusComputeServiceLiveTest")
|
||||||
public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest {
|
public class EucalyptusComputeServiceLiveTestDisabled extends EC2ComputeServiceLiveTest {
|
||||||
|
|
||||||
public EucalyptusComputeServiceLiveTest() {
|
public EucalyptusComputeServiceLiveTestDisabled() {
|
||||||
provider = "eucalyptus";
|
provider = "eucalyptus";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,12 +46,18 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest
|
||||||
tag = "euc";
|
tag = "euc";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test(enabled = false)
|
||||||
|
public void testExtendedOptionsAndLogin() throws Exception {
|
||||||
|
// euc does not support monitoring
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void assertDefaultWorks() {
|
protected void assertDefaultWorks() {
|
||||||
Template defaultTemplate = client.templateBuilder().build();
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 2.0d);
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -21,18 +21,23 @@ package org.jclouds.aws.ec2.compute.functions;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.aws.ec2.compute.strategy.EC2PopulateDefaultLoginCredentialsForImageStrategy;
|
import org.jclouds.aws.ec2.compute.strategy.EC2PopulateDefaultLoginCredentialsForImageStrategy;
|
||||||
import org.jclouds.aws.ec2.domain.Image;
|
import org.jclouds.aws.ec2.domain.Image;
|
||||||
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandlerTest;
|
import org.jclouds.aws.ec2.xml.DescribeImagesResponseHandlerTest;
|
||||||
|
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||||
import org.jclouds.compute.domain.ImageBuilder;
|
import org.jclouds.compute.domain.ImageBuilder;
|
||||||
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.domain.internal.LocationImpl;
|
import org.jclouds.domain.internal.LocationImpl;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
|
@ -42,6 +47,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
|
@ -141,6 +147,10 @@ public class ImageParserTest {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
new Gson().toJson(Iterables.get(result, 1)),
|
new Gson().toJson(Iterables.get(result, 1)),
|
||||||
"{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\"},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
|
"{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\"},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
new Gson().toJson(Iterables.get(result, 2)),
|
||||||
|
"{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"providerId\":\"ami-710c2605\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\"},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testParseEucalyptusImage() {
|
public void testParseEucalyptusImage() {
|
||||||
|
@ -208,8 +218,13 @@ public class ImageParserTest {
|
||||||
static Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", "us-east-1", null);
|
static Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", "us-east-1", null);
|
||||||
|
|
||||||
public static Set<org.jclouds.compute.domain.Image> convertImages(String resource) {
|
public static Set<org.jclouds.compute.domain.Image> convertImages(String resource) {
|
||||||
|
|
||||||
|
Map<OsFamily, Map<String, String>> map = new BaseComputeServiceContextModule() {
|
||||||
|
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
|
||||||
|
.getInstance(Json.class));
|
||||||
|
|
||||||
Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource);
|
Set<Image> result = DescribeImagesResponseHandlerTest.parseImages(resource);
|
||||||
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(),
|
ImageParser parser = new ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map,
|
||||||
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)),
|
Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet.<Location> of(defaultLocation)),
|
||||||
Suppliers.ofInstance(defaultLocation), "ec2");
|
Suppliers.ofInstance(defaultLocation), "ec2");
|
||||||
return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull()));
|
return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull()));
|
||||||
|
|
|
@ -27,6 +27,7 @@ import static org.easymock.classextension.EasyMock.verify;
|
||||||
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
@ -44,7 +45,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Test(groups = "unit", testName = "ec2.RegionAndIdToImageTest")
|
@Test(groups = "unit", testName = "ec2.RegionAndIdToImageTest")
|
||||||
public class RegionAndIdToImageTest {
|
public class RegionAndIdToImageTest {
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked"})
|
@SuppressWarnings({ "unchecked" })
|
||||||
@Test
|
@Test
|
||||||
public void testApply() {
|
public void testApply() {
|
||||||
|
|
||||||
|
@ -54,10 +55,10 @@ public class RegionAndIdToImageTest {
|
||||||
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
||||||
Image image = createNiceMock(Image.class);
|
Image image = createNiceMock(Image.class);
|
||||||
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
||||||
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||||
|
|
||||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set)images);
|
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set) images);
|
||||||
expect(parser.apply(ec2Image)).andReturn(image);
|
expect(parser.apply(ec2Image)).andReturn(image);
|
||||||
|
|
||||||
replay(caller);
|
replay(caller);
|
||||||
|
@ -76,7 +77,7 @@ public class RegionAndIdToImageTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings({ "unchecked"})
|
@SuppressWarnings({ "unchecked" })
|
||||||
@Test
|
@Test
|
||||||
public void testApplyNotFound() {
|
public void testApplyNotFound() {
|
||||||
|
|
||||||
|
@ -86,10 +87,10 @@ public class RegionAndIdToImageTest {
|
||||||
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
||||||
Image image = createNiceMock(Image.class);
|
Image image = createNiceMock(Image.class);
|
||||||
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
||||||
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||||
|
|
||||||
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||||
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set)images);
|
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set) images);
|
||||||
expect(parser.apply(ec2Image)).andThrow(new ResourceNotFoundException());
|
expect(parser.apply(ec2Image)).andThrow(new ResourceNotFoundException());
|
||||||
|
|
||||||
replay(caller);
|
replay(caller);
|
||||||
|
@ -107,4 +108,36 @@ public class RegionAndIdToImageTest {
|
||||||
verify(client);
|
verify(client);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked" })
|
||||||
|
@Test
|
||||||
|
public void testApplyNoSuchElementException() {
|
||||||
|
|
||||||
|
ImageParser parser = createMock(ImageParser.class);
|
||||||
|
EC2Client caller = createMock(EC2Client.class);
|
||||||
|
AMIClient client = createMock(AMIClient.class);
|
||||||
|
org.jclouds.aws.ec2.domain.Image ec2Image = createMock(org.jclouds.aws.ec2.domain.Image.class);
|
||||||
|
Image image = createNiceMock(Image.class);
|
||||||
|
Set<? extends org.jclouds.aws.ec2.domain.Image> images = ImmutableSet
|
||||||
|
.<org.jclouds.aws.ec2.domain.Image> of(ec2Image);
|
||||||
|
|
||||||
|
expect(caller.getAMIServices()).andReturn(client).atLeastOnce();
|
||||||
|
expect(client.describeImagesInRegion("region", imageIds("ami"))).andReturn((Set) images);
|
||||||
|
expect(parser.apply(ec2Image)).andThrow(new NoSuchElementException());
|
||||||
|
|
||||||
|
replay(caller);
|
||||||
|
replay(image);
|
||||||
|
replay(parser);
|
||||||
|
replay(client);
|
||||||
|
|
||||||
|
RegionAndIdToImage function = new RegionAndIdToImage(parser, caller);
|
||||||
|
|
||||||
|
assertEquals(function.apply(new RegionAndName("region", "ami")), null);
|
||||||
|
|
||||||
|
verify(caller);
|
||||||
|
verify(image);
|
||||||
|
verify(parser);
|
||||||
|
verify(client);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,12 +36,13 @@ import org.jclouds.aws.domain.Region;
|
||||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
import org.jclouds.aws.ec2.domain.Image;
|
import org.jclouds.aws.ec2.domain.Image;
|
||||||
import org.jclouds.aws.ec2.domain.RootDeviceType;
|
|
||||||
import org.jclouds.aws.ec2.domain.Image.ImageType;
|
import org.jclouds.aws.ec2.domain.Image.ImageType;
|
||||||
|
import org.jclouds.aws.ec2.domain.RootDeviceType;
|
||||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.testng.annotations.AfterTest;
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -74,13 +75,12 @@ public class AMIClientLiveTest {
|
||||||
protected String endpoint;
|
protected String endpoint;
|
||||||
protected String apiversion;
|
protected String apiversion;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
protected void setupCredentials() {
|
protected void setupCredentials() {
|
||||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||||
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
|
credential = System.getProperty("test." + provider + ".credential");
|
||||||
+ ".credential");
|
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||||
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
|
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||||
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
|
|
||||||
+ ".apiversion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
|
@ -88,9 +88,12 @@ public class AMIClientLiveTest {
|
||||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||||
overrides.setProperty(provider + ".identity", identity);
|
overrides.setProperty(provider + ".identity", identity);
|
||||||
overrides.setProperty(provider + ".credential", credential);
|
if (credential != null)
|
||||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
overrides.setProperty(provider + ".credential", credential);
|
||||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
if (endpoint != null)
|
||||||
|
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||||
|
if (apiversion != null)
|
||||||
|
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||||
return overrides;
|
return overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,10 @@ import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.aws.domain.Region;
|
import org.jclouds.aws.domain.Region;
|
||||||
|
@ -41,13 +41,13 @@ import org.jclouds.compute.ComputeServiceContextFactory;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.testng.annotations.AfterTest;
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -66,13 +66,12 @@ public class AvailabilityZoneAndRegionClientLiveTest {
|
||||||
protected String endpoint;
|
protected String endpoint;
|
||||||
protected String apiversion;
|
protected String apiversion;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
protected void setupCredentials() {
|
protected void setupCredentials() {
|
||||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||||
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
|
credential = System.getProperty("test." + provider + ".credential");
|
||||||
+ ".credential");
|
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||||
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
|
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||||
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
|
|
||||||
+ ".apiversion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
|
@ -80,9 +79,12 @@ public class AvailabilityZoneAndRegionClientLiveTest {
|
||||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||||
overrides.setProperty(provider + ".identity", identity);
|
overrides.setProperty(provider + ".identity", identity);
|
||||||
overrides.setProperty(provider + ".credential", credential);
|
if (credential != null)
|
||||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
overrides.setProperty(provider + ".credential", credential);
|
||||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
if (endpoint != null)
|
||||||
|
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||||
|
if (apiversion != null)
|
||||||
|
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||||
return overrides;
|
return overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,26 +92,25 @@ public class AvailabilityZoneAndRegionClientLiveTest {
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
setupCredentials();
|
setupCredentials();
|
||||||
Properties overrides = setupProperties();
|
Properties overrides = setupProperties();
|
||||||
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()),
|
context = new ComputeServiceContextFactory().createContext(provider,
|
||||||
overrides).getProviderSpecificContext();
|
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
|
||||||
client = context.getApi().getAvailabilityZoneAndRegionServices();
|
client = context.getApi().getAvailabilityZoneAndRegionServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDescribeAvailabilityZones() {
|
public void testDescribeAvailabilityZones() {
|
||||||
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1,
|
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
||||||
Region.US_WEST_1, Region.AP_SOUTHEAST_1)) {
|
Region.AP_SOUTHEAST_1)) {
|
||||||
Set<AvailabilityZoneInfo> allResults = Sets.newLinkedHashSet(client
|
Set<AvailabilityZoneInfo> allResults = client.describeAvailabilityZonesInRegion(region);
|
||||||
.describeAvailabilityZonesInRegion(region));
|
|
||||||
assertNotNull(allResults);
|
assertNotNull(allResults);
|
||||||
assert allResults.size() >= 2 : allResults.size();
|
assert allResults.size() >= 2 : allResults.size();
|
||||||
Iterator<AvailabilityZoneInfo> iterator = allResults.iterator();
|
Iterator<AvailabilityZoneInfo> iterator = allResults.iterator();
|
||||||
String id1 = iterator.next().getZone();
|
String id1 = iterator.next().getZone();
|
||||||
String id2 = iterator.next().getZone();
|
String id2 = iterator.next().getZone();
|
||||||
Set<AvailabilityZoneInfo> twoResults = Sets.newLinkedHashSet(client
|
Set<AvailabilityZoneInfo> twoResults = client.describeAvailabilityZonesInRegion(region,
|
||||||
.describeAvailabilityZonesInRegion(region, availabilityZones(id1, id2)));
|
availabilityZones(id1, id2));
|
||||||
assertNotNull(twoResults);
|
assertNotNull(twoResults);
|
||||||
assertEquals(twoResults.size(), 2);
|
assertEquals(twoResults.size(), 2);
|
||||||
iterator = twoResults.iterator();
|
iterator = allResults.iterator();
|
||||||
assertEquals(iterator.next().getZone(), id1);
|
assertEquals(iterator.next().getZone(), id1);
|
||||||
assertEquals(iterator.next().getZone(), id2);
|
assertEquals(iterator.next().getZone(), id2);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import java.util.SortedSet;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.aws.AWSResponseException;
|
|
||||||
import org.jclouds.aws.domain.Region;
|
import org.jclouds.aws.domain.Region;
|
||||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
@ -44,6 +43,7 @@ import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.rest.RestContext;
|
import org.jclouds.rest.RestContext;
|
||||||
import org.testng.annotations.AfterTest;
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -71,13 +71,12 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
protected String endpoint;
|
protected String endpoint;
|
||||||
protected String apiversion;
|
protected String apiversion;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
protected void setupCredentials() {
|
protected void setupCredentials() {
|
||||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||||
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
|
credential = System.getProperty("test." + provider + ".credential");
|
||||||
+ ".credential");
|
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||||
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
|
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||||
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
|
|
||||||
+ ".apiversion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
|
@ -85,9 +84,12 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||||
overrides.setProperty(provider + ".identity", identity);
|
overrides.setProperty(provider + ".identity", identity);
|
||||||
overrides.setProperty(provider + ".credential", credential);
|
if (credential != null)
|
||||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
overrides.setProperty(provider + ".credential", credential);
|
||||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
if (endpoint != null)
|
||||||
|
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||||
|
if (apiversion != null)
|
||||||
|
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||||
return overrides;
|
return overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,15 +97,15 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
public void setupClient() {
|
public void setupClient() {
|
||||||
setupCredentials();
|
setupCredentials();
|
||||||
Properties overrides = setupProperties();
|
Properties overrides = setupProperties();
|
||||||
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()),
|
context = new ComputeServiceContextFactory().createContext(provider,
|
||||||
overrides).getProviderSpecificContext();
|
ImmutableSet.<Module> of(new Log4JLoggingModule()), overrides).getProviderSpecificContext();
|
||||||
client = context.getApi().getElasticBlockStoreServices();
|
client = context.getApi().getElasticBlockStoreServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDescribeVolumes() {
|
void testDescribeVolumes() {
|
||||||
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
||||||
Region.AP_SOUTHEAST_1)) {
|
Region.AP_SOUTHEAST_1)) {
|
||||||
SortedSet<Volume> allResults = Sets.newTreeSet(client.describeVolumesInRegion(region));
|
SortedSet<Volume> allResults = Sets.newTreeSet(client.describeVolumesInRegion(region));
|
||||||
assertNotNull(allResults);
|
assertNotNull(allResults);
|
||||||
if (allResults.size() >= 1) {
|
if (allResults.size() >= 1) {
|
||||||
|
@ -136,11 +138,11 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
void testCreateSnapshotInRegion() {
|
void testCreateSnapshotInRegion() {
|
||||||
Snapshot snapshot = client.createSnapshotInRegion(null, volumeId);
|
Snapshot snapshot = client.createSnapshotInRegion(null, volumeId);
|
||||||
Predicate<Snapshot> snapshotted = new RetryablePredicate<Snapshot>(new SnapshotCompleted(client), 600, 10,
|
Predicate<Snapshot> snapshotted = new RetryablePredicate<Snapshot>(new SnapshotCompleted(client), 600, 10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
assert snapshotted.apply(snapshot);
|
assert snapshotted.apply(snapshot);
|
||||||
|
|
||||||
Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(snapshot.getRegion(),
|
Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(snapshot.getRegion(),
|
||||||
snapshotIds(snapshot.getId())));
|
snapshotIds(snapshot.getId())));
|
||||||
|
|
||||||
assertEquals(result.getProgress(), 100);
|
assertEquals(result.getProgress(), 100);
|
||||||
this.snapshot = result;
|
this.snapshot = result;
|
||||||
|
@ -152,7 +154,7 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
assertNotNull(volume);
|
assertNotNull(volume);
|
||||||
|
|
||||||
Predicate<Volume> availabile = new RetryablePredicate<Volume>(new VolumeAvailable(client), 600, 10,
|
Predicate<Volume> availabile = new RetryablePredicate<Volume>(new VolumeAvailable(client), 600, 10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
assert availabile.apply(volume);
|
assert availabile.apply(volume);
|
||||||
|
|
||||||
Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(), volume.getId()));
|
Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(), volume.getId()));
|
||||||
|
@ -166,12 +168,12 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreateSnapshotInRegion")
|
@Test(dependsOnMethods = "testCreateSnapshotInRegion")
|
||||||
void testCreateVolumeFromSnapshotInAvailabilityZoneWithSize() {
|
void testCreateVolumeFromSnapshotInAvailabilityZoneWithSize() {
|
||||||
Volume volume = client.createVolumeFromSnapshotInAvailabilityZone(AvailabilityZone.US_EAST_1B, 2, snapshot
|
Volume volume = client.createVolumeFromSnapshotInAvailabilityZone(AvailabilityZone.US_EAST_1B, 2,
|
||||||
.getId());
|
snapshot.getId());
|
||||||
assertNotNull(volume);
|
assertNotNull(volume);
|
||||||
|
|
||||||
Predicate<Volume> availabile = new RetryablePredicate<Volume>(new VolumeAvailable(client), 600, 10,
|
Predicate<Volume> availabile = new RetryablePredicate<Volume>(new VolumeAvailable(client), 600, 10,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
assert availabile.apply(volume);
|
assert availabile.apply(volume);
|
||||||
|
|
||||||
Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(), volume.getId()));
|
Volume result = Iterables.getOnlyElement(client.describeVolumesInRegion(snapshot.getRegion(), volume.getId()));
|
||||||
|
@ -197,13 +199,13 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
@Test
|
@Test
|
||||||
void testDescribeSnapshots() {
|
void testDescribeSnapshots() {
|
||||||
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
||||||
Region.AP_SOUTHEAST_1)) {
|
Region.AP_SOUTHEAST_1)) {
|
||||||
SortedSet<Snapshot> allResults = Sets.newTreeSet(client.describeSnapshotsInRegion(region));
|
SortedSet<Snapshot> allResults = Sets.newTreeSet(client.describeSnapshotsInRegion(region));
|
||||||
assertNotNull(allResults);
|
assertNotNull(allResults);
|
||||||
if (allResults.size() >= 1) {
|
if (allResults.size() >= 1) {
|
||||||
Snapshot snapshot = allResults.last();
|
Snapshot snapshot = allResults.last();
|
||||||
Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(region, snapshotIds(snapshot
|
Snapshot result = Iterables.getOnlyElement(client.describeSnapshotsInRegion(region,
|
||||||
.getId())));
|
snapshotIds(snapshot.getId())));
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
assertEquals(result, snapshot);
|
assertEquals(result, snapshot);
|
||||||
}
|
}
|
||||||
|
@ -246,12 +248,7 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
@Test(dependsOnMethods = "testGetCreateVolumePermissionForSnapshot")
|
@Test(dependsOnMethods = "testGetCreateVolumePermissionForSnapshot")
|
||||||
void testDeleteSnapshotInRegion() {
|
void testDeleteSnapshotInRegion() {
|
||||||
client.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId());
|
client.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId());
|
||||||
try {
|
assert client.describeSnapshotsInRegion(snapshot.getRegion(), snapshotIds(snapshot.getId())).size() == 0;
|
||||||
client.describeSnapshotsInRegion(snapshot.getRegion(), snapshotIds(snapshot.getId()));
|
|
||||||
assert false : "shoud have exception";
|
|
||||||
} catch (AWSResponseException e) {
|
|
||||||
assertEquals(e.getError().getCode(), "InvalidSnapshot.NotFound");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterTest
|
@AfterTest
|
||||||
|
|
|
@ -56,7 +56,9 @@ import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
import org.jclouds.compute.predicates.NodePredicates;
|
||||||
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
import org.testng.annotations.AfterTest;
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.BeforeGroups;
|
import org.testng.annotations.BeforeGroups;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -85,13 +87,12 @@ public class PlacementGroupClientLiveTest {
|
||||||
protected String endpoint;
|
protected String endpoint;
|
||||||
protected String apiversion;
|
protected String apiversion;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
protected void setupCredentials() {
|
protected void setupCredentials() {
|
||||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||||
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
|
credential = System.getProperty("test." + provider + ".credential");
|
||||||
+ ".credential");
|
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||||
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
|
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||||
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
|
|
||||||
+ ".apiversion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
|
@ -99,9 +100,12 @@ public class PlacementGroupClientLiveTest {
|
||||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||||
overrides.setProperty(provider + ".identity", identity);
|
overrides.setProperty(provider + ".identity", identity);
|
||||||
overrides.setProperty(provider + ".credential", credential);
|
if (credential != null)
|
||||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
overrides.setProperty(provider + ".credential", credential);
|
||||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
if (endpoint != null)
|
||||||
|
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||||
|
if (apiversion != null)
|
||||||
|
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||||
return overrides;
|
return overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,14 +113,14 @@ public class PlacementGroupClientLiveTest {
|
||||||
public void setupClient() throws FileNotFoundException, IOException {
|
public void setupClient() throws FileNotFoundException, IOException {
|
||||||
setupCredentials();
|
setupCredentials();
|
||||||
Properties overrides = setupProperties();
|
Properties overrides = setupProperties();
|
||||||
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet
|
context = new ComputeServiceContextFactory().createContext(provider,
|
||||||
.<Module> of(new Log4JLoggingModule()), overrides);
|
ImmutableSet.<Module> of(new Log4JLoggingModule(), new JschSshClientModule()), overrides);
|
||||||
keyPair = setupKeyPair();
|
keyPair = setupKeyPair();
|
||||||
|
|
||||||
client = EC2Client.class.cast(context.getProviderSpecificContext().getApi());
|
client = EC2Client.class.cast(context.getProviderSpecificContext().getApi());
|
||||||
|
|
||||||
availableTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupAvailable(client), 60, 1,
|
availableTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupAvailable(client), 60, 1,
|
||||||
TimeUnit.SECONDS);
|
TimeUnit.SECONDS);
|
||||||
|
|
||||||
deletedTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupDeleted(client), 60, 1, TimeUnit.SECONDS);
|
deletedTester = new RetryablePredicate<PlacementGroup>(new PlacementGroupDeleted(client), 60, 1, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
@ -125,12 +129,12 @@ public class PlacementGroupClientLiveTest {
|
||||||
void testDescribe() {
|
void testDescribe() {
|
||||||
for (String region : newArrayList(Region.US_EAST_1)) {
|
for (String region : newArrayList(Region.US_EAST_1)) {
|
||||||
SortedSet<PlacementGroup> allResults = newTreeSet(client.getPlacementGroupServices()
|
SortedSet<PlacementGroup> allResults = newTreeSet(client.getPlacementGroupServices()
|
||||||
.describePlacementGroupsInRegion(region));
|
.describePlacementGroupsInRegion(region));
|
||||||
assertNotNull(allResults);
|
assertNotNull(allResults);
|
||||||
if (allResults.size() >= 1) {
|
if (allResults.size() >= 1) {
|
||||||
PlacementGroup group = allResults.last();
|
PlacementGroup group = allResults.last();
|
||||||
SortedSet<PlacementGroup> result = newTreeSet(client.getPlacementGroupServices()
|
SortedSet<PlacementGroup> result = newTreeSet(client.getPlacementGroupServices()
|
||||||
.describePlacementGroupsInRegion(region, group.getName()));
|
.describePlacementGroupsInRegion(region, group.getName()));
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
PlacementGroup compare = result.last();
|
PlacementGroup compare = result.last();
|
||||||
assertEquals(compare, group);
|
assertEquals(compare, group);
|
||||||
|
@ -159,7 +163,7 @@ public class PlacementGroupClientLiveTest {
|
||||||
private void verifyPlacementGroup(String groupName) {
|
private void verifyPlacementGroup(String groupName) {
|
||||||
assert availableTester.apply(new PlacementGroup(Region.US_EAST_1, groupName, "cluster", State.PENDING)) : group;
|
assert availableTester.apply(new PlacementGroup(Region.US_EAST_1, groupName, "cluster", State.PENDING)) : group;
|
||||||
Set<PlacementGroup> oneResult = client.getPlacementGroupServices().describePlacementGroupsInRegion(null,
|
Set<PlacementGroup> oneResult = client.getPlacementGroupServices().describePlacementGroupsInRegion(null,
|
||||||
groupName);
|
groupName);
|
||||||
assertNotNull(oneResult);
|
assertNotNull(oneResult);
|
||||||
assertEquals(oneResult.size(), 1);
|
assertEquals(oneResult.size(), 1);
|
||||||
group = oneResult.iterator().next();
|
group = oneResult.iterator().next();
|
||||||
|
@ -169,6 +173,7 @@ public class PlacementGroupClientLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStartCCInstance() throws Exception {
|
public void testStartCCInstance() throws Exception {
|
||||||
|
|
||||||
Set<? extends Hardware> sizes = context.getComputeService().listHardwareProfiles();
|
Set<? extends Hardware> sizes = context.getComputeService().listHardwareProfiles();
|
||||||
assert any(sizes, new Predicate<Hardware>() {
|
assert any(sizes, new Predicate<Hardware>() {
|
||||||
|
|
||||||
|
@ -194,17 +199,19 @@ public class PlacementGroupClientLiveTest {
|
||||||
assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17");
|
assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17");
|
||||||
|
|
||||||
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
|
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
|
||||||
.runScript(buildScript(template.getImage().getOperatingSystem()));
|
.runScript(buildScript(template.getImage().getOperatingSystem()));
|
||||||
|
|
||||||
String tag = PREFIX + "cccluster";
|
String tag = PREFIX + "cccluster";
|
||||||
context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
|
context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag));
|
||||||
|
// TODO make this not lookup an explicit region
|
||||||
|
client.getPlacementGroupServices().deletePlacementGroupInRegion(null, "jclouds#" + tag + "#us-east-1");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Set<? extends NodeMetadata> nodes = context.getComputeService().runNodesWithTag(tag, 1, template);
|
Set<? extends NodeMetadata> nodes = context.getComputeService().runNodesWithTag(tag, 1, template);
|
||||||
NodeMetadata node = getOnlyElement(nodes);
|
NodeMetadata node = getOnlyElement(nodes);
|
||||||
|
|
||||||
getOnlyElement(getOnlyElement(client.getInstanceServices().describeInstancesInRegion(null,
|
getOnlyElement(getOnlyElement(client.getInstanceServices().describeInstancesInRegion(null,
|
||||||
node.getProviderId())));
|
node.getProviderId())));
|
||||||
|
|
||||||
} catch (RunNodesException e) {
|
} catch (RunNodesException e) {
|
||||||
System.err.println(e.getNodeErrors().keySet());
|
System.err.println(e.getNodeErrors().keySet());
|
||||||
|
|
|
@ -68,6 +68,12 @@ public class ParseAWSErrorFromXmlContentTest {
|
||||||
assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "",
|
assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "",
|
||||||
"<Error><Code>IncorrectState</Code></Error>", IllegalStateException.class);
|
"<Error><Code>IncorrectState</Code></Error>", IllegalStateException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test409SetsIllegalStateException() {
|
||||||
|
assertCodeMakes("PUT", URI.create("https://adriancole-blobstore011.s3.amazonaws.com/"), 409, "",
|
||||||
|
"<Error><Code>OperationAborted</Code><Message>A conflicting conditional operation is currently in progress against this resource. Please try again.</Message><RequestId>F716E81C3D814E59</RequestId><HostId>SDprHxWzG/YXzanVnV7VTz/wP+6fRt1dS+q00kH1rz248YOOSddkFiTXF04XtqNO</HostId></Error>", IllegalStateException.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test400WithInvalidGroupDuplicateIllegalStateException() {
|
public void test400WithInvalidGroupDuplicateIllegalStateException() {
|
||||||
|
|
|
@ -39,17 +39,17 @@ import java.util.concurrent.TimeoutException;
|
||||||
import org.jclouds.aws.domain.Region;
|
import org.jclouds.aws.domain.Region;
|
||||||
import org.jclouds.aws.s3.S3Client;
|
import org.jclouds.aws.s3.S3Client;
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList;
|
import org.jclouds.aws.s3.domain.AccessControlList;
|
||||||
|
import org.jclouds.aws.s3.domain.AccessControlList.CanonicalUserGrantee;
|
||||||
|
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
|
||||||
|
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
|
||||||
|
import org.jclouds.aws.s3.domain.AccessControlList.GroupGranteeURI;
|
||||||
|
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
|
||||||
import org.jclouds.aws.s3.domain.BucketLogging;
|
import org.jclouds.aws.s3.domain.BucketLogging;
|
||||||
import org.jclouds.aws.s3.domain.BucketMetadata;
|
import org.jclouds.aws.s3.domain.BucketMetadata;
|
||||||
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
|
import org.jclouds.aws.s3.domain.CannedAccessPolicy;
|
||||||
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
import org.jclouds.aws.s3.domain.ListBucketResponse;
|
||||||
import org.jclouds.aws.s3.domain.Payer;
|
import org.jclouds.aws.s3.domain.Payer;
|
||||||
import org.jclouds.aws.s3.domain.S3Object;
|
import org.jclouds.aws.s3.domain.S3Object;
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList.CanonicalUserGrantee;
|
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList.EmailAddressGrantee;
|
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList.Grant;
|
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList.GroupGranteeURI;
|
|
||||||
import org.jclouds.aws.s3.domain.AccessControlList.Permission;
|
|
||||||
import org.jclouds.aws.s3.internal.StubS3AsyncClient;
|
import org.jclouds.aws.s3.internal.StubS3AsyncClient;
|
||||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
@ -90,7 +90,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPrivateAclIsDefaultForBucket() throws InterruptedException, ExecutionException, TimeoutException,
|
public void testPrivateAclIsDefaultForBucket() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
IOException {
|
IOException {
|
||||||
String bucketName = getContainerName();
|
String bucketName = getContainerName();
|
||||||
try {
|
try {
|
||||||
AccessControlList acl = getApi().getBucketACL(bucketName);
|
AccessControlList acl = getApi().getBucketACL(bucketName);
|
||||||
|
@ -105,7 +105,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUpdateBucketACL() throws InterruptedException, ExecutionException, TimeoutException, IOException,
|
public void testUpdateBucketACL() throws InterruptedException, ExecutionException, TimeoutException, IOException,
|
||||||
Exception {
|
Exception {
|
||||||
String bucketName = getContainerName();
|
String bucketName = getContainerName();
|
||||||
try {
|
try {
|
||||||
// Confirm the bucket is private
|
// Confirm the bucket is private
|
||||||
|
@ -221,9 +221,9 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
assertNull(getApi().getBucketLogging(bucketName));
|
assertNull(getApi().getBucketLogging(bucketName));
|
||||||
|
|
||||||
setupAclForBucketLoggingTarget(targetBucket);
|
setupAclForBucketLoggingTarget(targetBucket);
|
||||||
final BucketLogging logging = new BucketLogging(targetBucket, "access_log-", ImmutableSet
|
final BucketLogging logging = new BucketLogging(targetBucket, "access_log-",
|
||||||
.<Grant> of(new Grant(new EmailAddressGrantee(StubS3AsyncClient.TEST_ACL_EMAIL),
|
ImmutableSet.<Grant> of(new Grant(new EmailAddressGrantee(StubS3AsyncClient.TEST_ACL_EMAIL),
|
||||||
Permission.FULL_CONTROL)));
|
Permission.FULL_CONTROL)));
|
||||||
|
|
||||||
getApi().enableBucketLogging(bucketName, logging);
|
getApi().enableBucketLogging(bucketName, logging);
|
||||||
|
|
||||||
|
@ -231,6 +231,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
BucketLogging newLogging = getApi().getBucketLogging(bucketName);
|
BucketLogging newLogging = getApi().getBucketLogging(bucketName);
|
||||||
|
assert newLogging !=null;
|
||||||
AccessControlList acl = new AccessControlList();
|
AccessControlList acl = new AccessControlList();
|
||||||
for (Grant grant : newLogging.getTargetGrants()) { // TODO: add permission
|
for (Grant grant : newLogging.getTargetGrants()) { // TODO: add permission
|
||||||
// checking features to
|
// checking features to
|
||||||
|
@ -277,7 +278,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
public void testEu() throws Exception {
|
public void testEu() throws Exception {
|
||||||
final String bucketName = getScratchContainerName();
|
final String bucketName = getScratchContainerName();
|
||||||
try {
|
try {
|
||||||
getApi().putBucketInRegion(Region.EU_WEST_1, bucketName + "eu", withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
|
getApi().putBucketInRegion(Region.EU, bucketName + "eu", withBucketAcl(CannedAccessPolicy.PUBLIC_READ));
|
||||||
assertConsistencyAware(new Runnable() {
|
assertConsistencyAware(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
|
@ -288,7 +289,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
assertEquals(Region.EU_WEST_1, getApi().getBucketLocation(bucketName + "eu"));
|
assertEquals(Region.EU, getApi().getBucketLocation(bucketName + "eu"));
|
||||||
// TODO: I believe that the following should work based on the above acl assertion passing.
|
// TODO: I believe that the following should work based on the above acl assertion passing.
|
||||||
// However, it fails on 403
|
// However, it fails on 403
|
||||||
// URL url = new URL(String.format("http://%s.s3.amazonaws.com", bucketName));
|
// URL url = new URL(String.format("http://%s.s3.amazonaws.com", bucketName));
|
||||||
|
@ -298,7 +299,6 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void bucketExists() throws Exception {
|
void bucketExists() throws Exception {
|
||||||
String bucketName = getContainerName();
|
String bucketName = getContainerName();
|
||||||
try {
|
try {
|
||||||
|
@ -334,7 +334,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListBucketDelimiter() throws InterruptedException, ExecutionException, TimeoutException,
|
public void testListBucketDelimiter() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
String bucketName = getContainerName();
|
String bucketName = getContainerName();
|
||||||
try {
|
try {
|
||||||
String prefix = "apps";
|
String prefix = "apps";
|
||||||
|
@ -352,7 +352,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListBucketPrefix() throws InterruptedException, ExecutionException, TimeoutException,
|
public void testListBucketPrefix() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
String bucketName = getContainerName();
|
String bucketName = getContainerName();
|
||||||
try {
|
try {
|
||||||
String prefix = "apps";
|
String prefix = "apps";
|
||||||
|
@ -370,7 +370,7 @@ public class BucketsLiveTest extends BaseBlobStoreIntegrationTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testListBucketMaxResults() throws InterruptedException, ExecutionException, TimeoutException,
|
public void testListBucketMaxResults() throws InterruptedException, ExecutionException, TimeoutException,
|
||||||
UnsupportedEncodingException {
|
UnsupportedEncodingException {
|
||||||
String bucketName = getContainerName();
|
String bucketName = getContainerName();
|
||||||
try {
|
try {
|
||||||
addAlphabetUnderRoot(bucketName);
|
addAlphabetUnderRoot(bucketName);
|
||||||
|
|
|
@ -68,10 +68,9 @@ public class SQSClientLiveTest {
|
||||||
protected void setupCredentials() {
|
protected void setupCredentials() {
|
||||||
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||||
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
|
credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider
|
||||||
+ ".credential");
|
+ ".credential");
|
||||||
endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint");
|
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||||
apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "test." + provider
|
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||||
+ ".apiversion");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
|
@ -79,9 +78,12 @@ public class SQSClientLiveTest {
|
||||||
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||||
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||||
overrides.setProperty(provider + ".identity", identity);
|
overrides.setProperty(provider + ".identity", identity);
|
||||||
overrides.setProperty(provider + ".credential", credential);
|
if (credential != null)
|
||||||
overrides.setProperty(provider + ".endpoint", endpoint);
|
overrides.setProperty(provider + ".credential", credential);
|
||||||
overrides.setProperty(provider + ".apiversion", apiversion);
|
if (endpoint != null)
|
||||||
|
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||||
|
if (apiversion != null)
|
||||||
|
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||||
return overrides;
|
return overrides;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,14 +92,14 @@ public class SQSClientLiveTest {
|
||||||
setupCredentials();
|
setupCredentials();
|
||||||
Properties overrides = setupProperties();
|
Properties overrides = setupProperties();
|
||||||
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()),
|
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()),
|
||||||
overrides);
|
overrides);
|
||||||
this.client = context.getApi();
|
this.client = context.getApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testListQueuesInRegion() throws InterruptedException {
|
void testListQueuesInRegion() throws InterruptedException {
|
||||||
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
||||||
Region.AP_SOUTHEAST_1)) {
|
Region.AP_SOUTHEAST_1)) {
|
||||||
SortedSet<Queue> allResults = Sets.newTreeSet(client.listQueuesInRegion(region));
|
SortedSet<Queue> allResults = Sets.newTreeSet(client.listQueuesInRegion(region));
|
||||||
assertNotNull(allResults);
|
assertNotNull(allResults);
|
||||||
if (allResults.size() >= 1) {
|
if (allResults.size() >= 1) {
|
||||||
|
@ -114,7 +116,7 @@ public class SQSClientLiveTest {
|
||||||
String queueName = PREFIX + "1";
|
String queueName = PREFIX + "1";
|
||||||
|
|
||||||
for (final String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
for (final String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1,
|
||||||
Region.AP_SOUTHEAST_1)) {
|
Region.AP_SOUTHEAST_1)) {
|
||||||
try {
|
try {
|
||||||
SortedSet<Queue> result = Sets.newTreeSet(client.listQueuesInRegion(region, queuePrefix(queueName)));
|
SortedSet<Queue> result = Sets.newTreeSet(client.listQueuesInRegion(region, queuePrefix(queueName)));
|
||||||
if (result.size() >= 1) {
|
if (result.size() >= 1) {
|
||||||
|
@ -182,7 +184,7 @@ public class SQSClientLiveTest {
|
||||||
assertion.run();
|
assertion.run();
|
||||||
if (i > 0)
|
if (i > 0)
|
||||||
System.err.printf("%d attempts and %dms asserting %s%n", i + 1, System.currentTimeMillis() - start,
|
System.err.printf("%d attempts and %dms asserting %s%n", i + 1, System.currentTimeMillis() - start,
|
||||||
assertion.getClass().getSimpleName());
|
assertion.getClass().getSimpleName());
|
||||||
return;
|
return;
|
||||||
} catch (AssertionError e) {
|
} catch (AssertionError e) {
|
||||||
error = e;
|
error = e;
|
||||||
|
|
|
@ -41,5 +41,54 @@
|
||||||
</item>
|
</item>
|
||||||
</blockDeviceMapping>
|
</blockDeviceMapping>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<imageId>ami-710c2605</imageId>
|
||||||
|
<imageLocation>411009282317/RightImage Windows_2003_i386_v5.4.3</imageLocation>
|
||||||
|
<imageState>available</imageState>
|
||||||
|
<imageOwnerId>411009282317</imageOwnerId>
|
||||||
|
<isPublic>true</isPublic>
|
||||||
|
<architecture>i386</architecture>
|
||||||
|
<imageType>machine</imageType>
|
||||||
|
<platform>windows</platform>
|
||||||
|
<name>RightImage Windows_2003_i386_v5.4.3</name>
|
||||||
|
<description>Built by RightScale</description>
|
||||||
|
<rootDeviceType>ebs</rootDeviceType>
|
||||||
|
<rootDeviceName>/dev/sda1</rootDeviceName>
|
||||||
|
<blockDeviceMapping>
|
||||||
|
<item>
|
||||||
|
<deviceName>/dev/sda1</deviceName>
|
||||||
|
<ebs>
|
||||||
|
<snapshotId>snap-9460affd</snapshotId>
|
||||||
|
<volumeSize>35</volumeSize>
|
||||||
|
<deleteOnTermination>true</deleteOnTermination>
|
||||||
|
</ebs>
|
||||||
|
</item>
|
||||||
|
</blockDeviceMapping>
|
||||||
|
<virtualizationType>hvm</virtualizationType>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<imageId>ami-c6a882b2</imageId>
|
||||||
|
<imageLocation>411009282317/RightImage_Windows_2008_x64_v5.5.5</imageLocation>
|
||||||
|
<imageOwnerId>411009282317</imageOwnerId>
|
||||||
|
<isPublic>true</isPublic>
|
||||||
|
<architecture>x86_64</architecture>
|
||||||
|
<imageType>machine</imageType>
|
||||||
|
<platform>windows</platform>
|
||||||
|
<name>RightImage_Windows_2008_x64_v5.5.5</name>
|
||||||
|
<description>Built by RightScale</description>
|
||||||
|
<rootDeviceType>ebs</rootDeviceType>
|
||||||
|
<rootDeviceName>/dev/sda1</rootDeviceName>
|
||||||
|
<blockDeviceMapping>
|
||||||
|
<item>
|
||||||
|
<deviceName>/dev/sda1</deviceName>
|
||||||
|
<ebs>
|
||||||
|
<snapshotId>snap-68b26c01</snapshotId>
|
||||||
|
<volumeSize>80</volumeSize>
|
||||||
|
<deleteOnTermination>true</deleteOnTermination>
|
||||||
|
</ebs>
|
||||||
|
</item>
|
||||||
|
</blockDeviceMapping>
|
||||||
|
<virtualizationType>hvm</virtualizationType>
|
||||||
|
</item>
|
||||||
</imagesSet>
|
</imagesSet>
|
||||||
</DescribeImagesResponse>
|
</DescribeImagesResponse>
|
||||||
|
|
|
@ -162,12 +162,10 @@
|
||||||
<priority value="DEBUG" />
|
<priority value="DEBUG" />
|
||||||
<appender-ref ref="ASYNCSSH" />
|
<appender-ref ref="ASYNCSSH" />
|
||||||
</category>
|
</category>
|
||||||
<!--
|
|
||||||
<category name="jclouds.wire">
|
<category name="jclouds.wire">
|
||||||
<priority value="DEBUG" />
|
<priority value="DEBUG" />
|
||||||
<appender-ref ref="ASYNCWIRE" />
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
</category>
|
</category>
|
||||||
-->
|
|
||||||
<category name="jclouds.blobstore">
|
<category name="jclouds.blobstore">
|
||||||
<priority value="DEBUG" />
|
<priority value="DEBUG" />
|
||||||
<appender-ref ref="ASYNCBLOBSTORE" />
|
<appender-ref ref="ASYNCBLOBSTORE" />
|
||||||
|
|
|
@ -68,44 +68,53 @@ public class ParseAzureStorageErrorFromXmlContent implements HttpErrorHandler {
|
||||||
try {
|
try {
|
||||||
if (response.getPayload() != null) {
|
if (response.getPayload() != null) {
|
||||||
String contentType = response.getPayload().getContentMetadata().getContentType();
|
String contentType = response.getPayload().getContentMetadata().getContentType();
|
||||||
if (contentType != null && (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)) {
|
if (contentType != null && (contentType.indexOf("xml") != -1 || contentType.indexOf("unknown") != -1)
|
||||||
AzureStorageError error = utils.parseAzureStorageErrorFromContent(command, response, response
|
&& !new Long(0).equals(response.getPayload().getContentMetadata().getContentLength())) {
|
||||||
|
try {
|
||||||
|
AzureStorageError error = utils.parseAzureStorageErrorFromContent(command, response, response
|
||||||
.getPayload().getInput());
|
.getPayload().getInput());
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
message = error.getMessage();
|
message = error.getMessage();
|
||||||
exception = new AzureStorageResponseException(command, response, error);
|
exception = new AzureStorageResponseException(command, response, error);
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
try {
|
||||||
|
message = Utils.toStringAndClose(response.getPayload().getInput());
|
||||||
|
exception = new HttpResponseException(command, response, message);
|
||||||
|
} catch (IOException e1) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
message = Utils.toStringAndClose(response.getPayload().getInput());
|
message = Utils.toStringAndClose(response.getPayload().getInput());
|
||||||
|
exception = new HttpResponseException(command, response, message);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
message = message != null ? message : String.format("%s -> %s", command.getRequest().getRequestLine(),
|
message = message != null ? message : String.format("%s -> %s", command.getRequest().getRequestLine(),
|
||||||
response.getStatusLine());
|
response.getStatusLine());
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
case 401:
|
case 401:
|
||||||
exception = new AuthorizationException(command.getRequest(), message);
|
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||||
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);
|
if (matcher.find()) {
|
||||||
|
exception = new ContainerNotFoundException(matcher.group(1), message);
|
||||||
|
} else {
|
||||||
|
matcher = CONTAINER_KEY_PATH.matcher(path);
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
exception = new ContainerNotFoundException(matcher.group(1), message);
|
exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message);
|
||||||
} else {
|
|
||||||
matcher = CONTAINER_KEY_PATH.matcher(path);
|
|
||||||
if (matcher.find()) {
|
|
||||||
exception = new KeyNotFoundException(matcher.group(1), matcher.group(2), message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case 411:
|
break;
|
||||||
exception = new IllegalArgumentException(message);
|
case 411:
|
||||||
break;
|
exception = new IllegalArgumentException(message);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
releasePayload(response);
|
releasePayload(response);
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -49,14 +50,33 @@ public class ParseAzureErrorFromXmlContentTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test411WithTextHtmlIllegalArgumentException() {
|
public void test411WithTextHtmlIllegalArgumentException() {
|
||||||
assertCodeMakes("PUT", URI
|
assertCodeMakes("PUT",
|
||||||
.create("https://jclouds.blob.core.windows.net/adriancole-azureblob-413790770?restype=container"), 411,
|
URI.create("https://jclouds.blob.core.windows.net/adriancole-azureblob-413790770?restype=container"), 411,
|
||||||
"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 test304WithNoContentIllegalArgumentException() {
|
||||||
|
assertCodeMakes("GET", URI.create("https://jclouds.blob.core.windows.net/adriancole-blobstore0/apples"), 411,
|
||||||
|
"HTTP/1.1 304 The condition specified using HTTP conditional header(s) is not met.", "application/unknown",
|
||||||
|
"", 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) {
|
||||||
|
|
||||||
ParseAzureStorageErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() {
|
ParseAzureStorageErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() {
|
||||||
|
|
||||||
|
@ -70,7 +90,7 @@ public class ParseAzureErrorFromXmlContentTest {
|
||||||
HttpCommand command = createMock(HttpCommand.class);
|
HttpCommand command = createMock(HttpCommand.class);
|
||||||
HttpRequest request = new HttpRequest(method, uri);
|
HttpRequest request = new HttpRequest(method, uri);
|
||||||
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils
|
HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Utils
|
||||||
.toInputStream(content)));
|
.toInputStream(content)));
|
||||||
response.getPayload().getContentMetadata().setContentType(contentType);
|
response.getPayload().getContentMetadata().setContentType(contentType);
|
||||||
|
|
||||||
expect(command.getRequest()).andReturn(request).atLeastOnce();
|
expect(command.getRequest()).andReturn(request).atLeastOnce();
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ public interface ComputeService {
|
||||||
* default, equivalent to {@code templateBuilder().any().options(templateOptions)}.
|
* default, equivalent to {@code templateBuilder().any().options(templateOptions)}.
|
||||||
*/
|
*/
|
||||||
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, TemplateOptions templateOptions)
|
Set<? extends NodeMetadata> runNodesWithTag(String tag, int count, TemplateOptions templateOptions)
|
||||||
throws RunNodesException;
|
throws RunNodesException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like {@link ComputeService#runNodesWithTag(String,int,TemplateOptions)}, except that the
|
* Like {@link ComputeService#runNodesWithTag(String,int,TemplateOptions)}, except that the
|
||||||
|
@ -148,6 +148,10 @@ public interface ComputeService {
|
||||||
/**
|
/**
|
||||||
* resume the node from {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state,
|
* resume the node from {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state,
|
||||||
* given its id.
|
* given its id.
|
||||||
|
*
|
||||||
|
* <h4>note</h4>
|
||||||
|
*
|
||||||
|
* affected nodes may not resume with the same IP address(es)
|
||||||
*/
|
*/
|
||||||
void resumeNode(String id);
|
void resumeNode(String id);
|
||||||
|
|
||||||
|
@ -155,6 +159,10 @@ public interface ComputeService {
|
||||||
* nodes matching the filter are treated as a logical set. Using the resume command, you can save
|
* nodes matching the filter are treated as a logical set. Using the resume command, you can save
|
||||||
* time by resumeing the nodes in parallel.
|
* time by resumeing the nodes in parallel.
|
||||||
*
|
*
|
||||||
|
* <h4>note</h4>
|
||||||
|
*
|
||||||
|
* affected nodes may not resume with the same IP address(es)
|
||||||
|
*
|
||||||
* @throws UnsupportedOperationException
|
* @throws UnsupportedOperationException
|
||||||
* if the underlying provider doesn't support suspend/resume
|
* if the underlying provider doesn't support suspend/resume
|
||||||
*/
|
*/
|
||||||
|
@ -164,6 +172,10 @@ public interface ComputeService {
|
||||||
* suspend the node, given its id. This will result in
|
* suspend the node, given its id. This will result in
|
||||||
* {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state.
|
* {@link org.jclouds.compute.domain.NodeState#SUSPENDED suspended} state.
|
||||||
*
|
*
|
||||||
|
* <h4>note</h4>
|
||||||
|
*
|
||||||
|
* affected nodes may not resume with the same IP address(es)
|
||||||
|
*
|
||||||
* @throws UnsupportedOperationException
|
* @throws UnsupportedOperationException
|
||||||
* if the underlying provider doesn't support suspend/resume
|
* if the underlying provider doesn't support suspend/resume
|
||||||
*/
|
*/
|
||||||
|
@ -173,6 +185,9 @@ public interface ComputeService {
|
||||||
* nodes matching the filter are treated as a logical set. Using the suspend command, you can
|
* nodes matching the filter are treated as a logical set. Using the suspend command, you can
|
||||||
* save time by suspending the nodes in parallel.
|
* save time by suspending the nodes in parallel.
|
||||||
*
|
*
|
||||||
|
* <h4>note</h4>
|
||||||
|
*
|
||||||
|
* affected nodes may not resume with the same IP address(es)
|
||||||
*/
|
*/
|
||||||
void suspendNodesMatching(Predicate<NodeMetadata> filter);
|
void suspendNodesMatching(Predicate<NodeMetadata> filter);
|
||||||
|
|
||||||
|
@ -224,7 +239,7 @@ public interface ComputeService {
|
||||||
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
* @see org.jclouds.compute.predicates.NodePredicates#runningWithTag(String)
|
||||||
*/
|
*/
|
||||||
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript)
|
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter, Payload runScript)
|
||||||
throws RunScriptOnNodesException;
|
throws RunScriptOnNodesException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the script on all nodes with the specific tag.
|
* Run the script on all nodes with the specific tag.
|
||||||
|
@ -243,6 +258,6 @@ public interface ComputeService {
|
||||||
* @see org.jclouds.io.Payloads
|
* @see org.jclouds.io.Payloads
|
||||||
*/
|
*/
|
||||||
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
Map<? extends NodeMetadata, ExecResponse> runScriptOnNodesMatching(Predicate<NodeMetadata> filter,
|
||||||
Payload runScript, RunScriptOptions options) throws RunScriptOnNodesException;
|
Payload runScript, RunScriptOptions options) throws RunScriptOnNodesException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,4 +44,5 @@ public interface Utils extends org.jclouds.rest.Utils {
|
||||||
* @return function that gets an ssh client for a node that is available via ssh.
|
* @return function that gets an ssh client for a node that is available via ssh.
|
||||||
*/
|
*/
|
||||||
Function<NodeMetadata, SshClient> sshForNode();
|
Function<NodeMetadata, SshClient> sshForNode();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,9 +35,12 @@ import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
|
import org.jclouds.compute.functions.CreateSshClientOncePortIsListeningOnNode;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.domain.Location;
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
import org.jclouds.rest.AuthorizationException;
|
import org.jclouds.rest.AuthorizationException;
|
||||||
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
|
@ -70,13 +73,20 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule {
|
||||||
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null)).in(Scopes.SINGLETON);
|
bind(LoadBalancerService.class).toProvider(Providers.<LoadBalancerService> of(null)).in(Scopes.SINGLETON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public Map<OsFamily, Map<String, String>> provideOsVersionMap(ComputeServiceConstants.ReferenceData data, Json json) {
|
||||||
|
return json.fromJson(data.osVersionMapJson, new TypeLiteral<Map<OsFamily, Map<String, String>>>() {
|
||||||
|
}.getType());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default template if none is provided.
|
* The default template if none is provided.
|
||||||
*/
|
*/
|
||||||
@Provides
|
@Provides
|
||||||
@Named("DEFAULT")
|
@Named("DEFAULT")
|
||||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
return template.osFamily(UBUNTU);
|
return template.osFamily(UBUNTU).osVersionMatches("10.04").os64Bit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -83,7 +83,6 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.scriptbuilder.InitBuilder;
|
|
||||||
import org.jclouds.scriptbuilder.domain.Statements;
|
import org.jclouds.scriptbuilder.domain.Statements;
|
||||||
import org.jclouds.ssh.ExecResponse;
|
import org.jclouds.ssh.ExecResponse;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
|
@ -175,9 +174,6 @@ public class BaseComputeService implements ComputeService {
|
||||||
throws RunNodesException {
|
throws RunNodesException {
|
||||||
checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens");
|
checkArgument(tag.indexOf('-') == -1, "tag cannot contain hyphens");
|
||||||
checkNotNull(template.getLocation(), "location");
|
checkNotNull(template.getLocation(), "location");
|
||||||
if (template.getOptions().getTaskName() == null && template.getOptions().getRunScript() != null
|
|
||||||
&& !(template.getOptions().getRunScript() instanceof InitBuilder))
|
|
||||||
template.getOptions().nameTask("bootstrap");
|
|
||||||
logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count,
|
logger.debug(">> running %d node%s tag(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count,
|
||||||
count > 1 ? "s" : "", tag, template.getLocation().getId(), template.getImage().getId(), template
|
count > 1 ? "s" : "", tag, template.getLocation().getId(), template.getImage().getId(), template
|
||||||
.getHardware().getId(), template.getOptions());
|
.getHardware().getId(), template.getOptions());
|
||||||
|
|
|
@ -38,10 +38,28 @@ public interface ComputeServiceConstants {
|
||||||
public static final String PROPERTY_TIMEOUT_SCRIPT_COMPLETE = "jclouds.compute.timeout.script-complete";
|
public static final String PROPERTY_TIMEOUT_SCRIPT_COMPLETE = "jclouds.compute.timeout.script-complete";
|
||||||
public static final String PROPERTY_TIMEOUT_PORT_OPEN = "jclouds.compute.timeout.port-open";
|
public static final String PROPERTY_TIMEOUT_PORT_OPEN = "jclouds.compute.timeout.port-open";
|
||||||
/**
|
/**
|
||||||
* comma-separated nodes that we shouldn't attempt to list as they are dead
|
* comma-separated nodes that we shouldn't attempt to list as they are dead in the provider for
|
||||||
* in the provider for some reason.
|
* some reason.
|
||||||
*/
|
*/
|
||||||
public static final String PROPERTY_BLACKLIST_NODES = "jclouds.compute.blacklist.nodes";
|
public static final String PROPERTY_BLACKLIST_NODES = "jclouds.compute.blacklist-nodes";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* os to map of version input string to output string
|
||||||
|
* <p/>
|
||||||
|
* ex.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* {"centos":{"5.4":"5.4","5.5":"5.5"},"rhel":{"5.4":"5.4","5.5":"5.5"},"ubuntu":{"karmic":"9.10","lucid":"10.04","maverick":"10.10","natty":"11.04"},"windows":{"2008":"2008","Server 2008":"2008","2008 R2":"2008 R2","Server 2008 R2":"2008 R2","2008 SP2":"2008 SP2","Server 2008 SP2":"2008 SP2"}}
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public static final String PROPERTY_OS_VERSION_MAP_JSON = "jclouds.compute.os-version-map-json";
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static class ReferenceData {
|
||||||
|
@Inject(optional = true)
|
||||||
|
@Named(PROPERTY_OS_VERSION_MAP_JSON)
|
||||||
|
public String osVersionMapJson = "{\"centos\":{\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"rhel\":{\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"ubuntu\":{\"hardy\":\"8.04\",\"karmic\":\"9.10\",\"lucid\":\"10.04\",\"maverick\":\"10.10\",\"natty\":\"11.04\"},\"windows\":{\"2003\":\"2003\",\"2003 Standard\":\"2003\",\"2008\":\"2008\",\"2008 Web\":\"2008\",\"Server 2008\":\"2008\",\"2008 R2\":\"2008 R2\",\"Server 2008 R2\":\"2008 R2\",\"2008 Server R2\":\"2008 R2\",\"2008 SP2\":\"2008 SP2\",\"Server 2008 SP2\":\"2008 SP2\"}}";
|
||||||
|
}
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class Timeouts {
|
public static class Timeouts {
|
||||||
|
@ -52,11 +70,11 @@ public interface ComputeServiceConstants {
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
@Named(PROPERTY_TIMEOUT_NODE_RUNNING)
|
@Named(PROPERTY_TIMEOUT_NODE_RUNNING)
|
||||||
public long nodeRunning = 1200 * 1000;
|
public long nodeRunning = 1200 * 1000;
|
||||||
|
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
@Named(PROPERTY_TIMEOUT_NODE_SUSPENDED)
|
@Named(PROPERTY_TIMEOUT_NODE_SUSPENDED)
|
||||||
public long nodeSuspended = 30 * 1000;
|
public long nodeSuspended = 30 * 1000;
|
||||||
|
|
||||||
@Inject(optional = true)
|
@Inject(optional = true)
|
||||||
@Named(PROPERTY_TIMEOUT_SCRIPT_COMPLETE)
|
@Named(PROPERTY_TIMEOUT_SCRIPT_COMPLETE)
|
||||||
public long scriptComplete = 600 * 1000;
|
public long scriptComplete = 600 * 1000;
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
package org.jclouds.compute.stub.config;
|
package org.jclouds.compute.stub.config;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -46,6 +48,7 @@ import org.jclouds.rest.ResourceNotFoundException;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -60,12 +63,13 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
private final String privateIpPrefix;
|
private final String privateIpPrefix;
|
||||||
private final String passwordPrefix;
|
private final String passwordPrefix;
|
||||||
private final String providerName;
|
private final String providerName;
|
||||||
|
private final Map<OsFamily, Map<String, String>> osToVersionMap;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes, Supplier<Location> location,
|
public StubComputeServiceAdapter(ConcurrentMap<String, NodeMetadata> nodes, Supplier<Location> location,
|
||||||
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
|
@Named("NODE_ID") Provider<Integer> idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix,
|
||||||
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
|
@Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix,
|
||||||
@org.jclouds.rest.annotations.Provider String providerName) {
|
@org.jclouds.rest.annotations.Provider String providerName, Map<OsFamily, Map<String, String>> osToVersionMap) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
this.idProvider = idProvider;
|
this.idProvider = idProvider;
|
||||||
|
@ -73,11 +77,12 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
this.privateIpPrefix = privateIpPrefix;
|
this.privateIpPrefix = privateIpPrefix;
|
||||||
this.passwordPrefix = passwordPrefix;
|
this.passwordPrefix = passwordPrefix;
|
||||||
this.providerName = providerName;
|
this.providerName = providerName;
|
||||||
|
this.osToVersionMap = osToVersionMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template,
|
public NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template,
|
||||||
Map<String, Credentials> credentialStore) {
|
Map<String, Credentials> credentialStore) {
|
||||||
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||||
String id = idProvider.get() + "";
|
String id = idProvider.get() + "";
|
||||||
builder.ids(id);
|
builder.ids(id);
|
||||||
|
@ -100,8 +105,8 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Hardware> listHardwareProfiles() {
|
public Iterable<Hardware> listHardwareProfiles() {
|
||||||
return ImmutableSet.<Hardware> of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160),
|
return ImmutableSet.<Hardware> of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160),
|
||||||
StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), StubComputeServiceDependenciesModule
|
StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850),
|
||||||
.stub("large", 8, 15360, 1690));
|
StubComputeServiceDependenciesModule.stub("large", 8, 15360, 1690));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,20 +114,19 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
Location zone = location.get().getParent();
|
Location zone = location.get().getParent();
|
||||||
String parentId = zone.getId();
|
String parentId = zone.getId();
|
||||||
Credentials defaultCredentials = new Credentials("root", null);
|
Credentials defaultCredentials = new Credentials("root", null);
|
||||||
return ImmutableSet.<Image> of(new ImageBuilder().providerId("1").name(OsFamily.UBUNTU.name())
|
Set<Image> images = Sets.newLinkedHashSet();
|
||||||
.id(parentId + "/1").location(zone).operatingSystem(
|
int id = 1;
|
||||||
new OperatingSystem(OsFamily.UBUNTU, "ubuntu 32", null, "X86_32", "ubuntu 32", false))
|
for (boolean is64Bit : new boolean[] { true, false })
|
||||||
.description("stub ubuntu 32").defaultCredentials(defaultCredentials).build(), //
|
for (Entry<OsFamily, Map<String, String>> osVersions : this.osToVersionMap.entrySet()) {
|
||||||
new ImageBuilder().providerId("2").name(OsFamily.UBUNTU.name()).id(parentId + "/2").location(zone)
|
for (String version : Sets.newHashSet(osVersions.getValue().values())) {
|
||||||
.operatingSystem(
|
String desc = String.format("stub %s %s", osVersions.getKey(), is64Bit);
|
||||||
new OperatingSystem(OsFamily.UBUNTU, "ubuntu 64", null, "X86_64", "ubuntu 64", true))
|
images.add(new ImageBuilder().providerId(id + "").name(osVersions.getKey().name())
|
||||||
.description("stub ubuntu 64").defaultCredentials(defaultCredentials).build(), //
|
.id(parentId + "/" + id++).location(zone)
|
||||||
new ImageBuilder().providerId("3").name(OsFamily.CENTOS.name()).id(parentId + "/3").location(zone)
|
.operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit))
|
||||||
.operatingSystem(
|
.description(desc).defaultCredentials(defaultCredentials).build());
|
||||||
new OperatingSystem(OsFamily.CENTOS, "centos 64", null, "X86_64", "centos 64", true))
|
}
|
||||||
.description("stub centos 64").defaultCredentials(defaultCredentials).build() //
|
}
|
||||||
|
return images;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -134,9 +138,9 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda
|
||||||
public Iterable<Location> listLocations() {
|
public Iterable<Location> listLocations() {
|
||||||
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null);
|
||||||
Location region = new LocationImpl(LocationScope.REGION, providerName + "region", providerName + "region",
|
Location region = new LocationImpl(LocationScope.REGION, providerName + "region", providerName + "region",
|
||||||
provider);
|
provider);
|
||||||
return ImmutableSet.<Location> of(new LocationImpl(LocationScope.ZONE, providerName + "zone", providerName
|
return ImmutableSet.<Location> of(new LocationImpl(LocationScope.ZONE, providerName + "zone", providerName
|
||||||
+ "zone", region));
|
+ "zone", region));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -38,7 +38,6 @@ import java.util.concurrent.Callable;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
@ -56,7 +55,7 @@ import org.jclouds.ssh.SshClient;
|
||||||
|
|
||||||
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.ImmutableMap;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -131,33 +130,6 @@ public class ComputeServiceUtils {
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Map<org.jclouds.compute.domain.OsFamily, Map<String, String>> NAME_VERSION_MAP = ImmutableMap
|
|
||||||
.<org.jclouds.compute.domain.OsFamily, Map<String, String>> of(
|
|
||||||
org.jclouds.compute.domain.OsFamily.CENTOS,
|
|
||||||
ImmutableMap.<String, String> builder().put("5.3", "5.3").put("5.4", "5.4").put("5.5", "5.5").build(),
|
|
||||||
org.jclouds.compute.domain.OsFamily.RHEL,
|
|
||||||
ImmutableMap.<String, String> builder().put("5.3", "5.3").put("5.4", "5.4").put("5.5", "5.5").build(),
|
|
||||||
org.jclouds.compute.domain.OsFamily.UBUNTU,
|
|
||||||
ImmutableMap.<String, String> builder().put("hardy", "8.04").put("intrepid", "8.10")
|
|
||||||
.put("jaunty", "9.04").put("karmic", "9.10").put("lucid", "10.04").put("maverick", "10.10")
|
|
||||||
.put("natty", "11.04").build());
|
|
||||||
|
|
||||||
public static String parseVersionOrReturnEmptyString(org.jclouds.compute.domain.OsFamily family, final String in) {
|
|
||||||
if (NAME_VERSION_MAP.containsKey(family)) {
|
|
||||||
CONTAINS_SUBSTRING contains = new CONTAINS_SUBSTRING(in.replace('-', '.'));
|
|
||||||
try {
|
|
||||||
String key = find(NAME_VERSION_MAP.get(family).keySet(), contains);
|
|
||||||
return NAME_VERSION_MAP.get(family).get(key);
|
|
||||||
} catch (NoSuchElementException e) {
|
|
||||||
try {
|
|
||||||
return find(NAME_VERSION_MAP.get(family).values(), contains);
|
|
||||||
} catch (NoSuchElementException e1) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static org.jclouds.compute.domain.OsFamily parseOsFamilyOrNull(String provider, String in) {
|
public static org.jclouds.compute.domain.OsFamily parseOsFamilyOrNull(String provider, String in) {
|
||||||
org.jclouds.compute.domain.OsFamily myOs = null;
|
org.jclouds.compute.domain.OsFamily myOs = null;
|
||||||
for (org.jclouds.compute.domain.OsFamily os : org.jclouds.compute.domain.OsFamily.values()) {
|
for (org.jclouds.compute.domain.OsFamily os : org.jclouds.compute.domain.OsFamily.values()) {
|
||||||
|
@ -201,19 +173,6 @@ public class ComputeServiceUtils {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class CONTAINS_SUBSTRING implements Predicate<String> {
|
|
||||||
private final String in;
|
|
||||||
|
|
||||||
private CONTAINS_SUBSTRING(String in) {
|
|
||||||
this.in = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(String input) {
|
|
||||||
return in.indexOf(input) != -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static interface SshCallable<T> extends Callable<T> {
|
public static interface SshCallable<T> extends Callable<T> {
|
||||||
NodeMetadata getNode();
|
NodeMetadata getNode();
|
||||||
|
|
||||||
|
@ -249,4 +208,36 @@ public class ComputeServiceUtils {
|
||||||
"node does not have IP addresses configured: " + node);
|
"node does not have IP addresses configured: " + node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String parseVersionOrReturnEmptyString(org.jclouds.compute.domain.OsFamily family, final String in,
|
||||||
|
Map<OsFamily, Map<String, String>> osVersionMap) {
|
||||||
|
if (osVersionMap.containsKey(family)) {
|
||||||
|
if (osVersionMap.get(family).containsKey(in))
|
||||||
|
return osVersionMap.get(family).get(in);
|
||||||
|
CONTAINS_SUBSTRING contains = new CONTAINS_SUBSTRING(in.replace('-', '.'));
|
||||||
|
try {
|
||||||
|
String key = Iterables.find(osVersionMap.get(family).keySet(), contains);
|
||||||
|
return osVersionMap.get(family).get(key);
|
||||||
|
} catch (NoSuchElementException e) {
|
||||||
|
try {
|
||||||
|
return Iterables.find(osVersionMap.get(family).values(), contains);
|
||||||
|
} catch (NoSuchElementException e1) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class CONTAINS_SUBSTRING implements Predicate<String> {
|
||||||
|
private final String in;
|
||||||
|
|
||||||
|
CONTAINS_SUBSTRING(String in) {
|
||||||
|
this.in = in;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String input) {
|
||||||
|
return in.indexOf(input) != -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||||
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
|
import org.jclouds.compute.util.ComputeServiceUtils.SshCallable;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
import org.jclouds.scriptbuilder.InitBuilder;
|
||||||
import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey;
|
import org.jclouds.scriptbuilder.domain.AuthorizeRSAPublicKey;
|
||||||
import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey;
|
import org.jclouds.scriptbuilder.domain.InstallRSAPrivateKey;
|
||||||
import org.jclouds.scriptbuilder.domain.Statement;
|
import org.jclouds.scriptbuilder.domain.Statement;
|
||||||
|
@ -144,8 +145,11 @@ public class ComputeUtils {
|
||||||
bootstrap.add(options.getRunScript());
|
bootstrap.add(options.getRunScript());
|
||||||
if (options.getPrivateKey() != null)
|
if (options.getPrivateKey() != null)
|
||||||
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
bootstrap.add(new InstallRSAPrivateKey(options.getPrivateKey()));
|
||||||
if (bootstrap.size() >= 1)
|
if (bootstrap.size() >= 1) {
|
||||||
|
if (options.getTaskName() == null && !(options.getRunScript() instanceof InitBuilder))
|
||||||
|
options.nameTask("bootstrap");
|
||||||
runScriptOnNode(node, bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap), options);
|
runScriptOnNode(node, bootstrap.size() == 1 ? bootstrap.get(0) : new StatementList(bootstrap), options);
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,8 +161,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
if (context != null)
|
if (context != null)
|
||||||
context.close();
|
context.close();
|
||||||
Properties props = setupProperties();
|
Properties props = setupProperties();
|
||||||
context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.of(new Log4JLoggingModule(),
|
context = new ComputeServiceContextFactory().createContext(provider,
|
||||||
getSshModule()), props);
|
ImmutableSet.of(new Log4JLoggingModule(), getSshModule()), props);
|
||||||
client = context.getComputeService();
|
client = context.getComputeService();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,8 +173,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
public void testCorrectAuthException() throws Exception {
|
public void testCorrectAuthException() throws Exception {
|
||||||
ComputeServiceContext context = null;
|
ComputeServiceContext context = null;
|
||||||
try {
|
try {
|
||||||
context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA", ImmutableSet
|
context = new ComputeServiceContextFactory().createContext(provider, "MOMMA", "MIA",
|
||||||
.<Module> of(new Log4JLoggingModule()));
|
ImmutableSet.<Module> of(new Log4JLoggingModule()));
|
||||||
context.getComputeService().listNodes();
|
context.getComputeService().listNodes();
|
||||||
} catch (AuthorizationException e) {
|
} catch (AuthorizationException e) {
|
||||||
throw e;
|
throw e;
|
||||||
|
@ -217,7 +217,7 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
OperatingSystem os = get(nodes, 0).getOperatingSystem();
|
OperatingSystem os = get(nodes, 0).getOperatingSystem();
|
||||||
try {
|
try {
|
||||||
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, os, new Credentials(
|
Map<? extends NodeMetadata, ExecResponse> responses = runScriptWithCreds(tag, os, new Credentials(
|
||||||
good.identity, "romeo"));
|
good.identity, "romeo"));
|
||||||
assert false : "shouldn't pass with a bad password\n" + responses;
|
assert false : "shouldn't pass with a bad password\n" + responses;
|
||||||
} catch (RunScriptOnNodesException e) {
|
} catch (RunScriptOnNodesException e) {
|
||||||
assert getRootCause(e).getMessage().contains("Auth fail") : e;
|
assert getRootCause(e).getMessage().contains("Auth fail") : e;
|
||||||
|
@ -276,7 +276,7 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
template = buildTemplate(client.templateBuilder());
|
template = buildTemplate(client.templateBuilder());
|
||||||
|
|
||||||
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
|
template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public"))
|
||||||
.runScript(buildScript(template.getImage().getOperatingSystem()));
|
.runScript(buildScript(template.getImage().getOperatingSystem()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void checkImageIdMatchesTemplate(NodeMetadata node) {
|
protected void checkImageIdMatchesTemplate(NodeMetadata node) {
|
||||||
|
@ -287,8 +287,8 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
protected void checkOsMatchesTemplate(NodeMetadata node) {
|
protected void checkOsMatchesTemplate(NodeMetadata node) {
|
||||||
if (node.getOperatingSystem() != null)
|
if (node.getOperatingSystem() != null)
|
||||||
assert node.getOperatingSystem().getFamily().equals(template.getImage().getOperatingSystem().getFamily()) : String
|
assert node.getOperatingSystem().getFamily().equals(template.getImage().getOperatingSystem().getFamily()) : String
|
||||||
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(), node
|
.format("expecting family %s but got %s", template.getImage().getOperatingSystem().getFamily(),
|
||||||
.getOperatingSystem());
|
node.getOperatingSystem());
|
||||||
}
|
}
|
||||||
|
|
||||||
void assertLocationSameOrChild(Location test, Location expected) {
|
void assertLocationSameOrChild(Location test, Location expected) {
|
||||||
|
@ -320,10 +320,11 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag, OperatingSystem os,
|
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(final String tag, OperatingSystem os,
|
||||||
Credentials creds) throws RunScriptOnNodesException {
|
Credentials creds) throws RunScriptOnNodesException {
|
||||||
try {
|
try {
|
||||||
return client.runScriptOnNodesMatching(runningWithTag(tag), newStringPayload(buildScript(os).render(
|
return client.runScriptOnNodesMatching(runningWithTag(tag),
|
||||||
OsFamily.UNIX)), overrideCredentialsWith(creds).nameTask("runScriptWithCreds"));
|
newStringPayload(buildScript(os).render(OsFamily.UNIX)),
|
||||||
|
overrideCredentialsWith(creds).nameTask("runScriptWithCreds"));
|
||||||
} catch (SshException e) {
|
} catch (SshException e) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
@ -353,16 +354,16 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
@Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired")
|
||||||
public void testGet() throws Exception {
|
public void testGet() throws Exception {
|
||||||
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(filter(client
|
Map<String, ? extends NodeMetadata> metadataMap = newLinkedHashMap(uniqueIndex(
|
||||||
.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))),
|
filter(client.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))),
|
||||||
new Function<NodeMetadata, String>() {
|
new Function<NodeMetadata, String>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String apply(NodeMetadata from) {
|
public String apply(NodeMetadata from) {
|
||||||
return from.getId();
|
return from.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
}));
|
}));
|
||||||
for (NodeMetadata node : nodes) {
|
for (NodeMetadata node : nodes) {
|
||||||
metadataMap.remove(node.getId());
|
metadataMap.remove(node.getId());
|
||||||
NodeMetadata metadata = client.getNodeMetadata(node.getId());
|
NodeMetadata metadata = client.getNodeMetadata(node.getId());
|
||||||
|
@ -372,15 +373,16 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
checkImageIdMatchesTemplate(metadata);
|
checkImageIdMatchesTemplate(metadata);
|
||||||
checkOsMatchesTemplate(metadata);
|
checkOsMatchesTemplate(metadata);
|
||||||
assertEquals(metadata.getState(), NodeState.RUNNING);
|
assertEquals(metadata.getState(), NodeState.RUNNING);
|
||||||
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
|
// due to DHCP the addresses can actually change in-between runs.
|
||||||
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
|
assertEquals(metadata.getPrivateAddresses().size(), node.getPrivateAddresses().size());
|
||||||
|
assertEquals(metadata.getPublicAddresses().size(), node.getPublicAddresses().size());
|
||||||
}
|
}
|
||||||
assertNodeZero(metadataMap.values());
|
assertNodeZero(metadataMap.values());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void assertNodeZero(Collection<? extends NodeMetadata> metadataSet) {
|
protected void assertNodeZero(Collection<? extends NodeMetadata> metadataSet) {
|
||||||
assert metadataSet.size() == 0 : String.format("nodes left in set: [%s] which didn't match set: [%s]",
|
assert metadataSet.size() == 0 : String.format("nodes left in set: [%s] which didn't match set: [%s]",
|
||||||
metadataSet, nodes);
|
metadataSet, nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = "testGet")
|
@Test(enabled = true, dependsOnMethods = "testGet")
|
||||||
|
@ -393,16 +395,20 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
@Test(enabled = true, dependsOnMethods = "testReboot")
|
@Test(enabled = true, dependsOnMethods = "testReboot")
|
||||||
public void testSuspendResume() throws Exception {
|
public void testSuspendResume() throws Exception {
|
||||||
client.suspendNodesMatching(withTag(tag));
|
client.suspendNodesMatching(withTag(tag));
|
||||||
|
|
||||||
Set<? extends NodeMetadata> stoppedNodes = refreshNodes();
|
Set<? extends NodeMetadata> stoppedNodes = refreshNodes();
|
||||||
|
|
||||||
assert Iterables.all(stoppedNodes, new Predicate<NodeMetadata>() {
|
assert Iterables.all(stoppedNodes, new Predicate<NodeMetadata>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(NodeMetadata input) {
|
public boolean apply(NodeMetadata input) {
|
||||||
return input.getState() == NodeState.SUSPENDED;
|
boolean returnVal = input.getState() == NodeState.SUSPENDED;
|
||||||
|
if (!returnVal)
|
||||||
|
System.err.printf("warning: node %s in state %s%n", input.getId(), input.getState());
|
||||||
|
return returnVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
}) : nodes;
|
}) : stoppedNodes;
|
||||||
|
|
||||||
client.resumeNodesMatching(withTag(tag));
|
client.resumeNodesMatching(withTag(tag));
|
||||||
testGet();
|
testGet();
|
||||||
|
@ -462,11 +468,11 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
template = client.templateBuilder().options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
|
template = client.templateBuilder().options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
|
||||||
.build();
|
.build();
|
||||||
// note this is a dependency on the template resolution
|
// note this is a dependency on the template resolution
|
||||||
template.getOptions().runScript(
|
template.getOptions().runScript(
|
||||||
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
|
RunScriptData.createScriptInstallAndStartJBoss(keyPair.get("public"), template.getImage()
|
||||||
.getOperatingSystem()));
|
.getOperatingSystem()));
|
||||||
try {
|
try {
|
||||||
NodeMetadata node = getOnlyElement(client.runNodesWithTag(tag, 1, template));
|
NodeMetadata node = getOnlyElement(client.runNodesWithTag(tag, 1, template));
|
||||||
|
|
||||||
|
@ -500,26 +506,26 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
assert location != location.getParent() : location;
|
assert location != location.getParent() : location;
|
||||||
assert location.getScope() != null : location;
|
assert location.getScope() != null : location;
|
||||||
switch (location.getScope()) {
|
switch (location.getScope()) {
|
||||||
case PROVIDER:
|
case PROVIDER:
|
||||||
assertProvider(location);
|
assertProvider(location);
|
||||||
break;
|
break;
|
||||||
case REGION:
|
case REGION:
|
||||||
assertProvider(location.getParent());
|
assertProvider(location.getParent());
|
||||||
break;
|
break;
|
||||||
case ZONE:
|
case ZONE:
|
||||||
Location provider = location.getParent().getParent();
|
Location provider = location.getParent().getParent();
|
||||||
// zone can be a direct descendant of provider
|
// zone can be a direct descendant of provider
|
||||||
if (provider == null)
|
if (provider == null)
|
||||||
provider = location.getParent();
|
provider = location.getParent();
|
||||||
assertProvider(provider);
|
assertProvider(provider);
|
||||||
break;
|
break;
|
||||||
case HOST:
|
case HOST:
|
||||||
Location provider2 = location.getParent().getParent().getParent();
|
Location provider2 = location.getParent().getParent().getParent();
|
||||||
// zone can be a direct descendant of provider
|
// zone can be a direct descendant of provider
|
||||||
if (provider2 == null)
|
if (provider2 == null)
|
||||||
provider2 = location.getParent().getParent();
|
provider2 = location.getParent().getParent();
|
||||||
assertProvider(provider2);
|
assertProvider(provider2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -607,7 +613,7 @@ public abstract class BaseComputeServiceLiveTest {
|
||||||
assertEquals(hello.getOutput().trim(), "hello");
|
assertEquals(hello.getOutput().trim(), "hello");
|
||||||
ExecResponse exec = ssh.exec("java -version");
|
ExecResponse exec = ssh.exec("java -version");
|
||||||
assert exec.getError().indexOf("1.6") != -1 || exec.getOutput().indexOf("1.6") != -1 : exec + "\n"
|
assert exec.getError().indexOf("1.6") != -1 || exec.getOutput().indexOf("1.6") != -1 : exec + "\n"
|
||||||
+ ssh.exec("cat /tmp/bootstrap/stdout.log /tmp/bootstrap/stderr.log");
|
+ ssh.exec("cat /tmp/bootstrap/stdout.log /tmp/bootstrap/stderr.log");
|
||||||
} finally {
|
} finally {
|
||||||
if (ssh != null)
|
if (ssh != null)
|
||||||
ssh.disconnect();
|
ssh.disconnect();
|
||||||
|
|
|
@ -0,0 +1,173 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.compute;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
|
||||||
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeClass;
|
||||||
|
import org.testng.annotations.DataProvider;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "integration,live", testName = "compute.BaseTemplateBuilderLiveTest")
|
||||||
|
public abstract class BaseTemplateBuilderLiveTest {
|
||||||
|
|
||||||
|
protected String provider;
|
||||||
|
protected String identity;
|
||||||
|
protected String credential;
|
||||||
|
protected String endpoint;
|
||||||
|
protected String apiversion;
|
||||||
|
protected ComputeServiceContext context;
|
||||||
|
|
||||||
|
protected void setupCredentials() {
|
||||||
|
identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity");
|
||||||
|
credential = System.getProperty("test." + provider + ".credential");
|
||||||
|
endpoint = System.getProperty("test." + provider + ".endpoint");
|
||||||
|
apiversion = System.getProperty("test." + provider + ".apiversion");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Properties setupProperties() {
|
||||||
|
Properties overrides = new Properties();
|
||||||
|
overrides.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
|
||||||
|
overrides.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true");
|
||||||
|
overrides.setProperty(provider + ".identity", identity);
|
||||||
|
if (credential != null)
|
||||||
|
overrides.setProperty(provider + ".credential", credential);
|
||||||
|
if (endpoint != null)
|
||||||
|
overrides.setProperty(provider + ".endpoint", endpoint);
|
||||||
|
if (apiversion != null)
|
||||||
|
overrides.setProperty(provider + ".apiversion", apiversion);
|
||||||
|
return overrides;
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException {
|
||||||
|
setupCredentials();
|
||||||
|
context = new ComputeServiceContextFactory().createContext(provider,
|
||||||
|
ImmutableSet.<Module> of(new Log4JLoggingModule()), setupProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
@DataProvider(name = "osSupported")
|
||||||
|
public Object[][] osSupported() {
|
||||||
|
return convertToArray(Sets.filter(provideAllOperatingSystems(),
|
||||||
|
Predicates.not(defineUnsupportedOperatingSystems())));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object[][] convertToArray(Set<OsFamilyVersion64Bit> supportedOperatingSystems) {
|
||||||
|
Object[][] returnVal = new Object[supportedOperatingSystems.size()][1];
|
||||||
|
int i = 0;
|
||||||
|
for (OsFamilyVersion64Bit config : supportedOperatingSystems)
|
||||||
|
returnVal[i++][0] = config;
|
||||||
|
return returnVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||||
|
return Predicates.alwaysFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DataProvider(name = "osNotSupported")
|
||||||
|
public Object[][] osNotSupported() {
|
||||||
|
return convertToArray(Sets.filter(provideAllOperatingSystems(), defineUnsupportedOperatingSystems()));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Set<OsFamilyVersion64Bit> provideAllOperatingSystems() {
|
||||||
|
Map<OsFamily, Map<String, String>> map = new BaseComputeServiceContextModule() {
|
||||||
|
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
|
||||||
|
.getInstance(Json.class));
|
||||||
|
|
||||||
|
Set<OsFamilyVersion64Bit> supportedOperatingSystems = Sets.newHashSet();
|
||||||
|
for (Entry<OsFamily, Map<String, String>> osVersions : map.entrySet()) {
|
||||||
|
for (String version : Sets.newHashSet(osVersions.getValue().values())) {
|
||||||
|
supportedOperatingSystems.add(new OsFamilyVersion64Bit(osVersions.getKey(), version, false));
|
||||||
|
supportedOperatingSystems.add(new OsFamilyVersion64Bit(osVersions.getKey(), version, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return supportedOperatingSystems;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "osSupported")
|
||||||
|
public void testTemplateBuilderCanFind(OsFamilyVersion64Bit matrix) throws InterruptedException {
|
||||||
|
Template template = context.getComputeService().templateBuilder().osFamily(matrix.family)
|
||||||
|
.osVersionMatches("^" + matrix.version + "$").os64Bit(matrix.is64Bit).build();
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().getVersion(), matrix.version);
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().is64Bit(), matrix.is64Bit);
|
||||||
|
assertEquals(template.getImage().getOperatingSystem().getFamily(), matrix.family);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dataProvider = "osNotSupported", expectedExceptions = NoSuchElementException.class)
|
||||||
|
public void testTemplateBuilderCannotFind(OsFamilyVersion64Bit matrix) throws InterruptedException {
|
||||||
|
context.getComputeService().templateBuilder().osFamily(matrix.family)
|
||||||
|
.osVersionMatches("^" + matrix.version + "$").os64Bit(matrix.is64Bit).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTemplateBuilderCanUseImageId() {
|
||||||
|
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||||
|
|
||||||
|
Template template = context.getComputeService().templateBuilder().imageId(defaultTemplate.getImage().getId())
|
||||||
|
.build();
|
||||||
|
assertEquals(template.getImage(), defaultTemplate.getImage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultTemplateBuilder() throws IOException {
|
||||||
|
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterTest
|
||||||
|
protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.compute;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
|
||||||
|
public class OsFamilyVersion64Bit {
|
||||||
|
public final OsFamily family;
|
||||||
|
public final String version;
|
||||||
|
public final boolean is64Bit;
|
||||||
|
|
||||||
|
public OsFamilyVersion64Bit(OsFamily family, String version, boolean is64Bit) {
|
||||||
|
this.family = family;
|
||||||
|
this.version = version;
|
||||||
|
this.is64Bit = is64Bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OsFamilyVersion64Bit [family=" + family + ", version=" + version + ", is64Bit=" + is64Bit + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((family == null) ? 0 : family.hashCode());
|
||||||
|
result = prime * result + (is64Bit ? 1231 : 1237);
|
||||||
|
result = prime * result + ((version == null) ? 0 : version.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
OsFamilyVersion64Bit other = (OsFamilyVersion64Bit) obj;
|
||||||
|
if (family != other.family)
|
||||||
|
return false;
|
||||||
|
if (is64Bit != other.is64Bit)
|
||||||
|
return false;
|
||||||
|
if (version == null) {
|
||||||
|
if (other.version != null)
|
||||||
|
return false;
|
||||||
|
} else if (!version.equals(other.version))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,6 @@ import static org.easymock.EasyMock.expect;
|
||||||
import static org.easymock.EasyMock.reportMatcher;
|
import static org.easymock.EasyMock.reportMatcher;
|
||||||
import static org.easymock.classextension.EasyMock.createMock;
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
import static org.easymock.classextension.EasyMock.replay;
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
@ -38,8 +37,6 @@ import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.easymock.IArgumentMatcher;
|
import org.easymock.IArgumentMatcher;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
|
||||||
import org.jclouds.compute.domain.Template;
|
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
import org.jclouds.net.IPSocket;
|
import org.jclouds.net.IPSocket;
|
||||||
|
@ -50,7 +47,6 @@ import org.jclouds.ssh.ExecResponse;
|
||||||
import org.jclouds.ssh.SshClient;
|
import org.jclouds.ssh.SshClient;
|
||||||
import org.jclouds.ssh.SshException;
|
import org.jclouds.ssh.SshException;
|
||||||
import org.jclouds.util.Utils;
|
import org.jclouds.util.Utils;
|
||||||
import org.testng.annotations.BeforeClass;
|
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
|
@ -63,15 +59,13 @@ import com.google.inject.Module;
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", enabled = true, sequential = true, testName = "stub.StubComputeServiceIntegrationTest")
|
@Test(groups = "live", testName = "stub.StubComputeServiceIntegrationTest")
|
||||||
public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTest {
|
public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
private static final ExecResponse EXEC_GOOD = new ExecResponse("", "", 0);
|
private static final ExecResponse EXEC_GOOD = new ExecResponse("", "", 0);
|
||||||
private static final ExecResponse EXEC_BAD = new ExecResponse("", "", 1);
|
private static final ExecResponse EXEC_BAD = new ExecResponse("", "", 1);
|
||||||
|
|
||||||
@BeforeClass
|
public StubComputeServiceIntegrationTest() {
|
||||||
@Override
|
|
||||||
public void setServiceDefaults() {
|
|
||||||
provider = "stub";
|
provider = "stub";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,15 +73,6 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
public void testCorrectAuthException() throws Exception {
|
public void testCorrectAuthException() throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testTemplateBuilder() {
|
|
||||||
Template defaultTemplate = client.templateBuilder().build();
|
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getArch(), "X86_64");
|
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
|
||||||
assertEquals(defaultTemplate.getLocation().getId(), provider + "zone");
|
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void buildSocketTester() {
|
protected void buildSocketTester() {
|
||||||
SocketOpen socketOpen = createMock(SocketOpen.class);
|
SocketOpen socketOpen = createMock(SocketOpen.class);
|
||||||
|
|
||||||
|
@ -121,48 +106,48 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
SshClient client5 = createMock(SshClient.class);
|
SshClient client5 = createMock(SshClient.class);
|
||||||
|
|
||||||
expect(factory.create(new IPSocket("144.175.1.1", 22), new Credentials("root", "password1"))).andReturn(
|
expect(factory.create(new IPSocket("144.175.1.1", 22), new Credentials("root", "password1"))).andReturn(
|
||||||
client1);
|
client1);
|
||||||
runScriptAndService(client1, 1);
|
runScriptAndService(client1, 1);
|
||||||
|
|
||||||
expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "password2"))).andReturn(
|
expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "password2"))).andReturn(
|
||||||
client2).times(2);
|
client2).times(2);
|
||||||
expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "romeo"))).andThrow(
|
expect(factory.create(new IPSocket("144.175.1.2", 22), new Credentials("root", "romeo"))).andThrow(
|
||||||
new SshException("Auth fail"));
|
new SshException("Auth fail"));
|
||||||
client2.connect();
|
client2.connect();
|
||||||
try {
|
try {
|
||||||
runScript(client2, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
|
runScript(client2, "runScriptWithCreds", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
|
||||||
.getResourceAsStream("/runscript.sh")), 2);
|
.getResourceAsStream("/runscript.sh")), 2);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
client2.disconnect();
|
client2.disconnect();
|
||||||
|
|
||||||
expect(factory.create(new IPSocket("144.175.1.3", 22), new Credentials("root", "password3"))).andReturn(
|
expect(factory.create(new IPSocket("144.175.1.3", 22), new Credentials("root", "password3"))).andReturn(
|
||||||
client3).times(2);
|
client3).times(2);
|
||||||
expect(factory.create(new IPSocket("144.175.1.4", 22), new Credentials("root", "password4"))).andReturn(
|
expect(factory.create(new IPSocket("144.175.1.4", 22), new Credentials("root", "password4"))).andReturn(
|
||||||
client4).times(2);
|
client4).times(2);
|
||||||
expect(factory.create(new IPSocket("144.175.1.5", 22), new Credentials("root", "password5"))).andReturn(
|
expect(factory.create(new IPSocket("144.175.1.5", 22), new Credentials("root", "password5"))).andReturn(
|
||||||
client5).times(2);
|
client5).times(2);
|
||||||
|
|
||||||
runScriptAndInstallSsh(client3, "bootstrap", 3);
|
runScriptAndInstallSsh(client3, "bootstrap", 3);
|
||||||
runScriptAndInstallSsh(client4, "bootstrap", 4);
|
runScriptAndInstallSsh(client4, "bootstrap", 4);
|
||||||
runScriptAndInstallSsh(client5, "bootstrap", 5);
|
runScriptAndInstallSsh(client5, "bootstrap", 5);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.1", 22)), eq(new Credentials("root", keyPair
|
factory.create(eq(new IPSocket("144.175.1.1", 22)),
|
||||||
.get("private"))))).andReturn(client1);
|
eq(new Credentials("root", keyPair.get("private"))))).andReturn(client1);
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.2", 22)), eq(new Credentials("root", keyPair
|
factory.create(eq(new IPSocket("144.175.1.2", 22)),
|
||||||
.get("private"))))).andReturn(client2);
|
eq(new Credentials("root", keyPair.get("private"))))).andReturn(client2);
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.3", 22)), eq(new Credentials("root", keyPair
|
factory.create(eq(new IPSocket("144.175.1.3", 22)),
|
||||||
.get("private"))))).andReturn(client3);
|
eq(new Credentials("root", keyPair.get("private"))))).andReturn(client3);
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.4", 22)), eq(new Credentials("root", keyPair
|
factory.create(eq(new IPSocket("144.175.1.4", 22)),
|
||||||
.get("private"))))).andReturn(client4);
|
eq(new Credentials("root", keyPair.get("private"))))).andReturn(client4);
|
||||||
expect(
|
expect(
|
||||||
factory.create(eq(new IPSocket("144.175.1.5", 22)), eq(new Credentials("root", keyPair
|
factory.create(eq(new IPSocket("144.175.1.5", 22)),
|
||||||
.get("private"))))).andReturn(client5);
|
eq(new Credentials("root", keyPair.get("private"))))).andReturn(client5);
|
||||||
|
|
||||||
helloAndJava(client2);
|
helloAndJava(client2);
|
||||||
helloAndJava(client3);
|
helloAndJava(client3);
|
||||||
|
@ -184,7 +169,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runScript(client, "jboss", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
|
runScript(client, "jboss", Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
|
||||||
.getResourceAsStream("/initscript_with_jboss.sh")), nodeId);
|
.getResourceAsStream("/initscript_with_jboss.sh")), nodeId);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
|
@ -198,7 +183,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
|
|
||||||
try {
|
try {
|
||||||
runScript(client, scriptName, Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
|
runScript(client, scriptName, Utils.toStringAndClose(StubComputeServiceIntegrationTest.class
|
||||||
.getResourceAsStream("/initscript_with_java.sh")), nodeId);
|
.getResourceAsStream("/initscript_with_java.sh")), nodeId);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Throwables.propagate(e);
|
Throwables.propagate(e);
|
||||||
}
|
}
|
||||||
|
@ -251,7 +236,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
public void testAssignability() throws Exception {
|
public void testAssignability() throws Exception {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
RestContext<ConcurrentMap<String, NodeMetadata>, ConcurrentMap<String, NodeMetadata>> stubContext = new ComputeServiceContextFactory()
|
RestContext<ConcurrentMap<String, NodeMetadata>, ConcurrentMap<String, NodeMetadata>> stubContext = new ComputeServiceContextFactory()
|
||||||
.createContext(provider, identity, credential).getProviderSpecificContext();
|
.createContext(provider, identity, credential).getProviderSpecificContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class PayloadEquals implements IArgumentMatcher, Serializable {
|
private static class PayloadEquals implements IArgumentMatcher, Serializable {
|
||||||
|
@ -298,7 +283,7 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
return false;
|
return false;
|
||||||
PayloadEquals other = (PayloadEquals) o;
|
PayloadEquals other = (PayloadEquals) o;
|
||||||
return this.expected == null && other.expected == null || this.expected != null
|
return this.expected == null && other.expected == null || this.expected != null
|
||||||
&& this.expected.equals(other.expected);
|
&& this.expected.equals(other.expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -321,6 +306,11 @@ public class StubComputeServiceIntegrationTest extends BaseComputeServiceLiveTes
|
||||||
super.testImagesCache();
|
super.testImagesCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testCompareSizes() throws Exception {
|
||||||
|
super.testCompareSizes();
|
||||||
|
}
|
||||||
|
|
||||||
@Test(enabled = true, dependsOnMethods = { "testImagesCache" })
|
@Test(enabled = true, dependsOnMethods = { "testImagesCache" })
|
||||||
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
|
public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
|
||||||
super.testAScriptExecutionAfterBootWithBasicTemplate();
|
super.testAScriptExecutionAfterBootWithBasicTemplate();
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.compute;
|
||||||
|
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = { "integration", "live" }, testName = "stub.StubTemplateBuilderIntegrationTest")
|
||||||
|
public class StubTemplateBuilderIntegrationTest extends BaseTemplateBuilderLiveTest {
|
||||||
|
|
||||||
|
public StubTemplateBuilderIntegrationTest() {
|
||||||
|
provider = "stub";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setupCredentials() {
|
||||||
|
identity = "stub";
|
||||||
|
credential = "stub";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,928 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Google Inc.
|
||||||
|
*
|
||||||
|
* 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 com.google.gson;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.ParameterizedType;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.sql.Time;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.MapMaker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of all the default type adapters ({@link JsonSerializer}s, {@link JsonDeserializer}s, and
|
||||||
|
* {@link InstanceCreator}s.
|
||||||
|
*
|
||||||
|
* <h4>Note!</h4>
|
||||||
|
* changed to edit the default behaviour of enum parsing by Adrian Cole
|
||||||
|
*
|
||||||
|
* @author Inderjeet Singh
|
||||||
|
* @author Joel Leitch
|
||||||
|
*/
|
||||||
|
final class JcloudsDefaultTypeAdapters {
|
||||||
|
|
||||||
|
private static final DefaultDateTypeAdapter DATE_TYPE_ADAPTER = new DefaultDateTypeAdapter();
|
||||||
|
private static final DefaultJavaSqlDateTypeAdapter JAVA_SQL_DATE_TYPE_ADAPTER = new DefaultJavaSqlDateTypeAdapter();
|
||||||
|
private static final DefaultTimeTypeAdapter TIME_TYPE_ADAPTER = new DefaultTimeTypeAdapter();
|
||||||
|
private static final DefaultTimestampDeserializer TIMESTAMP_DESERIALIZER = new DefaultTimestampDeserializer();
|
||||||
|
|
||||||
|
@SuppressWarnings({ "rawtypes" })
|
||||||
|
private static final EnumTypeAdapter ENUM_TYPE_ADAPTER = new EnumTypeAdapter();
|
||||||
|
private static final UrlTypeAdapter URL_TYPE_ADAPTER = new UrlTypeAdapter();
|
||||||
|
private static final UriTypeAdapter URI_TYPE_ADAPTER = new UriTypeAdapter();
|
||||||
|
private static final UuidTypeAdapter UUUID_TYPE_ADAPTER = new UuidTypeAdapter();
|
||||||
|
private static final LocaleTypeAdapter LOCALE_TYPE_ADAPTER = new LocaleTypeAdapter();
|
||||||
|
private static final CollectionTypeAdapter COLLECTION_TYPE_ADAPTER = new CollectionTypeAdapter();
|
||||||
|
private static final MapTypeAdapter MAP_TYPE_ADAPTER = new MapTypeAdapter();
|
||||||
|
private static final BigDecimalTypeAdapter BIG_DECIMAL_TYPE_ADAPTER = new BigDecimalTypeAdapter();
|
||||||
|
private static final BigIntegerTypeAdapter BIG_INTEGER_TYPE_ADAPTER = new BigIntegerTypeAdapter();
|
||||||
|
|
||||||
|
private static final BooleanTypeAdapter BOOLEAN_TYPE_ADAPTER = new BooleanTypeAdapter();
|
||||||
|
private static final ByteTypeAdapter BYTE_TYPE_ADAPTER = new ByteTypeAdapter();
|
||||||
|
private static final CharacterTypeAdapter CHARACTER_TYPE_ADAPTER = new CharacterTypeAdapter();
|
||||||
|
private static final DoubleDeserializer DOUBLE_TYPE_ADAPTER = new DoubleDeserializer();
|
||||||
|
private static final FloatDeserializer FLOAT_TYPE_ADAPTER = new FloatDeserializer();
|
||||||
|
private static final IntegerTypeAdapter INTEGER_TYPE_ADAPTER = new IntegerTypeAdapter();
|
||||||
|
private static final LongDeserializer LONG_DESERIALIZER = new LongDeserializer();
|
||||||
|
private static final NumberTypeAdapter NUMBER_TYPE_ADAPTER = new NumberTypeAdapter();
|
||||||
|
private static final ShortTypeAdapter SHORT_TYPE_ADAPTER = new ShortTypeAdapter();
|
||||||
|
private static final StringTypeAdapter STRING_TYPE_ADAPTER = new StringTypeAdapter();
|
||||||
|
|
||||||
|
private static final PropertiesCreator PROPERTIES_CREATOR = new PropertiesCreator();
|
||||||
|
private static final TreeSetCreator TREE_SET_CREATOR = new TreeSetCreator();
|
||||||
|
private static final HashSetCreator HASH_SET_CREATOR = new HashSetCreator();
|
||||||
|
private static final GregorianCalendarTypeAdapter GREGORIAN_CALENDAR_TYPE_ADAPTER = new GregorianCalendarTypeAdapter();
|
||||||
|
|
||||||
|
// The constants DEFAULT_SERIALIZERS, DEFAULT_DESERIALIZERS, and DEFAULT_INSTANCE_CREATORS
|
||||||
|
// must be defined after the constants for the type adapters. Otherwise, the type adapter
|
||||||
|
// constants will appear as nulls.
|
||||||
|
private static final ParameterizedTypeHandlerMap<JsonSerializer<?>> DEFAULT_SERIALIZERS = createDefaultSerializers();
|
||||||
|
private static final ParameterizedTypeHandlerMap<JsonDeserializer<?>> DEFAULT_DESERIALIZERS = createDefaultDeserializers();
|
||||||
|
private static final ParameterizedTypeHandlerMap<InstanceCreator<?>> DEFAULT_INSTANCE_CREATORS = createDefaultInstanceCreators();
|
||||||
|
|
||||||
|
private static ParameterizedTypeHandlerMap<JsonSerializer<?>> createDefaultSerializers() {
|
||||||
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> map = new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
|
||||||
|
|
||||||
|
map.registerForTypeHierarchy(Enum.class, ENUM_TYPE_ADAPTER);
|
||||||
|
map.register(URL.class, URL_TYPE_ADAPTER);
|
||||||
|
map.register(URI.class, URI_TYPE_ADAPTER);
|
||||||
|
map.register(UUID.class, UUUID_TYPE_ADAPTER);
|
||||||
|
map.register(Locale.class, LOCALE_TYPE_ADAPTER);
|
||||||
|
map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER);
|
||||||
|
map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER);
|
||||||
|
map.register(Date.class, DATE_TYPE_ADAPTER);
|
||||||
|
map.register(java.sql.Date.class, JAVA_SQL_DATE_TYPE_ADAPTER);
|
||||||
|
map.register(Timestamp.class, DATE_TYPE_ADAPTER);
|
||||||
|
map.register(Time.class, TIME_TYPE_ADAPTER);
|
||||||
|
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
||||||
|
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
||||||
|
map.register(BigDecimal.class, BIG_DECIMAL_TYPE_ADAPTER);
|
||||||
|
map.register(BigInteger.class, BIG_INTEGER_TYPE_ADAPTER);
|
||||||
|
|
||||||
|
// Add primitive serializers
|
||||||
|
map.register(Boolean.class, BOOLEAN_TYPE_ADAPTER);
|
||||||
|
map.register(boolean.class, BOOLEAN_TYPE_ADAPTER);
|
||||||
|
map.register(Byte.class, BYTE_TYPE_ADAPTER);
|
||||||
|
map.register(byte.class, BYTE_TYPE_ADAPTER);
|
||||||
|
map.register(Character.class, CHARACTER_TYPE_ADAPTER);
|
||||||
|
map.register(char.class, CHARACTER_TYPE_ADAPTER);
|
||||||
|
map.register(Integer.class, INTEGER_TYPE_ADAPTER);
|
||||||
|
map.register(int.class, INTEGER_TYPE_ADAPTER);
|
||||||
|
map.register(Number.class, NUMBER_TYPE_ADAPTER);
|
||||||
|
map.register(Short.class, SHORT_TYPE_ADAPTER);
|
||||||
|
map.register(short.class, SHORT_TYPE_ADAPTER);
|
||||||
|
map.register(String.class, STRING_TYPE_ADAPTER);
|
||||||
|
|
||||||
|
map.makeUnmodifiable();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ParameterizedTypeHandlerMap<JsonDeserializer<?>> createDefaultDeserializers() {
|
||||||
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> map = new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
|
||||||
|
map.registerForTypeHierarchy(Enum.class, wrapDeserializer(ENUM_TYPE_ADAPTER));
|
||||||
|
map.register(URL.class, wrapDeserializer(URL_TYPE_ADAPTER));
|
||||||
|
map.register(URI.class, wrapDeserializer(URI_TYPE_ADAPTER));
|
||||||
|
map.register(UUID.class, wrapDeserializer(UUUID_TYPE_ADAPTER));
|
||||||
|
map.register(Locale.class, wrapDeserializer(LOCALE_TYPE_ADAPTER));
|
||||||
|
map.registerForTypeHierarchy(Collection.class, wrapDeserializer(COLLECTION_TYPE_ADAPTER));
|
||||||
|
map.registerForTypeHierarchy(Map.class, wrapDeserializer(MAP_TYPE_ADAPTER));
|
||||||
|
map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER));
|
||||||
|
map.register(java.sql.Date.class, wrapDeserializer(JAVA_SQL_DATE_TYPE_ADAPTER));
|
||||||
|
map.register(Timestamp.class, wrapDeserializer(TIMESTAMP_DESERIALIZER));
|
||||||
|
map.register(Time.class, wrapDeserializer(TIME_TYPE_ADAPTER));
|
||||||
|
map.register(Calendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
||||||
|
map.register(GregorianCalendar.class, GREGORIAN_CALENDAR_TYPE_ADAPTER);
|
||||||
|
map.register(BigDecimal.class, wrapDeserializer(BIG_DECIMAL_TYPE_ADAPTER));
|
||||||
|
map.register(BigInteger.class, wrapDeserializer(BIG_INTEGER_TYPE_ADAPTER));
|
||||||
|
|
||||||
|
// Add primitive deserializers
|
||||||
|
map.register(Boolean.class, wrapDeserializer(BOOLEAN_TYPE_ADAPTER));
|
||||||
|
map.register(boolean.class, wrapDeserializer(BOOLEAN_TYPE_ADAPTER));
|
||||||
|
map.register(Byte.class, wrapDeserializer(BYTE_TYPE_ADAPTER));
|
||||||
|
map.register(byte.class, wrapDeserializer(BYTE_TYPE_ADAPTER));
|
||||||
|
map.register(Character.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
|
||||||
|
map.register(char.class, wrapDeserializer(CHARACTER_TYPE_ADAPTER));
|
||||||
|
map.register(Double.class, wrapDeserializer(DOUBLE_TYPE_ADAPTER));
|
||||||
|
map.register(double.class, wrapDeserializer(DOUBLE_TYPE_ADAPTER));
|
||||||
|
map.register(Float.class, wrapDeserializer(FLOAT_TYPE_ADAPTER));
|
||||||
|
map.register(float.class, wrapDeserializer(FLOAT_TYPE_ADAPTER));
|
||||||
|
map.register(Integer.class, wrapDeserializer(INTEGER_TYPE_ADAPTER));
|
||||||
|
map.register(int.class, wrapDeserializer(INTEGER_TYPE_ADAPTER));
|
||||||
|
map.register(Long.class, wrapDeserializer(LONG_DESERIALIZER));
|
||||||
|
map.register(long.class, wrapDeserializer(LONG_DESERIALIZER));
|
||||||
|
map.register(Number.class, wrapDeserializer(NUMBER_TYPE_ADAPTER));
|
||||||
|
map.register(Short.class, wrapDeserializer(SHORT_TYPE_ADAPTER));
|
||||||
|
map.register(short.class, wrapDeserializer(SHORT_TYPE_ADAPTER));
|
||||||
|
map.register(String.class, wrapDeserializer(STRING_TYPE_ADAPTER));
|
||||||
|
|
||||||
|
map.makeUnmodifiable();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ParameterizedTypeHandlerMap<InstanceCreator<?>> createDefaultInstanceCreators() {
|
||||||
|
ParameterizedTypeHandlerMap<InstanceCreator<?>> map = new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
|
||||||
|
map.registerForTypeHierarchy(Map.class, MAP_TYPE_ADAPTER);
|
||||||
|
|
||||||
|
// Add Collection type instance creators
|
||||||
|
map.registerForTypeHierarchy(Collection.class, COLLECTION_TYPE_ADAPTER);
|
||||||
|
|
||||||
|
map.registerForTypeHierarchy(Set.class, HASH_SET_CREATOR);
|
||||||
|
map.registerForTypeHierarchy(SortedSet.class, TREE_SET_CREATOR);
|
||||||
|
map.register(Properties.class, PROPERTIES_CREATOR);
|
||||||
|
map.makeUnmodifiable();
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
private static JsonDeserializer<?> wrapDeserializer(JsonDeserializer<?> deserializer) {
|
||||||
|
return new JsonDeserializerExceptionWrapper(deserializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers() {
|
||||||
|
return getDefaultSerializers(false, LongSerializationPolicy.DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParameterizedTypeHandlerMap<JsonSerializer<?>> getDefaultSerializers(
|
||||||
|
boolean serializeSpecialFloatingPointValues, LongSerializationPolicy longSerializationPolicy) {
|
||||||
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers = new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
|
||||||
|
|
||||||
|
// Double primitive
|
||||||
|
JcloudsDefaultTypeAdapters.DoubleSerializer doubleSerializer = new JcloudsDefaultTypeAdapters.DoubleSerializer(
|
||||||
|
serializeSpecialFloatingPointValues);
|
||||||
|
serializers.registerIfAbsent(Double.class, doubleSerializer);
|
||||||
|
serializers.registerIfAbsent(double.class, doubleSerializer);
|
||||||
|
|
||||||
|
// Float primitive
|
||||||
|
JcloudsDefaultTypeAdapters.FloatSerializer floatSerializer = new JcloudsDefaultTypeAdapters.FloatSerializer(
|
||||||
|
serializeSpecialFloatingPointValues);
|
||||||
|
serializers.registerIfAbsent(Float.class, floatSerializer);
|
||||||
|
serializers.registerIfAbsent(float.class, floatSerializer);
|
||||||
|
|
||||||
|
// Long primitive
|
||||||
|
JcloudsDefaultTypeAdapters.LongSerializer longSerializer = new JcloudsDefaultTypeAdapters.LongSerializer(
|
||||||
|
longSerializationPolicy);
|
||||||
|
serializers.registerIfAbsent(Long.class, longSerializer);
|
||||||
|
serializers.registerIfAbsent(long.class, longSerializer);
|
||||||
|
|
||||||
|
serializers.registerIfAbsent(DEFAULT_SERIALIZERS);
|
||||||
|
return serializers;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParameterizedTypeHandlerMap<JsonDeserializer<?>> getDefaultDeserializers() {
|
||||||
|
return DEFAULT_DESERIALIZERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParameterizedTypeHandlerMap<InstanceCreator<?>> getDefaultInstanceCreators() {
|
||||||
|
return DEFAULT_INSTANCE_CREATORS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
|
||||||
|
private final DateFormat format;
|
||||||
|
|
||||||
|
DefaultDateTypeAdapter() {
|
||||||
|
this.format = DateFormat.getDateTimeInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultDateTypeAdapter(final String datePattern) {
|
||||||
|
this.format = new SimpleDateFormat(datePattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
DefaultDateTypeAdapter(final int style) {
|
||||||
|
this.format = DateFormat.getDateInstance(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultDateTypeAdapter(final int dateStyle, final int timeStyle) {
|
||||||
|
this.format = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// These methods need to be synchronized since JDK DateFormat classes are not thread-safe
|
||||||
|
// See issue 162
|
||||||
|
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
synchronized (format) {
|
||||||
|
String dateFormatAsString = format.format(src);
|
||||||
|
return new JsonPrimitive(dateFormatAsString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
if (!(json instanceof JsonPrimitive)) {
|
||||||
|
throw new JsonParseException("The date should be a string value");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
synchronized (format) {
|
||||||
|
return format.parse(json.getAsString());
|
||||||
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new JsonParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(DefaultDateTypeAdapter.class.getSimpleName());
|
||||||
|
sb.append('(').append(format.getClass().getSimpleName()).append(')');
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DefaultJavaSqlDateTypeAdapter implements JsonSerializer<java.sql.Date>, JsonDeserializer<java.sql.Date> {
|
||||||
|
private final DateFormat format;
|
||||||
|
|
||||||
|
DefaultJavaSqlDateTypeAdapter() {
|
||||||
|
this.format = new SimpleDateFormat("MMM d, yyyy");
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement serialize(java.sql.Date src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
synchronized (format) {
|
||||||
|
String dateFormatAsString = format.format(src);
|
||||||
|
return new JsonPrimitive(dateFormatAsString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public java.sql.Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
if (!(json instanceof JsonPrimitive)) {
|
||||||
|
throw new JsonParseException("The date should be a string value");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
synchronized (format) {
|
||||||
|
Date date = format.parse(json.getAsString());
|
||||||
|
return new java.sql.Date(date.getTime());
|
||||||
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new JsonParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DefaultTimestampDeserializer implements JsonDeserializer<Timestamp> {
|
||||||
|
public Timestamp deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
Date date = context.deserialize(json, Date.class);
|
||||||
|
return new Timestamp(date.getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DefaultTimeTypeAdapter implements JsonSerializer<Time>, JsonDeserializer<Time> {
|
||||||
|
private final DateFormat format;
|
||||||
|
|
||||||
|
DefaultTimeTypeAdapter() {
|
||||||
|
this.format = new SimpleDateFormat("hh:mm:ss a");
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement serialize(Time src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
synchronized (format) {
|
||||||
|
String dateFormatAsString = format.format(src);
|
||||||
|
return new JsonPrimitive(dateFormatAsString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Time deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
if (!(json instanceof JsonPrimitive)) {
|
||||||
|
throw new JsonParseException("The date should be a string value");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
synchronized (format) {
|
||||||
|
Date date = format.parse(json.getAsString());
|
||||||
|
return new Time(date.getTime());
|
||||||
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new JsonParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class GregorianCalendarTypeAdapter implements JsonSerializer<GregorianCalendar>,
|
||||||
|
JsonDeserializer<GregorianCalendar> {
|
||||||
|
|
||||||
|
private static final String YEAR = "year";
|
||||||
|
private static final String MONTH = "month";
|
||||||
|
private static final String DAY_OF_MONTH = "dayOfMonth";
|
||||||
|
private static final String HOUR_OF_DAY = "hourOfDay";
|
||||||
|
private static final String MINUTE = "minute";
|
||||||
|
private static final String SECOND = "second";
|
||||||
|
|
||||||
|
public JsonElement serialize(GregorianCalendar src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject obj = new JsonObject();
|
||||||
|
obj.addProperty(YEAR, src.get(Calendar.YEAR));
|
||||||
|
obj.addProperty(MONTH, src.get(Calendar.MONTH));
|
||||||
|
obj.addProperty(DAY_OF_MONTH, src.get(Calendar.DAY_OF_MONTH));
|
||||||
|
obj.addProperty(HOUR_OF_DAY, src.get(Calendar.HOUR_OF_DAY));
|
||||||
|
obj.addProperty(MINUTE, src.get(Calendar.MINUTE));
|
||||||
|
obj.addProperty(SECOND, src.get(Calendar.SECOND));
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GregorianCalendar deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
JsonObject obj = json.getAsJsonObject();
|
||||||
|
int year = obj.get(YEAR).getAsInt();
|
||||||
|
int month = obj.get(MONTH).getAsInt();
|
||||||
|
int dayOfMonth = obj.get(DAY_OF_MONTH).getAsInt();
|
||||||
|
int hourOfDay = obj.get(HOUR_OF_DAY).getAsInt();
|
||||||
|
int minute = obj.get(MINUTE).getAsInt();
|
||||||
|
int second = obj.get(SECOND).getAsInt();
|
||||||
|
return new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute, second);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return GregorianCalendarTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static class EnumTypeAdapter<T extends Enum<T>> implements JsonSerializer<T>, JsonDeserializer<T> {
|
||||||
|
public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("cast")
|
||||||
|
public T deserialize(JsonElement json, Type classOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
try {
|
||||||
|
return (T) Enum.valueOf((Class<T>) classOfT, json.getAsString());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Method converter = classToConvert.get(classOfT);
|
||||||
|
if (converter != null)
|
||||||
|
try {
|
||||||
|
return (T) converter.invoke(null, json.getAsString());
|
||||||
|
} catch (Exception e1) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Map<Class<?>, Method> classToConvert = new MapMaker()
|
||||||
|
.makeComputingMap(new Function<Class<?>, Method>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Method apply(Class<?> from) {
|
||||||
|
try {
|
||||||
|
Method method = from.getMethod("fromValue", String.class);
|
||||||
|
method.setAccessible(true);
|
||||||
|
return method;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return EnumTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UrlTypeAdapter implements JsonSerializer<URL>, JsonDeserializer<URL> {
|
||||||
|
public JsonElement serialize(URL src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.toExternalForm());
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
try {
|
||||||
|
return new URL(json.getAsString());
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new JsonParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return UrlTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UriTypeAdapter implements JsonSerializer<URI>, JsonDeserializer<URI> {
|
||||||
|
public JsonElement serialize(URI src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.toASCIIString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public URI deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
try {
|
||||||
|
return new URI(json.getAsString());
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new JsonParseException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return UriTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UuidTypeAdapter implements JsonSerializer<UUID>, JsonDeserializer<UUID> {
|
||||||
|
public JsonElement serialize(UUID src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return UUID.fromString(json.getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return UuidTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LocaleTypeAdapter implements JsonSerializer<Locale>, JsonDeserializer<Locale> {
|
||||||
|
public JsonElement serialize(Locale src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locale deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
String locale = json.getAsString();
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer(locale, "_");
|
||||||
|
String language = null;
|
||||||
|
String country = null;
|
||||||
|
String variant = null;
|
||||||
|
if (tokenizer.hasMoreElements()) {
|
||||||
|
language = tokenizer.nextToken();
|
||||||
|
}
|
||||||
|
if (tokenizer.hasMoreElements()) {
|
||||||
|
country = tokenizer.nextToken();
|
||||||
|
}
|
||||||
|
if (tokenizer.hasMoreElements()) {
|
||||||
|
variant = tokenizer.nextToken();
|
||||||
|
}
|
||||||
|
if (country == null && variant == null) {
|
||||||
|
return new Locale(language);
|
||||||
|
} else if (variant == null) {
|
||||||
|
return new Locale(language, country);
|
||||||
|
} else {
|
||||||
|
return new Locale(language, country, variant);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return LocaleTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
private static class CollectionTypeAdapter implements JsonSerializer<Collection>, JsonDeserializer<Collection>,
|
||||||
|
InstanceCreator<Collection> {
|
||||||
|
public JsonElement serialize(Collection src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
if (src == null) {
|
||||||
|
return JsonNull.createJsonNull();
|
||||||
|
}
|
||||||
|
JsonArray array = new JsonArray();
|
||||||
|
Type childGenericType = null;
|
||||||
|
if (typeOfSrc instanceof ParameterizedType) {
|
||||||
|
childGenericType = new TypeInfoCollection(typeOfSrc).getElementType();
|
||||||
|
}
|
||||||
|
for (Object child : src) {
|
||||||
|
if (child == null) {
|
||||||
|
array.add(JsonNull.createJsonNull());
|
||||||
|
} else {
|
||||||
|
Type childType = (childGenericType == null || childGenericType == Object.class) ? child.getClass()
|
||||||
|
: childGenericType;
|
||||||
|
JsonElement element = context.serialize(child, childType);
|
||||||
|
array.add(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
if (json.isJsonNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// Use ObjectConstructor to create instance instead of hard-coding a specific type.
|
||||||
|
// This handles cases where users are using their own subclass of Collection.
|
||||||
|
Collection collection = constructCollectionType(typeOfT, context);
|
||||||
|
Type childType = new TypeInfoCollection(typeOfT).getElementType();
|
||||||
|
for (JsonElement childElement : json.getAsJsonArray()) {
|
||||||
|
if (childElement == null || childElement.isJsonNull()) {
|
||||||
|
collection.add(null);
|
||||||
|
} else {
|
||||||
|
Object value = context.deserialize(childElement, childType);
|
||||||
|
collection.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return collection;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection constructCollectionType(Type collectionType, JsonDeserializationContext context) {
|
||||||
|
JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context;
|
||||||
|
ObjectConstructor objectConstructor = contextImpl.getObjectConstructor();
|
||||||
|
return (Collection) objectConstructor.construct(collectionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection createInstance(Type type) {
|
||||||
|
return new LinkedList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PropertiesCreator implements InstanceCreator<Properties> {
|
||||||
|
public Properties createInstance(Type type) {
|
||||||
|
return new Properties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
|
static class MapTypeAdapter implements JsonSerializer<Map>, JsonDeserializer<Map>, InstanceCreator<Map> {
|
||||||
|
|
||||||
|
public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
JsonObject map = new JsonObject();
|
||||||
|
Type childGenericType = null;
|
||||||
|
if (typeOfSrc instanceof ParameterizedType) {
|
||||||
|
childGenericType = new TypeInfoMap(typeOfSrc).getValueType();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry entry : (Set<Map.Entry>) src.entrySet()) {
|
||||||
|
Object value = entry.getValue();
|
||||||
|
|
||||||
|
JsonElement valueElement;
|
||||||
|
if (value == null) {
|
||||||
|
valueElement = JsonNull.createJsonNull();
|
||||||
|
} else {
|
||||||
|
Type childType = (childGenericType == null) ? value.getClass() : childGenericType;
|
||||||
|
valueElement = context.serialize(value, childType);
|
||||||
|
}
|
||||||
|
map.add(String.valueOf(entry.getKey()), valueElement);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
// Use ObjectConstructor to create instance instead of hard-coding a specific type.
|
||||||
|
// This handles cases where users are using their own subclass of Map.
|
||||||
|
Map<Object, Object> map = constructMapType(typeOfT, context);
|
||||||
|
TypeInfoMap mapTypeInfo = new TypeInfoMap(typeOfT);
|
||||||
|
for (Map.Entry<String, JsonElement> entry : json.getAsJsonObject().entrySet()) {
|
||||||
|
Object key = context.deserialize(new JsonPrimitive(entry.getKey()), mapTypeInfo.getKeyType());
|
||||||
|
Object value = context.deserialize(entry.getValue(), mapTypeInfo.getValueType());
|
||||||
|
map.put(key, value);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map constructMapType(Type mapType, JsonDeserializationContext context) {
|
||||||
|
JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context;
|
||||||
|
ObjectConstructor objectConstructor = contextImpl.getObjectConstructor();
|
||||||
|
return (Map) objectConstructor.construct(mapType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map createInstance(Type type) {
|
||||||
|
return new LinkedHashMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return MapTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BigDecimalTypeAdapter implements JsonSerializer<BigDecimal>, JsonDeserializer<BigDecimal> {
|
||||||
|
public JsonElement serialize(BigDecimal src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsBigDecimal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return BigDecimalTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BigIntegerTypeAdapter implements JsonSerializer<BigInteger>, JsonDeserializer<BigInteger> {
|
||||||
|
|
||||||
|
public JsonElement serialize(BigInteger src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsBigInteger();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return BigIntegerTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NumberTypeAdapter implements JsonSerializer<Number>, JsonDeserializer<Number> {
|
||||||
|
public JsonElement serialize(Number src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Number deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return NumberTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LongSerializer implements JsonSerializer<Long> {
|
||||||
|
private final LongSerializationPolicy longSerializationPolicy;
|
||||||
|
|
||||||
|
private LongSerializer(LongSerializationPolicy longSerializationPolicy) {
|
||||||
|
this.longSerializationPolicy = longSerializationPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return longSerializationPolicy.serialize(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return LongSerializer.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LongDeserializer implements JsonDeserializer<Long> {
|
||||||
|
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return LongDeserializer.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class IntegerTypeAdapter implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
|
||||||
|
public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return IntegerTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ShortTypeAdapter implements JsonSerializer<Short>, JsonDeserializer<Short> {
|
||||||
|
public JsonElement serialize(Short src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Short deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ShortTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ByteTypeAdapter implements JsonSerializer<Byte>, JsonDeserializer<Byte> {
|
||||||
|
public JsonElement serialize(Byte src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Byte deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ByteTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FloatSerializer implements JsonSerializer<Float> {
|
||||||
|
private final boolean serializeSpecialFloatingPointValues;
|
||||||
|
|
||||||
|
FloatSerializer(boolean serializeSpecialDoubleValues) {
|
||||||
|
this.serializeSpecialFloatingPointValues = serializeSpecialDoubleValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement serialize(Float src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
if (!serializeSpecialFloatingPointValues) {
|
||||||
|
if (Float.isNaN(src) || Float.isInfinite(src)) {
|
||||||
|
throw new IllegalArgumentException(src
|
||||||
|
+ " is not a valid float value as per JSON specification. To override this"
|
||||||
|
+ " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class FloatDeserializer implements JsonDeserializer<Float> {
|
||||||
|
public Float deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return FloatDeserializer.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DoubleSerializer implements JsonSerializer<Double> {
|
||||||
|
private final boolean serializeSpecialFloatingPointValues;
|
||||||
|
|
||||||
|
DoubleSerializer(boolean serializeSpecialDoubleValues) {
|
||||||
|
this.serializeSpecialFloatingPointValues = serializeSpecialDoubleValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
if (!serializeSpecialFloatingPointValues) {
|
||||||
|
if (Double.isNaN(src) || Double.isInfinite(src)) {
|
||||||
|
throw new IllegalArgumentException(src
|
||||||
|
+ " is not a valid double value as per JSON specification. To override this"
|
||||||
|
+ " behavior, use GsonBuilder.serializeSpecialDoubleValues() method.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DoubleDeserializer implements JsonDeserializer<Double> {
|
||||||
|
public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return DoubleDeserializer.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CharacterTypeAdapter implements JsonSerializer<Character>, JsonDeserializer<Character> {
|
||||||
|
public JsonElement serialize(Character src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Character deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsCharacter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return CharacterTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class StringTypeAdapter implements JsonSerializer<String>, JsonDeserializer<String> {
|
||||||
|
public JsonElement serialize(String src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return StringTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class BooleanTypeAdapter implements JsonSerializer<Boolean>, JsonDeserializer<Boolean> {
|
||||||
|
public JsonElement serialize(Boolean src, Type typeOfSrc, JsonSerializationContext context) {
|
||||||
|
return new JsonPrimitive(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
|
throws JsonParseException {
|
||||||
|
return json.getAsBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return BooleanTypeAdapter.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TreeSetCreator implements InstanceCreator<TreeSet<?>> {
|
||||||
|
public TreeSet<?> createInstance(Type type) {
|
||||||
|
return new TreeSet<Object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return TreeSetCreator.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class HashSetCreator implements InstanceCreator<HashSet<?>> {
|
||||||
|
public HashSet<?> createInstance(Type type) {
|
||||||
|
return new HashSet<Object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return HashSetCreator.class.getSimpleName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,591 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2008 Google Inc.
|
||||||
|
*
|
||||||
|
* 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 com.google.gson;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.gson.JcloudsDefaultTypeAdapters.DefaultDateTypeAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Use this builder to construct a {@link Gson} instance when you need to set configuration
|
||||||
|
* options other than the default. For {@link Gson} with default configuration, it is simpler to
|
||||||
|
* use {@code new Gson()}. {@code JcloudsGsonBuilder} is best used by creating it, and then invoking its
|
||||||
|
* various configuration methods, and finally calling create.</p>
|
||||||
|
*
|
||||||
|
* <p>The following is an example shows how to use the {@code JcloudsGsonBuilder} to construct a Gson
|
||||||
|
* instance:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* Gson gson = new JcloudsGsonBuilder()
|
||||||
|
* .registerTypeAdapter(Id.class, new IdTypeAdapter())
|
||||||
|
* .serializeNulls()
|
||||||
|
* .setDateFormat(DateFormat.LONG)
|
||||||
|
* .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
|
||||||
|
* .setPrettyPrinting()
|
||||||
|
* .setVersion(1.0)
|
||||||
|
* .create();
|
||||||
|
* </pre></p>
|
||||||
|
*
|
||||||
|
* <p>NOTE: the order of invocation of configuration methods does not matter.</p>
|
||||||
|
*
|
||||||
|
* @author Inderjeet Singh
|
||||||
|
* @author Joel Leitch
|
||||||
|
*/
|
||||||
|
public final class JcloudsGsonBuilder {
|
||||||
|
private static final InnerClassExclusionStrategy innerClassExclusionStrategy =
|
||||||
|
new InnerClassExclusionStrategy();
|
||||||
|
private static final ExposeAnnotationSerializationExclusionStrategy
|
||||||
|
exposeAnnotationSerializationExclusionStrategy =
|
||||||
|
new ExposeAnnotationSerializationExclusionStrategy();
|
||||||
|
private static final ExposeAnnotationDeserializationExclusionStrategy
|
||||||
|
exposeAnnotationDeserializationExclusionStrategy =
|
||||||
|
new ExposeAnnotationDeserializationExclusionStrategy();
|
||||||
|
|
||||||
|
private final Collection<ExclusionStrategy> exclusionStrategies =
|
||||||
|
new HashSet<ExclusionStrategy>();
|
||||||
|
|
||||||
|
private double ignoreVersionsAfter;
|
||||||
|
private ModifierBasedExclusionStrategy modifierBasedExclusionStrategy;
|
||||||
|
private boolean serializeInnerClasses;
|
||||||
|
private boolean excludeFieldsWithoutExposeAnnotation;
|
||||||
|
private LongSerializationPolicy longSerializationPolicy;
|
||||||
|
private FieldNamingStrategy2 fieldNamingPolicy;
|
||||||
|
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreators;
|
||||||
|
private final ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers;
|
||||||
|
private final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;
|
||||||
|
private boolean serializeNulls;
|
||||||
|
private String datePattern;
|
||||||
|
private int dateStyle;
|
||||||
|
private int timeStyle;
|
||||||
|
private boolean serializeSpecialFloatingPointValues;
|
||||||
|
private boolean escapeHtmlChars;
|
||||||
|
private boolean prettyPrinting;
|
||||||
|
private boolean generateNonExecutableJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JcloudsGsonBuilder instance that can be used to build Gson with various configuration
|
||||||
|
* settings. JcloudsGsonBuilder follows the builder pattern, and it is typically used by first
|
||||||
|
* invoking various configuration methods to set desired options, and finally calling
|
||||||
|
* {@link #create()}.
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder() {
|
||||||
|
// add default exclusion strategies
|
||||||
|
exclusionStrategies.add(Gson.DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY);
|
||||||
|
exclusionStrategies.add(Gson.DEFAULT_SYNTHETIC_FIELD_EXCLUSION_STRATEGY);
|
||||||
|
|
||||||
|
// setup default values
|
||||||
|
ignoreVersionsAfter = VersionConstants.IGNORE_VERSIONS;
|
||||||
|
serializeInnerClasses = true;
|
||||||
|
prettyPrinting = false;
|
||||||
|
escapeHtmlChars = true;
|
||||||
|
modifierBasedExclusionStrategy = Gson.DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY;
|
||||||
|
excludeFieldsWithoutExposeAnnotation = false;
|
||||||
|
longSerializationPolicy = LongSerializationPolicy.DEFAULT;
|
||||||
|
fieldNamingPolicy = Gson.DEFAULT_NAMING_POLICY;
|
||||||
|
instanceCreators = new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
|
||||||
|
serializers = new ParameterizedTypeHandlerMap<JsonSerializer<?>>();
|
||||||
|
deserializers = new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
|
||||||
|
serializeNulls = false;
|
||||||
|
dateStyle = DateFormat.DEFAULT;
|
||||||
|
timeStyle = DateFormat.DEFAULT;
|
||||||
|
serializeSpecialFloatingPointValues = false;
|
||||||
|
generateNonExecutableJson = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to enable versioning support.
|
||||||
|
*
|
||||||
|
* @param ignoreVersionsAfter any field or type marked with a version higher than this value
|
||||||
|
* are ignored during serialization or deserialization.
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setVersion(double ignoreVersionsAfter) {
|
||||||
|
this.ignoreVersionsAfter = ignoreVersionsAfter;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to excludes all class fields that have the specified modifiers. By default,
|
||||||
|
* Gson will exclude all fields marked transient or static. This method will override that
|
||||||
|
* behavior.
|
||||||
|
*
|
||||||
|
* @param modifiers the field modifiers. You must use the modifiers specified in the
|
||||||
|
* {@link java.lang.reflect.Modifier} class. For example,
|
||||||
|
* {@link java.lang.reflect.Modifier#TRANSIENT},
|
||||||
|
* {@link java.lang.reflect.Modifier#STATIC}.
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder excludeFieldsWithModifiers(int... modifiers) {
|
||||||
|
modifierBasedExclusionStrategy = new ModifierBasedExclusionStrategy(modifiers);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the output JSON non-executable in Javascript by prefixing the generated JSON with some
|
||||||
|
* special text. This prevents attacks from third-party sites through script sourcing. See
|
||||||
|
* <a href="http://code.google.com/p/google-gson/issues/detail?id=42">Gson Issue 42</a>
|
||||||
|
* for details.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder generateNonExecutableJson() {
|
||||||
|
this.generateNonExecutableJson = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to exclude all fields from consideration for serialization or deserialization
|
||||||
|
* that do not have the {@link com.google.gson.annotations.Expose} annotation.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder excludeFieldsWithoutExposeAnnotation() {
|
||||||
|
excludeFieldsWithoutExposeAnnotation = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure Gson to serialize null fields. By default, Gson omits all fields that are null
|
||||||
|
* during serialization.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder serializeNulls() {
|
||||||
|
this.serializeNulls = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to exclude inner classes during serialization.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder disableInnerClassSerialization() {
|
||||||
|
serializeInnerClasses = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to apply a specific serialization policy for {@code Long} and {@code long}
|
||||||
|
* objects.
|
||||||
|
*
|
||||||
|
* @param serializationPolicy the particular policy to use for serializing longs.
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setLongSerializationPolicy(LongSerializationPolicy serializationPolicy) {
|
||||||
|
this.longSerializationPolicy = serializationPolicy;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to apply a specific naming policy to an object's field during serialization
|
||||||
|
* and deserialization.
|
||||||
|
*
|
||||||
|
* @param namingConvention the JSON field naming convention to use for serialization and
|
||||||
|
* deserialization.
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setFieldNamingPolicy(FieldNamingPolicy namingConvention) {
|
||||||
|
return setFieldNamingStrategy(namingConvention.getFieldNamingPolicy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to apply a specific naming policy strategy to an object's field during
|
||||||
|
* serialization and deserialization.
|
||||||
|
*
|
||||||
|
* @param fieldNamingStrategy the actual naming strategy to apply to the fields
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy) {
|
||||||
|
return setFieldNamingStrategy(new FieldNamingStrategy2Adapter(fieldNamingStrategy));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to apply a specific naming policy strategy to an object's field during
|
||||||
|
* serialization and deserialization.
|
||||||
|
*
|
||||||
|
* @param fieldNamingStrategy the actual naming strategy to apply to the fields
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
JcloudsGsonBuilder setFieldNamingStrategy(FieldNamingStrategy2 fieldNamingStrategy) {
|
||||||
|
this.fieldNamingPolicy =
|
||||||
|
new SerializedNameAnnotationInterceptingNamingPolicy(fieldNamingStrategy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to apply a set of exclusion strategies during both serialization and
|
||||||
|
* deserialization. Each of the {@code strategies} will be applied as a disjunction rule.
|
||||||
|
* This means that if one of the {@code strategies} suggests that a field (or class) should be
|
||||||
|
* skipped then that field (or object) is skipped during serializaiton/deserialization.
|
||||||
|
*
|
||||||
|
* @param strategies the set of strategy object to apply during object (de)serialization.
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
|
||||||
|
for (ExclusionStrategy strategy : strategies) {
|
||||||
|
exclusionStrategies.add(strategy);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to output Json that fits in a page for pretty printing. This option only
|
||||||
|
* affects Json serialization.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setPrettyPrinting() {
|
||||||
|
prettyPrinting = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, Gson escapes HTML characters such as < > etc. Use this option to configure
|
||||||
|
* Gson to pass-through HTML characters as is.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder disableHtmlEscaping() {
|
||||||
|
this.escapeHtmlChars = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to serialize {@code Date} objects according to the pattern provided. You can
|
||||||
|
* call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
|
||||||
|
* will be used to decide the serialization format.
|
||||||
|
*
|
||||||
|
* <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
|
||||||
|
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
|
||||||
|
* valid date and time patterns.</p>
|
||||||
|
*
|
||||||
|
* @param pattern the pattern that dates will be serialized/deserialized to/from
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setDateFormat(String pattern) {
|
||||||
|
// TODO(Joel): Make this fail fast if it is an invalid date format
|
||||||
|
this.datePattern = pattern;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to to serialize {@code Date} objects according to the style value provided.
|
||||||
|
* You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
|
||||||
|
* invocation will be used to decide the serialization format.
|
||||||
|
*
|
||||||
|
* <p>Note that this style value should be one of the predefined constants in the
|
||||||
|
* {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
|
||||||
|
* information on the valid style constants.</p>
|
||||||
|
*
|
||||||
|
* @param style the predefined date style that date objects will be serialized/deserialized
|
||||||
|
* to/from
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setDateFormat(int style) {
|
||||||
|
this.dateStyle = style;
|
||||||
|
this.datePattern = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to to serialize {@code Date} objects according to the style value provided.
|
||||||
|
* You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
|
||||||
|
* invocation will be used to decide the serialization format.
|
||||||
|
*
|
||||||
|
* <p>Note that this style value should be one of the predefined constants in the
|
||||||
|
* {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
|
||||||
|
* information on the valid style constants.</p>
|
||||||
|
*
|
||||||
|
* @param dateStyle the predefined date style that date objects will be serialized/deserialized
|
||||||
|
* to/from
|
||||||
|
* @param timeStyle the predefined style for the time portion of the date objects
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.2
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder setDateFormat(int dateStyle, int timeStyle) {
|
||||||
|
this.dateStyle = dateStyle;
|
||||||
|
this.timeStyle = timeStyle;
|
||||||
|
this.datePattern = null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson for custom serialization or deserialization. This method combines the
|
||||||
|
* registration of an {@link InstanceCreator}, {@link JsonSerializer}, and a
|
||||||
|
* {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter} implements
|
||||||
|
* all the required interfaces for custom serialization with Gson. If an instance creator,
|
||||||
|
* serializer or deserializer was previously registered for the specified {@code type}, it is
|
||||||
|
* overwritten.
|
||||||
|
*
|
||||||
|
* @param type the type definition for the type adapter being registered
|
||||||
|
* @param typeAdapter This object must implement at least one of the {@link InstanceCreator},
|
||||||
|
* {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder registerTypeAdapter(Type type, Object typeAdapter) {
|
||||||
|
Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
||||||
|
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
||||||
|
if (typeAdapter instanceof InstanceCreator<?>) {
|
||||||
|
registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter);
|
||||||
|
}
|
||||||
|
if (typeAdapter instanceof JsonSerializer<?>) {
|
||||||
|
registerSerializer(type, (JsonSerializer<?>) typeAdapter);
|
||||||
|
}
|
||||||
|
if (typeAdapter instanceof JsonDeserializer<?>) {
|
||||||
|
registerDeserializer(type, (JsonDeserializer<?>) typeAdapter);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to use a custom {@link InstanceCreator} for the specified type. If an instance
|
||||||
|
* creator was previously registered for the specified class, it is overwritten. Since this method
|
||||||
|
* takes a type instead of a Class object, it can be used to register a specific handler for a
|
||||||
|
* generic type corresponding to a raw type.
|
||||||
|
*
|
||||||
|
* @param <T> the type for which instance creator is being registered
|
||||||
|
* @param typeOfT The Type definition for T
|
||||||
|
* @param instanceCreator the instance creator for T
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
private <T> JcloudsGsonBuilder registerInstanceCreator(Type typeOfT,
|
||||||
|
InstanceCreator<? extends T> instanceCreator) {
|
||||||
|
instanceCreators.register(typeOfT, instanceCreator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to use a custom JSON serializer for the specified type. You should use this
|
||||||
|
* method if you want to register different serializers for different generic types corresponding
|
||||||
|
* to a raw type.
|
||||||
|
*
|
||||||
|
* @param <T> the type for which the serializer is being registered
|
||||||
|
* @param typeOfT The type definition for T
|
||||||
|
* @param serializer the custom serializer
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
private <T> JcloudsGsonBuilder registerSerializer(Type typeOfT, final JsonSerializer<T> serializer) {
|
||||||
|
serializers.register(typeOfT, serializer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson to use a custom JSON deserializer for the specified type. You should use this
|
||||||
|
* method if you want to register different deserializers for different generic types
|
||||||
|
* corresponding to a raw type.
|
||||||
|
*
|
||||||
|
* @param <T> the type for which the deserializer is being registered
|
||||||
|
* @param typeOfT The type definition for T
|
||||||
|
* @param deserializer the custom deserializer
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
*/
|
||||||
|
private <T> JcloudsGsonBuilder registerDeserializer(Type typeOfT, JsonDeserializer<T> deserializer) {
|
||||||
|
deserializers.register(typeOfT, new JsonDeserializerExceptionWrapper<T>(deserializer));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures Gson for custom serialization or deserialization for an inheritance type hierarchy.
|
||||||
|
* This method combines the registration of an {@link InstanceCreator}, {@link JsonSerializer},
|
||||||
|
* and a {@link JsonDeserializer}. It is best used when a single object {@code typeAdapter}
|
||||||
|
* implements all the required interfaces for custom serialization with Gson.
|
||||||
|
* If an instance creator, serializer or deserializer was previously registered for the specified
|
||||||
|
* type hierarchy, it is overwritten. If an instance creator, serializer or deserializer is
|
||||||
|
* registered for a specific type in the type hierarchy, it will be invoked instead of the one
|
||||||
|
* registered for the type hierarchy.
|
||||||
|
*
|
||||||
|
* @param baseType the class definition for the type adapter being registered for the base class
|
||||||
|
* or interface
|
||||||
|
* @param typeAdapter This object must implement at least one of the {@link InstanceCreator},
|
||||||
|
* {@link JsonSerializer}, and a {@link JsonDeserializer} interfaces.
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.5
|
||||||
|
*/
|
||||||
|
JcloudsGsonBuilder registerTypeHierarchyAdapter(Class<?> baseType, Object typeAdapter) {
|
||||||
|
Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|
||||||
|
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
|
||||||
|
if (typeAdapter instanceof InstanceCreator<?>) {
|
||||||
|
registerInstanceCreatorForTypeHierarchy(baseType, (InstanceCreator<?>) typeAdapter);
|
||||||
|
}
|
||||||
|
if (typeAdapter instanceof JsonSerializer<?>) {
|
||||||
|
registerSerializerForTypeHierarchy(baseType, (JsonSerializer<?>) typeAdapter);
|
||||||
|
}
|
||||||
|
if (typeAdapter instanceof JsonDeserializer<?>) {
|
||||||
|
registerDeserializerForTypeHierarchy(baseType, (JsonDeserializer<?>) typeAdapter);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> JcloudsGsonBuilder registerInstanceCreatorForTypeHierarchy(Class<?> classOfT,
|
||||||
|
InstanceCreator<? extends T> instanceCreator) {
|
||||||
|
instanceCreators.registerForTypeHierarchy(classOfT, instanceCreator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> JcloudsGsonBuilder registerSerializerForTypeHierarchy(Class<?> classOfT,
|
||||||
|
final JsonSerializer<T> serializer) {
|
||||||
|
serializers.registerForTypeHierarchy(classOfT, serializer);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> JcloudsGsonBuilder registerDeserializerForTypeHierarchy(Class<?> classOfT,
|
||||||
|
JsonDeserializer<T> deserializer) {
|
||||||
|
deserializers.registerForTypeHierarchy(classOfT,
|
||||||
|
new JsonDeserializerExceptionWrapper<T>(deserializer));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Section 2.4 of <a href="http://www.ietf.org/rfc/rfc4627.txt">JSON specification</a> disallows
|
||||||
|
* special double values (NaN, Infinity, -Infinity). However,
|
||||||
|
* <a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf">Javascript
|
||||||
|
* specification</a> (see section 4.3.20, 4.3.22, 4.3.23) allows these values as valid Javascript
|
||||||
|
* values. Moreover, most JavaScript engines will accept these special values in JSON without
|
||||||
|
* problem. So, at a practical level, it makes sense to accept these values as valid JSON even
|
||||||
|
* though JSON specification disallows them.
|
||||||
|
*
|
||||||
|
* <p>Gson always accepts these special values during deserialization. However, it outputs
|
||||||
|
* strictly compliant JSON. Hence, if it encounters a float value {@link Float#NaN},
|
||||||
|
* {@link Float#POSITIVE_INFINITY}, {@link Float#NEGATIVE_INFINITY}, or a double value
|
||||||
|
* {@link Double#NaN}, {@link Double#POSITIVE_INFINITY}, {@link Double#NEGATIVE_INFINITY}, it
|
||||||
|
* will throw an {@link IllegalArgumentException}. This method provides a way to override the
|
||||||
|
* default behavior when you know that the JSON receiver will be able to handle these special
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @return a reference to this {@code JcloudsGsonBuilder} object to fulfill the "Builder" pattern
|
||||||
|
* @since 1.3
|
||||||
|
*/
|
||||||
|
public JcloudsGsonBuilder serializeSpecialFloatingPointValues() {
|
||||||
|
this.serializeSpecialFloatingPointValues = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link Gson} instance based on the current configuration. This method is free of
|
||||||
|
* side-effects to this {@code JcloudsGsonBuilder} instance and hence can be called multiple times.
|
||||||
|
*
|
||||||
|
* @return an instance of Gson configured with the options currently set in this builder
|
||||||
|
*/
|
||||||
|
public Gson create() {
|
||||||
|
List<ExclusionStrategy> serializationStrategies =
|
||||||
|
new LinkedList<ExclusionStrategy>(exclusionStrategies);
|
||||||
|
List<ExclusionStrategy> deserializationStrategies =
|
||||||
|
new LinkedList<ExclusionStrategy>(exclusionStrategies);
|
||||||
|
|
||||||
|
serializationStrategies.add(modifierBasedExclusionStrategy);
|
||||||
|
deserializationStrategies.add(modifierBasedExclusionStrategy);
|
||||||
|
|
||||||
|
if (!serializeInnerClasses) {
|
||||||
|
serializationStrategies.add(innerClassExclusionStrategy);
|
||||||
|
deserializationStrategies.add(innerClassExclusionStrategy);
|
||||||
|
}
|
||||||
|
if (ignoreVersionsAfter != VersionConstants.IGNORE_VERSIONS) {
|
||||||
|
serializationStrategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
||||||
|
deserializationStrategies.add(new VersionExclusionStrategy(ignoreVersionsAfter));
|
||||||
|
}
|
||||||
|
if (excludeFieldsWithoutExposeAnnotation) {
|
||||||
|
serializationStrategies.add(exposeAnnotationSerializationExclusionStrategy);
|
||||||
|
deserializationStrategies.add(exposeAnnotationDeserializationExclusionStrategy);
|
||||||
|
}
|
||||||
|
ExclusionStrategy serializationExclusionStrategy =
|
||||||
|
new DisjunctionExclusionStrategy(serializationStrategies);
|
||||||
|
ExclusionStrategy deserializationExclusionStrategy =
|
||||||
|
new DisjunctionExclusionStrategy(deserializationStrategies);
|
||||||
|
|
||||||
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers = serializers.copyOf();
|
||||||
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> customDeserializers = deserializers.copyOf();
|
||||||
|
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, customSerializers,
|
||||||
|
customDeserializers);
|
||||||
|
|
||||||
|
customSerializers.registerIfAbsent(JcloudsDefaultTypeAdapters.getDefaultSerializers(
|
||||||
|
serializeSpecialFloatingPointValues, longSerializationPolicy));
|
||||||
|
|
||||||
|
customDeserializers.registerIfAbsent(JcloudsDefaultTypeAdapters.getDefaultDeserializers());
|
||||||
|
|
||||||
|
ParameterizedTypeHandlerMap<InstanceCreator<?>> customInstanceCreators =
|
||||||
|
instanceCreators.copyOf();
|
||||||
|
customInstanceCreators.registerIfAbsent(JcloudsDefaultTypeAdapters.getDefaultInstanceCreators());
|
||||||
|
|
||||||
|
customSerializers.makeUnmodifiable();
|
||||||
|
customDeserializers.makeUnmodifiable();
|
||||||
|
instanceCreators.makeUnmodifiable();
|
||||||
|
|
||||||
|
MappedObjectConstructor objConstructor = new MappedObjectConstructor(customInstanceCreators);
|
||||||
|
|
||||||
|
JsonFormatter formatter = prettyPrinting ?
|
||||||
|
new JsonPrintFormatter(escapeHtmlChars) : new JsonCompactFormatter(escapeHtmlChars);
|
||||||
|
Gson gson = new Gson(serializationExclusionStrategy, deserializationExclusionStrategy,
|
||||||
|
fieldNamingPolicy, objConstructor, formatter, serializeNulls, customSerializers,
|
||||||
|
customDeserializers, generateNonExecutableJson);
|
||||||
|
return gson;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
|
||||||
|
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
||||||
|
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
|
||||||
|
DefaultDateTypeAdapter dateTypeAdapter = null;
|
||||||
|
if (datePattern != null && !"".equals(datePattern.trim())) {
|
||||||
|
dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
|
||||||
|
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
|
||||||
|
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dateTypeAdapter != null) {
|
||||||
|
if (!serializers.hasSpecificHandlerFor(Date.class)) {
|
||||||
|
serializers.register(Date.class, dateTypeAdapter);
|
||||||
|
}
|
||||||
|
if (!deserializers.hasSpecificHandlerFor(Date.class)) {
|
||||||
|
deserializers.register(Date.class, dateTypeAdapter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,15 @@
|
||||||
|
|
||||||
package org.jclouds.http;
|
package org.jclouds.http;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.jclouds.io.Payload;
|
import org.jclouds.io.Payload;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a response produced from {@link HttpCommandExecutorService}
|
* Represents a response produced from {@link HttpCommandExecutorService}
|
||||||
*
|
*
|
||||||
|
@ -34,9 +39,14 @@ public class HttpResponse extends HttpMessage {
|
||||||
private final String message;
|
private final String message;
|
||||||
|
|
||||||
public HttpResponse(int statusCode, String message, @Nullable Payload payload) {
|
public HttpResponse(int statusCode, String message, @Nullable Payload payload) {
|
||||||
|
this(statusCode, message, payload, ImmutableMultimap.<String, String> of());
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpResponse(int statusCode, String message, @Nullable Payload payload, Multimap<String, String> headers) {
|
||||||
super(payload);
|
super(payload);
|
||||||
this.statusCode = statusCode;
|
this.statusCode = statusCode;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
|
this.headers.putAll(checkNotNull(headers));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStatusCode() {
|
public int getStatusCode() {
|
||||||
|
@ -49,8 +59,8 @@ public class HttpResponse extends HttpMessage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[message=" + message + ", statusCode=" + statusCode + ", headers=" + headers
|
return "[message=" + message + ", statusCode=" + statusCode + ", headers=" + headers + ", payload=" + payload
|
||||||
+ ", payload=" + payload + "]";
|
+ "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getStatusLine() {
|
public String getStatusLine() {
|
||||||
|
|
|
@ -19,8 +19,13 @@
|
||||||
|
|
||||||
package org.jclouds.http;
|
package org.jclouds.http;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jclouds.io.payloads.StringPayload;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an error obtained from an HttpResponse.
|
* Represents an error obtained from an HttpResponse.
|
||||||
*
|
*
|
||||||
|
@ -34,15 +39,14 @@ public class HttpResponseException extends RuntimeException {
|
||||||
protected final HttpResponse response;
|
protected final HttpResponse response;
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
public HttpResponseException(String message, HttpCommand command,
|
public HttpResponseException(String message, HttpCommand command, @Nullable HttpResponse response, Throwable cause) {
|
||||||
@Nullable HttpResponse response, Throwable cause) {
|
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponseException(String message, HttpCommand command,
|
public HttpResponseException(String message, HttpCommand command, @Nullable HttpResponse response, String content,
|
||||||
@Nullable HttpResponse response, String content, Throwable cause) {
|
Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
|
@ -50,15 +54,13 @@ public class HttpResponseException extends RuntimeException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponseException(HttpCommand command, HttpResponse response, Throwable cause) {
|
public HttpResponseException(HttpCommand command, HttpResponse response, Throwable cause) {
|
||||||
this(String.format("command: %1$s failed with response: %2$s", command.getRequest()
|
this(String.format("command: %1$s failed with response: %2$s", command.getRequest().getRequestLine(),
|
||||||
.getRequestLine(), response.getStatusLine()), command, response, cause);
|
response.getStatusLine()), command, response, cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponseException(HttpCommand command, HttpResponse response, String content,
|
public HttpResponseException(HttpCommand command, HttpResponse response, String content, Throwable cause) {
|
||||||
Throwable cause) {
|
this(String.format("command: %1$s failed with response: %2$s; content: [%3$s]", command.getRequest()
|
||||||
this(String.format("command: %1$s failed with response: %2$s; content: [%3$s]", command
|
.getRequestLine(), response.getStatusLine()), command, response, content, cause);
|
||||||
.getRequest().getRequestLine(), response.getStatusLine()), command, response,
|
|
||||||
content, cause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponseException(String message, HttpCommand command, @Nullable HttpResponse response) {
|
public HttpResponseException(String message, HttpCommand command, @Nullable HttpResponse response) {
|
||||||
|
@ -67,8 +69,7 @@ public class HttpResponseException extends RuntimeException {
|
||||||
this.response = response;
|
this.response = response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponseException(String message, HttpCommand command,
|
public HttpResponseException(String message, HttpCommand command, @Nullable HttpResponse response, String content) {
|
||||||
@Nullable HttpResponse response, String content) {
|
|
||||||
super(message);
|
super(message);
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.response = response;
|
this.response = response;
|
||||||
|
@ -76,14 +77,29 @@ public class HttpResponseException extends RuntimeException {
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponseException(HttpCommand command, HttpResponse response) {
|
public HttpResponseException(HttpCommand command, HttpResponse response) {
|
||||||
this(String.format("command: %1$s failed with response: %2$s", command.getRequest()
|
this(String.format("request: %s %sfailed with response: %s", command.getRequest().getRequestLine(),
|
||||||
.getRequestLine(), response.getStatusLine()), command, response);
|
requestPayloadIfStringOrFormIfNotReturnEmptyString(command.getRequest()), response.getStatusLine()),
|
||||||
|
command, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
static String requestPayloadIfStringOrFormIfNotReturnEmptyString(HttpRequest request) {
|
||||||
|
if (request.getPayload() != null
|
||||||
|
&& ("application/x-www-form-urlencoded".equals(request.getPayload().getContentMetadata().getContentType()) || request
|
||||||
|
.getPayload() instanceof StringPayload)
|
||||||
|
&& request.getPayload().getContentMetadata().getContentLength() != null
|
||||||
|
&& request.getPayload().getContentMetadata().getContentLength() < 1024) {
|
||||||
|
try {
|
||||||
|
return String.format(" [%s] ", request.getPayload() instanceof StringPayload ? request.getPayload()
|
||||||
|
.getRawContent() : Utils.toStringAndClose(request.getPayload().getInput()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpResponseException(HttpCommand command, HttpResponse response, String content) {
|
public HttpResponseException(HttpCommand command, HttpResponse response, String content) {
|
||||||
this(String.format("command: %1$s failed with response: %2$s; content: [%3$s]", command
|
this(String.format("command: %s failed with response: %s; content: [%s]", command.getRequest().getRequestLine(),
|
||||||
.getRequest().getRequestLine(), response.getStatusLine(), content), command,
|
response.getStatusLine(), content), command, response, content);
|
||||||
response, content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpCommand getCommand() {
|
public HttpCommand getCommand() {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
package org.jclouds.http.handlers;
|
package org.jclouds.http.handlers;
|
||||||
|
|
||||||
import static org.jclouds.http.HttpUtils.changePathTo;
|
import static java.util.Collections.singletonList;
|
||||||
import static org.jclouds.http.HttpUtils.changeSchemeHostAndPortTo;
|
import static javax.ws.rs.core.HttpHeaders.HOST;
|
||||||
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
@ -58,8 +58,7 @@ public class RedirectionRetryHandler implements HttpRetryHandler {
|
||||||
protected final Provider<UriBuilder> uriBuilderProvider;
|
protected final Provider<UriBuilder> uriBuilderProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected RedirectionRetryHandler(Provider<UriBuilder> uriBuilderProvider,
|
protected RedirectionRetryHandler(Provider<UriBuilder> uriBuilderProvider, BackoffLimitedRetryHandler backoffHandler) {
|
||||||
BackoffLimitedRetryHandler backoffHandler) {
|
|
||||||
this.backoffHandler = backoffHandler;
|
this.backoffHandler = backoffHandler;
|
||||||
this.uriBuilderProvider = uriBuilderProvider;
|
this.uriBuilderProvider = uriBuilderProvider;
|
||||||
}
|
}
|
||||||
|
@ -67,25 +66,36 @@ public class RedirectionRetryHandler implements HttpRetryHandler {
|
||||||
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
public boolean shouldRetryRequest(HttpCommand command, HttpResponse response) {
|
||||||
closeClientButKeepContentStream(response);
|
closeClientButKeepContentStream(response);
|
||||||
String hostHeader = response.getFirstHeaderOrNull(HttpHeaders.LOCATION);
|
String hostHeader = response.getFirstHeaderOrNull(HttpHeaders.LOCATION);
|
||||||
if (hostHeader != null && command.incrementRedirectCount() < retryCountLimit) {
|
if (command.incrementRedirectCount() < retryCountLimit && hostHeader != null) {
|
||||||
URI redirectionUrl = uriBuilderProvider.get().uri(URI.create(hostHeader)).build();
|
URI redirectionUrl = URI.create(hostHeader);
|
||||||
if (redirectionUrl.getScheme().equals(command.getRequest().getEndpoint().getScheme())
|
|
||||||
&& redirectionUrl.getHost().equals(command.getRequest().getEndpoint().getHost())
|
// if you are sent the same uri, assume there's a transient problem and retry.
|
||||||
&& redirectionUrl.getPort() == command.getRequest().getEndpoint().getPort()) {
|
if (redirectionUrl.equals(command.getRequest().getEndpoint()))
|
||||||
if (!redirectionUrl.getPath().equals(command.getRequest().getEndpoint().getPath())) {
|
return backoffHandler.shouldRetryRequest(command, response);
|
||||||
changePathTo(command.getRequest(), redirectionUrl.getPath(), uriBuilderProvider
|
|
||||||
.get());
|
UriBuilder builder = uriBuilderProvider.get().uri(command.getRequest().getEndpoint());
|
||||||
} else {
|
assert redirectionUrl.getPath() != null : "no path in redirect header from: " + response;
|
||||||
return backoffHandler.shouldRetryRequest(command, response);
|
builder.replacePath(redirectionUrl.getPath());
|
||||||
}
|
|
||||||
} else {
|
if (redirectionUrl.getScheme() != null)
|
||||||
changeSchemeHostAndPortTo(command.getRequest(), redirectionUrl.getScheme(),
|
builder.scheme(redirectionUrl.getScheme());
|
||||||
redirectionUrl.getHost(), redirectionUrl.getPort(), uriBuilderProvider.get());
|
|
||||||
|
if (redirectionUrl.getHost() != null) {
|
||||||
|
builder.host(redirectionUrl.getHost());
|
||||||
|
if (command.getRequest().getFirstHeaderOrNull(HOST) != null)
|
||||||
|
command.getRequest().getHeaders().replaceValues(HOST, singletonList(redirectionUrl.getHost()));
|
||||||
}
|
}
|
||||||
|
if (redirectionUrl.getPort() != command.getRequest().getEndpoint().getPort())
|
||||||
|
builder.port(redirectionUrl.getPort());
|
||||||
|
|
||||||
|
if (redirectionUrl.getQuery() != null)
|
||||||
|
builder.replaceQuery(redirectionUrl.getQuery());
|
||||||
|
|
||||||
|
command.getRequest().setEndpoint(builder.build());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -227,7 +227,7 @@ public class JavaUrlHttpCommandExecutorService extends BaseHttpCommandExecutorSe
|
||||||
connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH, "0");
|
connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH, "0");
|
||||||
// for some reason POST/PUT undoes the content length header above.
|
// for some reason POST/PUT undoes the content length header above.
|
||||||
if (connection.getRequestMethod().equals("POST") || connection.getRequestMethod().equals("PUT"))
|
if (connection.getRequestMethod().equals("POST") || connection.getRequestMethod().equals("PUT"))
|
||||||
connection.setChunkedStreamingMode(0);
|
connection.setFixedLengthStreamingMode(0);
|
||||||
}
|
}
|
||||||
return connection;
|
return connection;
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,8 @@ import org.jclouds.json.internal.GsonWrapper;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.primitives.Bytes;
|
import com.google.common.primitives.Bytes;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JcloudsCompactFormatter;
|
import com.google.gson.JcloudsCompactFormatter;
|
||||||
|
import com.google.gson.JcloudsGsonBuilder;
|
||||||
import com.google.gson.JsonDeserializationContext;
|
import com.google.gson.JsonDeserializationContext;
|
||||||
import com.google.gson.JsonDeserializer;
|
import com.google.gson.JsonDeserializer;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
|
@ -64,9 +64,9 @@ public class GsonModule extends AbstractModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
Gson provideGson(JsonBallAdapter jsonObjectAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
|
Gson provideGson(JsonBallAdapter jsonObjectAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
|
||||||
ByteArrayAdapter byteArrayAdapter, JsonAdapterBindings bindings) throws SecurityException,
|
ByteArrayAdapter byteArrayAdapter, JsonAdapterBindings bindings) throws ClassNotFoundException, Exception {
|
||||||
NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
|
JcloudsGsonBuilder builder = new JcloudsGsonBuilder();
|
||||||
GsonBuilder builder = new GsonBuilder();
|
|
||||||
builder.registerTypeAdapter(JsonBall.class, jsonObjectAdapter);
|
builder.registerTypeAdapter(JsonBall.class, jsonObjectAdapter);
|
||||||
builder.registerTypeAdapter(Date.class, adapter);
|
builder.registerTypeAdapter(Date.class, adapter);
|
||||||
builder.registerTypeAdapter(new TypeToken<List<Byte>>() {
|
builder.registerTypeAdapter(new TypeToken<List<Byte>>() {
|
||||||
|
@ -105,7 +105,7 @@ public class GsonModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Byte> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public List<Byte> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
return Bytes.asList(CryptoStreams.hex(json.getAsString()));
|
return Bytes.asList(CryptoStreams.hex(json.getAsString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ public class GsonModule extends AbstractModule {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
return CryptoStreams.hex(json.getAsString());
|
return CryptoStreams.hex(json.getAsString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ public class GsonModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
String toParse = json.getAsJsonPrimitive().getAsString();
|
String toParse = json.getAsJsonPrimitive().getAsString();
|
||||||
try {
|
try {
|
||||||
return dateService.iso8601DateParse(toParse);
|
return dateService.iso8601DateParse(toParse);
|
||||||
|
@ -170,7 +170,7 @@ public class GsonModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
String toParse = json.getAsJsonPrimitive().getAsString();
|
String toParse = json.getAsJsonPrimitive().getAsString();
|
||||||
Date toReturn = dateService.cDateParse(toParse);
|
Date toReturn = dateService.cDateParse(toParse);
|
||||||
return toReturn;
|
return toReturn;
|
||||||
|
@ -191,7 +191,7 @@ public class GsonModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
public JsonBall deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public JsonBall deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
return new JsonBall(json.toString());
|
return new JsonBall(json.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ public class GsonModule extends AbstractModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
|
||||||
throws JsonParseException {
|
throws JsonParseException {
|
||||||
long toParse = json.getAsJsonPrimitive().getAsLong();
|
long toParse = json.getAsJsonPrimitive().getAsLong();
|
||||||
if (toParse == -1)
|
if (toParse == -1)
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.jclouds.rest;
|
package org.jclouds.rest;
|
||||||
|
|
||||||
import org.jclouds.http.HttpRequest;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thrown when there is an authorization error.
|
* Thrown when there is an authorization error.
|
||||||
|
@ -39,14 +38,6 @@ public class AuthorizationException extends RuntimeException {
|
||||||
super(arg0, arg1);
|
super(arg0, arg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthorizationException(HttpRequest resource, String error) {
|
|
||||||
super(String.format("%s -> %s", resource.getRequestLine(), error));
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthorizationException(HttpRequest resource, String error, Throwable arg1) {
|
|
||||||
super(String.format("%s -> %s", resource.getRequestLine(), error), arg1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AuthorizationException(Throwable arg0) {
|
public AuthorizationException(Throwable arg0) {
|
||||||
super(arg0);
|
super(arg0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -1,123 +1,126 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
# Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
#
|
#
|
||||||
# ====================================================================
|
# ====================================================================
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
# You may obtain a copy of the License at
|
# You may obtain a copy of the License at
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
# ====================================================================
|
# ====================================================================
|
||||||
#
|
#
|
||||||
azurequeue.contextbuilder=org.jclouds.azure.storage.AzureStorageContextBuilder
|
azurequeue.contextbuilder=org.jclouds.azure.storage.AzureStorageContextBuilder
|
||||||
azurequeue.sync=org.jclouds.azure.storage.queue.AzureQueueClient
|
azurequeue.sync=org.jclouds.azure.storage.queue.AzureQueueClient
|
||||||
azurequeue.async=org.jclouds.azure.storage.queue.AzureQueueAsyncClient
|
azurequeue.async=org.jclouds.azure.storage.queue.AzureQueueAsyncClient
|
||||||
azurequeue.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder
|
azurequeue.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder
|
||||||
azurequeue.endpoint=https://{identity}.queue.core.windows.net
|
azurequeue.endpoint=https://{identity}.queue.core.windows.net
|
||||||
|
|
||||||
azureblob.contextbuilder=org.jclouds.azure.storage.blob.AzureBlobContextBuilder
|
azureblob.contextbuilder=org.jclouds.azure.storage.blob.AzureBlobContextBuilder
|
||||||
azureblob.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder
|
azureblob.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder
|
||||||
azureblob.endpoint=https://{identity}.blob.core.windows.net
|
azureblob.endpoint=https://{identity}.blob.core.windows.net
|
||||||
|
|
||||||
pcs.contextbuilder=org.jclouds.mezeo.pcs2.PCSContextBuilder
|
pcs.contextbuilder=org.jclouds.mezeo.pcs2.PCSContextBuilder
|
||||||
pcs.apiVersion=unknown
|
pcs.apiVersion=unknown
|
||||||
|
|
||||||
sdn.contextbuilder=org.jclouds.nirvanix.sdn.SDNContextBuilder
|
sdn.contextbuilder=org.jclouds.nirvanix.sdn.SDNContextBuilder
|
||||||
sdn.propertiesbuilder=org.jclouds.nirvanix.sdn.SDNPropertiesBuilder
|
sdn.propertiesbuilder=org.jclouds.nirvanix.sdn.SDNPropertiesBuilder
|
||||||
|
|
||||||
sqs.contextbuilder=org.jclouds.aws.sqs.SQSContextBuilder
|
sqs.contextbuilder=org.jclouds.aws.sqs.SQSContextBuilder
|
||||||
sqs.propertiesbuilder=org.jclouds.aws.sqs.SQSPropertiesBuilder
|
sqs.propertiesbuilder=org.jclouds.aws.sqs.SQSPropertiesBuilder
|
||||||
|
|
||||||
elb.contextbuilder=org.jclouds.aws.elb.ELBContextBuilder
|
elb.contextbuilder=org.jclouds.aws.elb.ELBContextBuilder
|
||||||
elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder
|
elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder
|
||||||
|
|
||||||
cloudwatch.contextbuilder=org.jclouds.aws.cloudwatch.CloudWatchContextBuilder
|
cloudwatch.contextbuilder=org.jclouds.aws.cloudwatch.CloudWatchContextBuilder
|
||||||
cloudwatch.propertiesbuilder=org.jclouds.aws.cloudwatch.CloudWatchPropertiesBuilder
|
cloudwatch.propertiesbuilder=org.jclouds.aws.cloudwatch.CloudWatchPropertiesBuilder
|
||||||
|
|
||||||
s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
s3.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
||||||
s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
|
s3.propertiesbuilder=org.jclouds.aws.s3.S3PropertiesBuilder
|
||||||
|
|
||||||
ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
|
ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
|
||||||
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
|
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
|
||||||
|
|
||||||
rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.RimuHostingContextBuilder
|
rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.RimuHostingContextBuilder
|
||||||
rimuhosting.propertiesbuilder=org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder
|
rimuhosting.propertiesbuilder=org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder
|
||||||
|
|
||||||
slicehost.contextbuilder=org.jclouds.slicehost.SlicehostContextBuilder
|
slicehost.contextbuilder=org.jclouds.slicehost.SlicehostContextBuilder
|
||||||
slicehost.propertiesbuilder=org.jclouds.slicehost.SlicehostPropertiesBuilder
|
slicehost.propertiesbuilder=org.jclouds.slicehost.SlicehostPropertiesBuilder
|
||||||
|
|
||||||
trmk-vcloudexpress.contextbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressContextBuilder
|
trmk-vcloudexpress.contextbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressContextBuilder
|
||||||
trmk-vcloudexpress.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressPropertiesBuilder
|
trmk-vcloudexpress.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudExpressPropertiesBuilder
|
||||||
|
|
||||||
trmk-ecloud.contextbuilder=org.jclouds.vcloud.terremark.TerremarkECloudContextBuilder
|
trmk-ecloud.contextbuilder=org.jclouds.vcloud.terremark.TerremarkECloudContextBuilder
|
||||||
trmk-ecloud.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkECloudPropertiesBuilder
|
trmk-ecloud.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkECloudPropertiesBuilder
|
||||||
|
|
||||||
chef.contextbuilder=org.jclouds.chef.ChefContextBuilder
|
chef.contextbuilder=org.jclouds.chef.ChefContextBuilder
|
||||||
chef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
|
chef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
|
||||||
|
|
||||||
transientchef.contextbuilder=org.jclouds.chef.test.TransientChefContextBuilder
|
transientchef.contextbuilder=org.jclouds.chef.test.TransientChefContextBuilder
|
||||||
transientchef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
|
transientchef.propertiesbuilder=org.jclouds.chef.ChefPropertiesBuilder
|
||||||
|
|
||||||
opscodeplatform.contextbuilder=org.jclouds.opscodeplatform.OpscodePlatformContextBuilder
|
opscodeplatform.contextbuilder=org.jclouds.opscodeplatform.OpscodePlatformContextBuilder
|
||||||
opscodeplatform.propertiesbuilder=org.jclouds.opscodeplatform.OpscodePlatformPropertiesBuilder
|
opscodeplatform.propertiesbuilder=org.jclouds.opscodeplatform.OpscodePlatformPropertiesBuilder
|
||||||
|
|
||||||
vcloud.contextbuilder=org.jclouds.vcloud.VCloudContextBuilder
|
vcloud.contextbuilder=org.jclouds.vcloud.VCloudContextBuilder
|
||||||
vcloud.propertiesbuilder=org.jclouds.vcloud.VCloudPropertiesBuilder
|
vcloud.propertiesbuilder=org.jclouds.vcloud.VCloudPropertiesBuilder
|
||||||
|
|
||||||
vcloudexpress.contextbuilder=org.jclouds.vcloud.VCloudExpressContextBuilder
|
vcloudexpress.contextbuilder=org.jclouds.vcloud.VCloudExpressContextBuilder
|
||||||
vcloudexpress.propertiesbuilder=org.jclouds.vcloud.VCloudExpressPropertiesBuilder
|
vcloudexpress.propertiesbuilder=org.jclouds.vcloud.VCloudExpressPropertiesBuilder
|
||||||
|
|
||||||
eucalyptus.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
|
eucalyptus.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
|
||||||
eucalyptus.propertiesbuilder=org.jclouds.aws.ec2.EucalyptusPropertiesBuilder
|
eucalyptus.propertiesbuilder=org.jclouds.aws.ec2.EucalyptusPropertiesBuilder
|
||||||
|
|
||||||
nova.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
|
nova.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
|
||||||
nova.propertiesbuilder=org.jclouds.aws.ec2.NovaPropertiesBuilder
|
nova.propertiesbuilder=org.jclouds.aws.ec2.NovaPropertiesBuilder
|
||||||
|
|
||||||
cloudservers.contextbuilder=org.jclouds.rackspace.cloudservers.CloudServersContextBuilder
|
cloudservers.contextbuilder=org.jclouds.rackspace.cloudservers.CloudServersContextBuilder
|
||||||
cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder
|
cloudservers.propertiesbuilder=org.jclouds.rackspace.RackspacePropertiesBuilder
|
||||||
|
|
||||||
bluelock-vcdirector.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorContextBuilder
|
bluelock-vcdirector.contextbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorContextBuilder
|
||||||
bluelock-vcdirector.propertiesbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorPropertiesBuilder
|
bluelock-vcdirector.propertiesbuilder=org.jclouds.vcloud.bluelock.BlueLockVCloudDirectorPropertiesBuilder
|
||||||
|
|
||||||
gogrid.propertiesbuilder=org.jclouds.gogrid.GoGridPropertiesBuilder
|
gogrid.propertiesbuilder=org.jclouds.gogrid.GoGridPropertiesBuilder
|
||||||
gogrid.contextbuilder=org.jclouds.gogrid.GoGridContextBuilder
|
gogrid.contextbuilder=org.jclouds.gogrid.GoGridContextBuilder
|
||||||
|
|
||||||
ibmdev.propertiesbuilder=org.jclouds.ibmdev.IBMDeveloperCloudPropertiesBuilder
|
ibmdev.propertiesbuilder=org.jclouds.ibmdev.IBMDeveloperCloudPropertiesBuilder
|
||||||
ibmdev.contextbuilder=org.jclouds.ibmdev.IBMDeveloperCloudContextBuilder
|
ibmdev.contextbuilder=org.jclouds.ibmdev.IBMDeveloperCloudContextBuilder
|
||||||
|
|
||||||
stub.contextbuilder=org.jclouds.compute.stub.StubComputeServiceContextBuilder
|
stub.contextbuilder=org.jclouds.compute.stub.StubComputeServiceContextBuilder
|
||||||
# example of where to change your endpoint
|
# example of where to change your endpoint
|
||||||
# bluelock.endpoint=https://express3.bluelock.com/api
|
# bluelock.endpoint=https://express3.bluelock.com/api
|
||||||
|
|
||||||
atmosonline.contextbuilder=org.jclouds.atmosonline.saas.AtmosStorageContextBuilder
|
atmosonline.contextbuilder=org.jclouds.atmosonline.saas.AtmosStorageContextBuilder
|
||||||
atmosonline.endpoint=https://accesspoint.atmosonline.com
|
atmosonline.endpoint=https://accesspoint.atmosonline.com
|
||||||
atmosonline.apiversion=1.3.0
|
atmosonline.apiversion=1.3.0
|
||||||
|
|
||||||
synaptic.contextbuilder=org.jclouds.atmosonline.saas.AtmosStorageContextBuilder
|
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
|
||||||
cloudfiles.contextbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesContextBuilder
|
peer1-storage.apiversion=1.3.0
|
||||||
cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder
|
|
||||||
|
# TODO hostedsolutions use atmos
|
||||||
walrus.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
|
||||||
walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder
|
cloudfiles.contextbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesContextBuilder
|
||||||
|
cloudfiles.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesPropertiesBuilder
|
||||||
googlestorage.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
|
||||||
googlestorage.propertiesbuilder=org.jclouds.aws.s3.GoogleStoragePropertiesBuilder
|
walrus.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
||||||
|
walrus.propertiesbuilder=org.jclouds.aws.s3.WalrusPropertiesBuilder
|
||||||
transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder
|
|
||||||
transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder
|
googlestorage.contextbuilder=org.jclouds.aws.s3.S3ContextBuilder
|
||||||
|
googlestorage.propertiesbuilder=org.jclouds.aws.s3.GoogleStoragePropertiesBuilder
|
||||||
filesystem.contextbuilder=org.jclouds.filesystem.FilesystemBlobStoreContextBuilder
|
|
||||||
filesystem.propertiesbuilder=org.jclouds.filesystem.FilesystemBlobStorePropertiesBuilder
|
transient.contextbuilder=org.jclouds.blobstore.TransientBlobStoreContextBuilder
|
||||||
|
transient.propertiesbuilder=org.jclouds.blobstore.TransientBlobStorePropertiesBuilder
|
||||||
|
|
||||||
|
filesystem.contextbuilder=org.jclouds.filesystem.FilesystemBlobStoreContextBuilder
|
||||||
|
filesystem.propertiesbuilder=org.jclouds.filesystem.FilesystemBlobStorePropertiesBuilder
|
|
@ -0,0 +1,141 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.http.functions;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
import static org.easymock.classextension.EasyMock.verify;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
import org.xml.sax.Locator;
|
||||||
|
import org.xml.sax.SAXParseException;
|
||||||
|
|
||||||
|
public class ParseSaxTest extends BaseHandlerTest {
|
||||||
|
public static class TestHandler extends ParseSax.HandlerWithResult<String> {
|
||||||
|
@Override
|
||||||
|
public String getResult() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseSax<String> createParser() {
|
||||||
|
return factory.create(injector.getInstance(TestHandler.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddDetailsAndPropagateOkWhenRequestWithNoDataAndRuntimeExceptionThrowsOriginalException()
|
||||||
|
throws ExecutionException, InterruptedException, TimeoutException, IOException {
|
||||||
|
|
||||||
|
ParseSax<String> parser = createParser();
|
||||||
|
Exception input = new RuntimeException("foo");
|
||||||
|
|
||||||
|
try {
|
||||||
|
parser.addDetailsAndPropagate(null, input);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
assertEquals(e, input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddDetailsAndPropagateOkWhenRequestWithNoDataAndExceptionPropagates() throws ExecutionException,
|
||||||
|
InterruptedException, TimeoutException, IOException {
|
||||||
|
|
||||||
|
ParseSax<String> parser = createParser();
|
||||||
|
Exception input = new Exception("foo");
|
||||||
|
|
||||||
|
try {
|
||||||
|
parser.addDetailsAndPropagate(null, input);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
assertEquals(e.getMessage(), "java.lang.Exception: foo");
|
||||||
|
assertEquals(e.getCause(), input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddDetailsAndPropagateOkWhenRequestIsNotNullAndResponseIsNull() throws ExecutionException,
|
||||||
|
InterruptedException, TimeoutException, IOException {
|
||||||
|
|
||||||
|
ParseSax<String> parser = createParser();
|
||||||
|
HttpRequest request = new HttpRequest("GET", URI.create("http://foohost"));
|
||||||
|
Exception input = new Exception("foo");
|
||||||
|
|
||||||
|
try {
|
||||||
|
parser.setContext(request);
|
||||||
|
parser.addDetailsAndPropagate(null, input);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
assertEquals(e.getMessage(), "request: GET http://foohost HTTP/1.1; cause: java.lang.Exception: foo");
|
||||||
|
assertEquals(e.getCause(), input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddDetailsAndPropagateOkWithValidRequestResponse() throws ExecutionException, InterruptedException,
|
||||||
|
TimeoutException, IOException {
|
||||||
|
|
||||||
|
ParseSax<String> parser = createParser();
|
||||||
|
HttpRequest request = new HttpRequest("GET", URI.create("http://foohost"));
|
||||||
|
HttpResponse response = new HttpResponse(304, "Not Modified", null);
|
||||||
|
Exception input = new Exception("foo");
|
||||||
|
|
||||||
|
try {
|
||||||
|
parser.setContext(request);
|
||||||
|
parser.addDetailsAndPropagate(response, input);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
assertEquals(e.getMessage(), "request: GET http://foohost HTTP/1.1; response: HTTP/1.1 304 Not Modified; cause: java.lang.Exception: foo");
|
||||||
|
assertEquals(e.getCause(), input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddDetailsAndPropagateOkWithValidRequestResponseWithSAXParseException() throws ExecutionException,
|
||||||
|
InterruptedException, TimeoutException, IOException {
|
||||||
|
|
||||||
|
ParseSax<String> parser = createParser();
|
||||||
|
HttpRequest request = new HttpRequest("GET", URI.create("http://foohost"));
|
||||||
|
HttpResponse response = new HttpResponse(304, "Not Modified", null);
|
||||||
|
Locator locator = createMock(Locator.class);
|
||||||
|
expect(locator.getColumnNumber()).andReturn(1);
|
||||||
|
expect(locator.getLineNumber()).andReturn(1);
|
||||||
|
expect(locator.getPublicId()).andReturn("publicId");
|
||||||
|
expect(locator.getSystemId()).andReturn("systemId");
|
||||||
|
replay(locator);
|
||||||
|
Exception input = new SAXParseException("foo", locator);
|
||||||
|
verify(locator);
|
||||||
|
|
||||||
|
try {
|
||||||
|
parser.setContext(request);
|
||||||
|
parser.addDetailsAndPropagate(response, input);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
assertEquals(e.getMessage(),
|
||||||
|
"request: GET http://foohost HTTP/1.1; response: HTTP/1.1 304 Not Modified; error at 1:1 in document systemId; cause: org.xml.sax.SAXParseException: foo");
|
||||||
|
assertEquals(e.getCause(), input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,171 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.http.handlers;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.classextension.EasyMock.createMock;
|
||||||
|
import static org.easymock.classextension.EasyMock.replay;
|
||||||
|
import static org.easymock.classextension.EasyMock.verify;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.HttpHeaders;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpCommand;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.rest.BaseRestClientTest.MockModule;
|
||||||
|
import org.jclouds.rest.config.RestModule;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code RedirectionRetryHandler}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "http.RedirectionRetryHandlerTest")
|
||||||
|
public class RedirectionRetryHandlerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test302DoesNotRetry() {
|
||||||
|
|
||||||
|
HttpCommand command = createMock(HttpCommand.class);
|
||||||
|
HttpResponse response = new HttpResponse(302, "HTTP/1.1 302 Found", null);
|
||||||
|
|
||||||
|
expect(command.incrementRedirectCount()).andReturn(0);
|
||||||
|
|
||||||
|
replay(command);
|
||||||
|
|
||||||
|
RedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
||||||
|
RedirectionRetryHandler.class);
|
||||||
|
|
||||||
|
assert !retry.shouldRetryRequest(command, response);
|
||||||
|
|
||||||
|
verify(command);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test302DoesNotRetryAfterLimit() {
|
||||||
|
|
||||||
|
HttpCommand command = createMock(HttpCommand.class);
|
||||||
|
HttpResponse response = new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(
|
||||||
|
HttpHeaders.LOCATION, "/api/v0.8b-ext2.5/Error.aspx?aspxerrorpath=/api/v0.8b-ext2.5/org.svc/1906645"));
|
||||||
|
|
||||||
|
expect(command.incrementRedirectCount()).andReturn(5);
|
||||||
|
|
||||||
|
replay(command);
|
||||||
|
|
||||||
|
RedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
||||||
|
RedirectionRetryHandler.class);
|
||||||
|
|
||||||
|
assert !retry.shouldRetryRequest(command, response);
|
||||||
|
|
||||||
|
verify(command);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test302WithPathOnlyHeader() {
|
||||||
|
|
||||||
|
verifyRedirectRoutes(
|
||||||
|
new HttpRequest("GET",
|
||||||
|
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||||
|
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||||
|
"/api/v0.8b-ext2.5/Error.aspx?aspxerrorpath=/api/v0.8b-ext2.5/org.svc/1906645")),
|
||||||
|
new HttpRequest(
|
||||||
|
"GET",
|
||||||
|
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/Error.aspx?aspxerrorpath=/api/v0.8b-ext2.5/org.svc/1906645")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test302ToHttps() {
|
||||||
|
|
||||||
|
verifyRedirectRoutes(
|
||||||
|
new HttpRequest("GET",
|
||||||
|
URI.create("http://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||||
|
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||||
|
"https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),//
|
||||||
|
new HttpRequest("GET", URI
|
||||||
|
.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test302ToDifferentPort() {
|
||||||
|
|
||||||
|
verifyRedirectRoutes(
|
||||||
|
new HttpRequest("GET",
|
||||||
|
URI.create("http://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||||
|
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||||
|
"http://services.enterprisecloud.terremark.com:3030/api/v0.8b-ext2.5/org/1906645")),//
|
||||||
|
new HttpRequest("GET", URI
|
||||||
|
.create("http://services.enterprisecloud.terremark.com:3030/api/v0.8b-ext2.5/org/1906645")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test302WithHeader() {
|
||||||
|
|
||||||
|
verifyRedirectRoutes(
|
||||||
|
new HttpRequest("GET",
|
||||||
|
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),
|
||||||
|
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||||
|
"https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")), new HttpRequest(
|
||||||
|
"GET", URI.create("https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test302WithHeaderReplacesHostHeader() {
|
||||||
|
|
||||||
|
verifyRedirectRoutes(
|
||||||
|
new HttpRequest("GET",
|
||||||
|
URI.create("https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645"),
|
||||||
|
ImmutableMultimap.of(HttpHeaders.HOST, "services.enterprisecloud.terremark.com")),
|
||||||
|
new HttpResponse(302, "HTTP/1.1 302 Found", null, ImmutableMultimap.of(HttpHeaders.LOCATION,
|
||||||
|
"https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645")),//
|
||||||
|
new HttpRequest("GET", URI
|
||||||
|
.create("https://services1.enterprisecloud.terremark.com/api/v0.8b-ext2.5/org/1906645"),
|
||||||
|
ImmutableMultimap.of(HttpHeaders.HOST, "services1.enterprisecloud.terremark.com")));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void verifyRedirectRoutes(HttpRequest request, HttpResponse response, HttpRequest expected) {
|
||||||
|
HttpCommand command = createMock(HttpCommand.class);
|
||||||
|
|
||||||
|
expect(command.incrementRedirectCount()).andReturn(0);
|
||||||
|
expect(command.getRequest()).andReturn(request).atLeastOnce();
|
||||||
|
|
||||||
|
replay(command);
|
||||||
|
|
||||||
|
RedirectionRetryHandler retry = Guice.createInjector(new MockModule(), new RestModule()).getInstance(
|
||||||
|
RedirectionRetryHandler.class);
|
||||||
|
|
||||||
|
assert retry.shouldRetryRequest(command, response);
|
||||||
|
assertEquals(command.getRequest(), expected);
|
||||||
|
verify(command);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.json;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public class JsonTest {
|
||||||
|
private Json json = Guice.createInjector(new GsonModule()).getInstance(Json.class);
|
||||||
|
|
||||||
|
private static class EnumInside {
|
||||||
|
private static enum Test {
|
||||||
|
FOO, BAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Test enumValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeserializeEnum() {
|
||||||
|
assertEquals(json.fromJson("{enumValue : \"FOO\"}", EnumInside.class).enumValue, EnumInside.Test.FOO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = JsonParseException.class)
|
||||||
|
public void testDeserializeEnumWhenBadValue() {
|
||||||
|
assertEquals(json.fromJson("{enumValue : \"s\"}", EnumInside.class).enumValue, EnumInside.Test.FOO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class EnumInsideWithParser {
|
||||||
|
private static enum Test {
|
||||||
|
FOO, BAR, UNRECOGNIZED;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static Test fromValue(String state) {
|
||||||
|
try {
|
||||||
|
return valueOf(state);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return UNRECOGNIZED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Test enumValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeserializeEnumWithParser() {
|
||||||
|
assertEquals(json.fromJson("{enumValue : \"FOO\"}", EnumInsideWithParser.class).enumValue,
|
||||||
|
EnumInsideWithParser.Test.FOO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeserializeEnumWithParserAndBadValue() {
|
||||||
|
assertEquals(json.fromJson("{enumValue : \"sd\"}", EnumInsideWithParser.class).enumValue,
|
||||||
|
EnumInsideWithParser.Test.UNRECOGNIZED);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -29,12 +29,13 @@ import static org.testng.Assert.assertNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.concurrent.MoreExecutors;
|
import org.jclouds.concurrent.MoreExecutors;
|
||||||
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
import org.jclouds.concurrent.config.ConfiguresExecutorService;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
|
||||||
import org.jclouds.crypto.Crypto;
|
import org.jclouds.crypto.Crypto;
|
||||||
import org.jclouds.crypto.CryptoStreams;
|
import org.jclouds.crypto.CryptoStreams;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
|
@ -47,6 +48,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
public abstract class BaseRestClientTest {
|
public abstract class BaseRestClientTest {
|
||||||
|
|
||||||
|
@ -69,7 +71,8 @@ public abstract class BaseRestClientTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors.sameThreadExecutor()));
|
bind(ExecutorService.class).annotatedWith(Names.named(Constants.PROPERTY_USER_THREADS)).toInstance(MoreExecutors.sameThreadExecutor());
|
||||||
|
bind(ExecutorService.class).annotatedWith(Names.named(Constants.PROPERTY_IO_WORKER_THREADS)).toInstance(MoreExecutors.sameThreadExecutor());
|
||||||
bind(TransformingHttpCommandExecutorService.class).toInstance(mock);
|
bind(TransformingHttpCommandExecutorService.class).toInstance(mock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,44 +255,44 @@
|
||||||
<configuration>
|
<configuration>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
<property>
|
||||||
<name>twitter.identity</name>
|
<name>test.twitter.identity</name>
|
||||||
<value>${jclouds.twitter.user}</value>
|
<value>${test.twitter.identity}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>twitter.credential</name>
|
<name>test.twitter.credential</name>
|
||||||
<value>${jclouds.twitter.password}</value>
|
<value>${test.twitter.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>azureblob.identity</name>
|
<name>test.azureblob.identity</name>
|
||||||
<value>${jclouds.azure.storage.account}</value>
|
<value>${test.azureblob.identity}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>azureblob.credential</name>
|
<name>test.azureblob.credential</name>
|
||||||
<value>${jclouds.azure.storage.key}</value>
|
<value>${test.azureblob.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>cloudfiles.identity</name>
|
<name>test.cloudfiles.identity</name>
|
||||||
<value>${jclouds.rackspace.user}</value>
|
<value>${test.cloudfiles.identity}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>cloudfiles.credential</name>
|
<name>test.cloudfiles.credential</name>
|
||||||
<value>${jclouds.rackspace.key}</value>
|
<value>${test.cloudfiles.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>googlestorage.identity</name>
|
<name>test.googlestorage.identity</name>
|
||||||
<value>${jclouds.googlestorage.accesskeyid}</value>
|
<value>${test.googlestorage.identity}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>googlestorage.credential</name>
|
<name>test.googlestorage.credential</name>
|
||||||
<value>${jclouds.googlestorage.secretaccesskey}</value>
|
<value>${test.googlestorage.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>s3.identity</name>
|
<name>test.s3.identity</name>
|
||||||
<value>${jclouds.aws.accesskeyid}</value>
|
<value>${test.s3.identity}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>s3.credential</name>
|
<name>test.s3.credential</name>
|
||||||
<value>${jclouds.aws.secretaccesskey}</value>
|
<value>${test.s3.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>appengine.home</name>
|
<name>appengine.home</name>
|
||||||
|
|
|
@ -1,202 +1,202 @@
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
*
|
*
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* ====================================================================
|
* ====================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jclouds.demo.tweetstore.config;
|
package org.jclouds.demo.tweetstore.config;
|
||||||
|
|
||||||
import static com.google.appengine.api.labs.taskqueue.TaskOptions.Builder.url;
|
import static com.google.appengine.api.labs.taskqueue.TaskOptions.Builder.url;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.demo.tweetstore.reference.TweetStoreConstants.PROPERTY_TWEETSTORE_CONTAINER;
|
import static org.jclouds.demo.tweetstore.reference.TweetStoreConstants.PROPERTY_TWEETSTORE_CONTAINER;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import javax.servlet.ServletConfig;
|
import javax.servlet.ServletConfig;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
|
||||||
import org.jclouds.blobstore.BlobStoreContext;
|
import org.jclouds.blobstore.BlobStoreContext;
|
||||||
import org.jclouds.blobstore.BlobStoreContextFactory;
|
import org.jclouds.blobstore.BlobStoreContextFactory;
|
||||||
import org.jclouds.demo.tweetstore.controller.AddTweetsController;
|
import org.jclouds.demo.tweetstore.controller.AddTweetsController;
|
||||||
import org.jclouds.demo.tweetstore.controller.StoreTweetsController;
|
import org.jclouds.demo.tweetstore.controller.StoreTweetsController;
|
||||||
import org.jclouds.demo.tweetstore.functions.ServiceToStoredTweetStatuses;
|
import org.jclouds.demo.tweetstore.functions.ServiceToStoredTweetStatuses;
|
||||||
import org.jclouds.gae.config.GoogleAppEngineConfigurationModule;
|
import org.jclouds.gae.config.GoogleAppEngineConfigurationModule;
|
||||||
import org.springframework.beans.factory.BeanCreationException;
|
import org.springframework.beans.factory.BeanCreationException;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.web.context.ServletConfigAware;
|
import org.springframework.web.context.ServletConfigAware;
|
||||||
import org.springframework.web.servlet.HandlerAdapter;
|
import org.springframework.web.servlet.HandlerAdapter;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
|
import org.springframework.web.servlet.handler.SimpleServletHandlerAdapter;
|
||||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
|
|
||||||
import twitter4j.Twitter;
|
import twitter4j.Twitter;
|
||||||
import twitter4j.TwitterFactory;
|
import twitter4j.TwitterFactory;
|
||||||
|
|
||||||
import com.google.appengine.api.labs.taskqueue.Queue;
|
import com.google.appengine.api.labs.taskqueue.Queue;
|
||||||
import com.google.appengine.api.labs.taskqueue.QueueFactory;
|
import com.google.appengine.api.labs.taskqueue.QueueFactory;
|
||||||
import com.google.appengine.api.labs.taskqueue.TaskOptions.Method;
|
import com.google.appengine.api.labs.taskqueue.TaskOptions.Method;
|
||||||
import com.google.appengine.repackaged.com.google.common.base.Splitter;
|
import com.google.appengine.repackaged.com.google.common.base.Splitter;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.io.Closeables;
|
import com.google.common.io.Closeables;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates servlets (using resources from the {@link SpringAppConfig}) and mappings.
|
* Creates servlets (using resources from the {@link SpringAppConfig}) and mappings.
|
||||||
*
|
*
|
||||||
* @author Andrew Phillips
|
* @author Andrew Phillips
|
||||||
* @see SpringAppConfig
|
* @see SpringAppConfig
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class SpringServletConfig extends LoggingConfig implements ServletConfigAware {
|
public class SpringServletConfig extends LoggingConfig implements ServletConfigAware {
|
||||||
public static final String PROPERTY_BLOBSTORE_CONTEXTS = "blobstore.contexts";
|
public static final String PROPERTY_BLOBSTORE_CONTEXTS = "blobstore.contexts";
|
||||||
|
|
||||||
private ServletConfig servletConfig;
|
private ServletConfig servletConfig;
|
||||||
|
|
||||||
private Map<String, BlobStoreContext> providerTypeToBlobStoreMap;
|
private Map<String, BlobStoreContext> providerTypeToBlobStoreMap;
|
||||||
private Twitter twitterClient;
|
private Twitter twitterClient;
|
||||||
private String container;
|
private String container;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void initialize() throws IOException {
|
public void initialize() throws IOException {
|
||||||
BlobStoreContextFactory blobStoreContextFactory = new BlobStoreContextFactory();
|
BlobStoreContextFactory blobStoreContextFactory = new BlobStoreContextFactory();
|
||||||
|
|
||||||
Properties props = loadJCloudsProperties();
|
Properties props = loadJCloudsProperties();
|
||||||
logger.trace("About to initialize members.");
|
logger.trace("About to initialize members.");
|
||||||
|
|
||||||
Module googleModule = new GoogleAppEngineConfigurationModule();
|
Module googleModule = new GoogleAppEngineConfigurationModule();
|
||||||
Set<Module> modules = ImmutableSet.<Module> of(googleModule);
|
Set<Module> modules = ImmutableSet.<Module> of(googleModule);
|
||||||
// shared across all blobstores and used to retrieve tweets
|
// shared across all blobstores and used to retrieve tweets
|
||||||
try {
|
try {
|
||||||
twitterClient = new TwitterFactory().getInstance(props.getProperty("twitter.identity"), props
|
twitterClient = new TwitterFactory().getInstance(props.getProperty("twitter.identity"),
|
||||||
.getProperty("credential"));
|
props.getProperty("twitter.credential"));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new IllegalArgumentException("properties for twitter not configured properly in " + props.toString(), e);
|
throw new IllegalArgumentException("properties for twitter not configured properly in " + props.toString(), e);
|
||||||
}
|
}
|
||||||
// common namespace for storing tweets
|
// common namespace for storing tweets
|
||||||
container = checkNotNull(props.getProperty(PROPERTY_TWEETSTORE_CONTAINER), PROPERTY_TWEETSTORE_CONTAINER);
|
container = checkNotNull(props.getProperty(PROPERTY_TWEETSTORE_CONTAINER), PROPERTY_TWEETSTORE_CONTAINER);
|
||||||
|
|
||||||
// instantiate and store references to all blobstores by provider name
|
// instantiate and store references to all blobstores by provider name
|
||||||
providerTypeToBlobStoreMap = Maps.newHashMap();
|
providerTypeToBlobStoreMap = Maps.newHashMap();
|
||||||
for (String hint : Splitter.on(',').split(
|
for (String hint : Splitter.on(',').split(
|
||||||
checkNotNull(props.getProperty(PROPERTY_BLOBSTORE_CONTEXTS), PROPERTY_BLOBSTORE_CONTEXTS))) {
|
checkNotNull(props.getProperty(PROPERTY_BLOBSTORE_CONTEXTS), PROPERTY_BLOBSTORE_CONTEXTS))) {
|
||||||
providerTypeToBlobStoreMap.put(hint, blobStoreContextFactory.createContext(hint, modules, props));
|
providerTypeToBlobStoreMap.put(hint, blobStoreContextFactory.createContext(hint, modules, props));
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a queue for submitting store tweet requests
|
// get a queue for submitting store tweet requests
|
||||||
Queue queue = QueueFactory.getQueue("twitter");
|
Queue queue = QueueFactory.getQueue("twitter");
|
||||||
// submit a job to store tweets for each configured blobstore
|
// submit a job to store tweets for each configured blobstore
|
||||||
for (String name : providerTypeToBlobStoreMap.keySet()) {
|
for (String name : providerTypeToBlobStoreMap.keySet()) {
|
||||||
queue.add(url("/store/do").header("context", name).method(Method.GET));
|
queue.add(url("/store/do").header("context", name).method(Method.GET));
|
||||||
}
|
}
|
||||||
logger.trace("Members initialized. Twitter: '%s', container: '%s', provider types: '%s'", twitterClient,
|
logger.trace("Members initialized. Twitter: '%s', container: '%s', provider types: '%s'", twitterClient,
|
||||||
container, providerTypeToBlobStoreMap.keySet());
|
container, providerTypeToBlobStoreMap.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Properties loadJCloudsProperties() {
|
private Properties loadJCloudsProperties() {
|
||||||
logger.trace("About to read properties from '%s'", "/WEB-INF/jclouds.properties");
|
logger.trace("About to read properties from '%s'", "/WEB-INF/jclouds.properties");
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
InputStream input = servletConfig.getServletContext().getResourceAsStream("/WEB-INF/jclouds.properties");
|
InputStream input = servletConfig.getServletContext().getResourceAsStream("/WEB-INF/jclouds.properties");
|
||||||
try {
|
try {
|
||||||
props.load(input);
|
props.load(input);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
} finally {
|
} finally {
|
||||||
Closeables.closeQuietly(input);
|
Closeables.closeQuietly(input);
|
||||||
}
|
}
|
||||||
logger.trace("Properties successfully read.");
|
logger.trace("Properties successfully read.");
|
||||||
return props;
|
return props;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public StoreTweetsController storeTweetsController() {
|
public StoreTweetsController storeTweetsController() {
|
||||||
StoreTweetsController controller = new StoreTweetsController(providerTypeToBlobStoreMap, container, twitterClient);
|
StoreTweetsController controller = new StoreTweetsController(providerTypeToBlobStoreMap, container, twitterClient);
|
||||||
injectServletConfig(controller);
|
injectServletConfig(controller);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public AddTweetsController addTweetsController() {
|
public AddTweetsController addTweetsController() {
|
||||||
AddTweetsController controller = new AddTweetsController(providerTypeToBlobStoreMap,
|
AddTweetsController controller = new AddTweetsController(providerTypeToBlobStoreMap,
|
||||||
serviceToStoredTweetStatuses());
|
serviceToStoredTweetStatuses());
|
||||||
injectServletConfig(controller);
|
injectServletConfig(controller);
|
||||||
return controller;
|
return controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void injectServletConfig(Servlet servlet) {
|
private void injectServletConfig(Servlet servlet) {
|
||||||
logger.trace("About to inject servlet config '%s'", servletConfig);
|
logger.trace("About to inject servlet config '%s'", servletConfig);
|
||||||
try {
|
try {
|
||||||
servlet.init(checkNotNull(servletConfig));
|
servlet.init(checkNotNull(servletConfig));
|
||||||
} catch (ServletException exception) {
|
} catch (ServletException exception) {
|
||||||
throw new BeanCreationException("Unable to instantiate " + servlet, exception);
|
throw new BeanCreationException("Unable to instantiate " + servlet, exception);
|
||||||
}
|
}
|
||||||
logger.trace("Successfully injected servlet config.");
|
logger.trace("Successfully injected servlet config.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
ServiceToStoredTweetStatuses serviceToStoredTweetStatuses() {
|
ServiceToStoredTweetStatuses serviceToStoredTweetStatuses() {
|
||||||
return new ServiceToStoredTweetStatuses(providerTypeToBlobStoreMap, container);
|
return new ServiceToStoredTweetStatuses(providerTypeToBlobStoreMap, container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public HandlerMapping handlerMapping() {
|
public HandlerMapping handlerMapping() {
|
||||||
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
|
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
|
||||||
Map<String, Object> urlMap = Maps.newHashMapWithExpectedSize(2);
|
Map<String, Object> urlMap = Maps.newHashMapWithExpectedSize(2);
|
||||||
urlMap.put("/store/*", storeTweetsController());
|
urlMap.put("/store/*", storeTweetsController());
|
||||||
urlMap.put("/tweets/*", addTweetsController());
|
urlMap.put("/tweets/*", addTweetsController());
|
||||||
mapping.setUrlMap(urlMap);
|
mapping.setUrlMap(urlMap);
|
||||||
/*
|
/*
|
||||||
* "/store" and "/tweets" are part of the servlet mapping and thus stripped by the mapping if
|
* "/store" and "/tweets" are part of the servlet mapping and thus stripped by the mapping if
|
||||||
* using default settings.
|
* using default settings.
|
||||||
*/
|
*/
|
||||||
mapping.setAlwaysUseFullPath(true);
|
mapping.setAlwaysUseFullPath(true);
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public HandlerAdapter servletHandlerAdapter() {
|
public HandlerAdapter servletHandlerAdapter() {
|
||||||
return new SimpleServletHandlerAdapter();
|
return new SimpleServletHandlerAdapter();
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
@PreDestroy
|
||||||
public void destroy() throws Exception {
|
public void destroy() throws Exception {
|
||||||
logger.trace("About to close contexts.");
|
logger.trace("About to close contexts.");
|
||||||
for (BlobStoreContext context : providerTypeToBlobStoreMap.values()) {
|
for (BlobStoreContext context : providerTypeToBlobStoreMap.values()) {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
logger.trace("Contexts closed.");
|
logger.trace("Contexts closed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
*
|
*
|
||||||
* @see
|
* @see
|
||||||
* org.springframework.web.context.ServletConfigAware#setServletConfig(javax.servlet.ServletConfig
|
* org.springframework.web.context.ServletConfigAware#setServletConfig(javax.servlet.ServletConfig
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setServletConfig(ServletConfig servletConfig) {
|
public void setServletConfig(ServletConfig servletConfig) {
|
||||||
this.servletConfig = servletConfig;
|
this.servletConfig = servletConfig;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,9 +27,9 @@ import java.io.InputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
@ -70,16 +70,17 @@ public class TweetStoreLiveTest {
|
||||||
private String container;
|
private String container;
|
||||||
|
|
||||||
private static final String blobs = System.getProperty("jclouds.tweetstore.blobstores",
|
private static final String blobs = System.getProperty("jclouds.tweetstore.blobstores",
|
||||||
"cloudfiles,googlestorage,s3,azureblob");
|
"cloudfiles,googlestorage,s3,azureblob");
|
||||||
private static final Iterable<String> blobstores = Splitter.on(',').split(blobs);
|
private static final Iterable<String> blobstores = Splitter.on(',').split(blobs);
|
||||||
private static final Properties props = new Properties();
|
private static final Properties props = new Properties();
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
void clearAndCreateContainers() throws InterruptedException, ExecutionException, TimeoutException, IOException, TwitterException {
|
void clearAndCreateContainers() throws InterruptedException, ExecutionException, TimeoutException, IOException,
|
||||||
|
TwitterException {
|
||||||
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER));
|
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER));
|
||||||
|
|
||||||
props.setProperty(PROPERTY_TWEETSTORE_CONTAINER, checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER),
|
props.setProperty(PROPERTY_TWEETSTORE_CONTAINER,
|
||||||
PROPERTY_TWEETSTORE_CONTAINER));
|
checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER), PROPERTY_TWEETSTORE_CONTAINER));
|
||||||
|
|
||||||
props.setProperty(SpringServletConfig.PROPERTY_BLOBSTORE_CONTEXTS, Joiner.on(',').join(blobstores));
|
props.setProperty(SpringServletConfig.PROPERTY_BLOBSTORE_CONTEXTS, Joiner.on(',').join(blobstores));
|
||||||
|
|
||||||
|
@ -98,8 +99,8 @@ public class TweetStoreLiveTest {
|
||||||
contexts.put(provider, factory.createContext(provider, wiring, props));
|
contexts.put(provider, factory.createContext(provider, wiring, props));
|
||||||
}
|
}
|
||||||
|
|
||||||
Twitter client = new TwitterFactory().getInstance(props.getProperty("twitter.identity"), props
|
Twitter client = new TwitterFactory().getInstance(props.getProperty("twitter.identity"),
|
||||||
.getProperty("twitter.credential"));
|
props.getProperty("twitter.credential"));
|
||||||
StoreTweetsController controller = new StoreTweetsController(contexts, container, client);
|
StoreTweetsController controller = new StoreTweetsController(contexts, container, client);
|
||||||
|
|
||||||
ResponseList<Status> statuses = client.getMentions();
|
ResponseList<Status> statuses = client.getMentions();
|
||||||
|
@ -108,7 +109,7 @@ public class TweetStoreLiveTest {
|
||||||
for (BlobStoreContext context : contexts.values()) {
|
for (BlobStoreContext context : contexts.values()) {
|
||||||
if (context.getBlobStore().containerExists(container)) {
|
if (context.getBlobStore().containerExists(container)) {
|
||||||
System.err.printf("deleting container %s at %s%n", container, context.getProviderSpecificContext()
|
System.err.printf("deleting container %s at %s%n", container, context.getProviderSpecificContext()
|
||||||
.getEndpoint());
|
.getEndpoint());
|
||||||
context.getBlobStore().deleteContainer(container);
|
context.getBlobStore().deleteContainer(container);
|
||||||
deleted = true;
|
deleted = true;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +120,7 @@ public class TweetStoreLiveTest {
|
||||||
}
|
}
|
||||||
for (BlobStoreContext context : contexts.values()) {
|
for (BlobStoreContext context : contexts.values()) {
|
||||||
System.err.printf("creating container %s at %s%n", container, context.getProviderSpecificContext()
|
System.err.printf("creating container %s at %s%n", container, context.getProviderSpecificContext()
|
||||||
.getEndpoint());
|
.getEndpoint());
|
||||||
context.getBlobStore().createContainerInLocation(null, container);
|
context.getBlobStore().createContainerInLocation(null, container);
|
||||||
}
|
}
|
||||||
if (deleted) {
|
if (deleted) {
|
||||||
|
@ -134,22 +135,23 @@ public class TweetStoreLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConfigurationForTwitter(Properties props) {
|
private void addConfigurationForTwitter(Properties props) {
|
||||||
props.setProperty("twitter.identity", checkNotNull(System.getProperty("twitter.identity"), "twitter.identity"));
|
props.setProperty("twitter.identity",
|
||||||
props.setProperty("twitter.credential", checkNotNull(System.getProperty("twitter.credential"),
|
checkNotNull(System.getProperty("test.twitter.identity"), "test.twitter.identity"));
|
||||||
"twitter.credential"));
|
props.setProperty("twitter.credential",
|
||||||
|
checkNotNull(System.getProperty("test.twitter.credential"), "test.twitter.credential"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCredentialsForBlobStores(Properties props) {
|
private void addCredentialsForBlobStores(Properties props) {
|
||||||
for (String provider : blobstores) {
|
for (String provider : blobstores) {
|
||||||
props.setProperty(provider + ".identity", checkNotNull(System.getProperty(provider + ".identity"), provider
|
props.setProperty(provider + ".identity",
|
||||||
+ ".identity"));
|
checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"));
|
||||||
props.setProperty(provider + ".credential", checkNotNull(System.getProperty(provider + ".credential"),
|
props.setProperty(provider + ".credential",
|
||||||
provider + ".credential"));
|
checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + ".credential"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
@Parameters( { "warfile", "devappserver.address", "devappserver.port" })
|
@Parameters({ "warfile", "devappserver.address", "devappserver.port" })
|
||||||
public void startDevAppServer(final String warfile, final String address, final String port) throws Exception {
|
public void startDevAppServer(final String warfile, final String address, final String port) throws Exception {
|
||||||
url = new URL(String.format("http://%s:%s", address, port));
|
url = new URL(String.format("http://%s:%s", address, port));
|
||||||
server = new GoogleDevServer();
|
server = new GoogleDevServer();
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class GuiceServletConfig extends GuiceServletContextListener {
|
||||||
// shared across all blobstores and used to retrieve tweets
|
// shared across all blobstores and used to retrieve tweets
|
||||||
try {
|
try {
|
||||||
twitterClient = new TwitterFactory().getInstance(props.getProperty("twitter.identity"), props
|
twitterClient = new TwitterFactory().getInstance(props.getProperty("twitter.identity"), props
|
||||||
.getProperty("credential"));
|
.getProperty("twitter.credential"));
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
throw new IllegalArgumentException("properties for twitter not configured properly in " + props.toString(), e);
|
throw new IllegalArgumentException("properties for twitter not configured properly in " + props.toString(), e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,9 @@ import java.io.InputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ import com.google.common.collect.Maps;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts up the Google App Engine for Java Development environment and deploys
|
* Starts up the Google App Engine for Java Development environment and deploys an application which
|
||||||
* an application which tests accesses twitter and blobstores.
|
* tests accesses twitter and blobstores.
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -75,11 +75,12 @@ public class TweetStoreLiveTest {
|
||||||
private static final Properties props = new Properties();
|
private static final Properties props = new Properties();
|
||||||
|
|
||||||
@BeforeTest
|
@BeforeTest
|
||||||
void clearAndCreateContainers() throws InterruptedException, ExecutionException, TimeoutException, IOException, TwitterException {
|
void clearAndCreateContainers() throws InterruptedException, ExecutionException, TimeoutException, IOException,
|
||||||
|
TwitterException {
|
||||||
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER));
|
container = checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER));
|
||||||
|
|
||||||
props.setProperty(PROPERTY_TWEETSTORE_CONTAINER, checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER),
|
props.setProperty(PROPERTY_TWEETSTORE_CONTAINER,
|
||||||
PROPERTY_TWEETSTORE_CONTAINER));
|
checkNotNull(System.getProperty(PROPERTY_TWEETSTORE_CONTAINER), PROPERTY_TWEETSTORE_CONTAINER));
|
||||||
|
|
||||||
props.setProperty(GuiceServletConfig.PROPERTY_BLOBSTORE_CONTEXTS, Joiner.on(',').join(blobstores));
|
props.setProperty(GuiceServletConfig.PROPERTY_BLOBSTORE_CONTEXTS, Joiner.on(',').join(blobstores));
|
||||||
|
|
||||||
|
@ -98,8 +99,8 @@ public class TweetStoreLiveTest {
|
||||||
contexts.put(provider, factory.createContext(provider, wiring, props));
|
contexts.put(provider, factory.createContext(provider, wiring, props));
|
||||||
}
|
}
|
||||||
|
|
||||||
Twitter client = new TwitterFactory().getInstance(props.getProperty("twitter.identity"), props
|
Twitter client = new TwitterFactory().getInstance(props.getProperty("twitter.identity"),
|
||||||
.getProperty("twitter.credential"));
|
props.getProperty("twitter.credential"));
|
||||||
StoreTweetsController controller = new StoreTweetsController(contexts, container, client);
|
StoreTweetsController controller = new StoreTweetsController(contexts, container, client);
|
||||||
|
|
||||||
ResponseList<Status> statuses = client.getMentions();
|
ResponseList<Status> statuses = client.getMentions();
|
||||||
|
@ -139,7 +140,7 @@ public class TweetStoreLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@BeforeTest(dependsOnMethods = "clearAndCreateContainers")
|
@BeforeTest(dependsOnMethods = "clearAndCreateContainers")
|
||||||
@Parameters( { "warfile", "devappserver.address", "devappserver.port" })
|
@Parameters({ "warfile", "devappserver.address", "devappserver.port" })
|
||||||
public void startDevAppServer(final String warfile, final String address, final String port) throws Exception {
|
public void startDevAppServer(final String warfile, final String address, final String port) throws Exception {
|
||||||
url = new URL(String.format("http://%s:%s", address, port));
|
url = new URL(String.format("http://%s:%s", address, port));
|
||||||
|
|
||||||
|
@ -148,17 +149,17 @@ public class TweetStoreLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addConfigurationForTwitter(Properties props) {
|
private void addConfigurationForTwitter(Properties props) {
|
||||||
props.setProperty("twitter.identity", checkNotNull(System.getProperty("twitter.identity"), "twitter.identity"));
|
props.setProperty("twitter.identity", checkNotNull(System.getProperty("test.twitter.identity"), "test.twitter.identity"));
|
||||||
props.setProperty("twitter.credential", checkNotNull(System.getProperty("twitter.credential"),
|
props.setProperty("twitter.credential",
|
||||||
"twitter.credential"));
|
checkNotNull(System.getProperty("test.twitter.credential"), "test.twitter.credential"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addCredentialsForBlobStores(Properties props) {
|
private void addCredentialsForBlobStores(Properties props) {
|
||||||
for (String provider : blobstores) {
|
for (String provider : blobstores) {
|
||||||
props.setProperty(provider + ".identity", checkNotNull(System.getProperty(provider + ".identity"), provider
|
props.setProperty(provider + ".identity",
|
||||||
+ ".identity"));
|
checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"));
|
||||||
props.setProperty(provider + ".credential", checkNotNull(System.getProperty(provider + ".credential"),
|
props.setProperty(provider + ".credential",
|
||||||
provider + ".credential"));
|
checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + ".credential"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,6 @@ package org.jclouds.filesystem.reference;
|
||||||
public class FilesystemConstants {
|
public class FilesystemConstants {
|
||||||
|
|
||||||
/** Specify the base directory where provider starts its file operations - must exists */
|
/** Specify the base directory where provider starts its file operations - must exists */
|
||||||
public static final String PROPERTY_BASEDIR = "FileSystemAsyncBlobStore-basedir";
|
public static final String PROPERTY_BASEDIR = "jclouds.filesystem.basedir";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -335,12 +335,12 @@ public class FilesystemStorageStrategyImpl implements FilesystemStorageStrategy
|
||||||
* @return the resulting string
|
* @return the resulting string
|
||||||
*/
|
*/
|
||||||
protected String buildPathStartingFromBaseDir(String...pathTokens) {
|
protected String buildPathStartingFromBaseDir(String...pathTokens) {
|
||||||
String normalizedToken = removeFileSeparatorFromBorders(normalize(baseDirectory));
|
String normalizedToken = removeFileSeparatorFromBorders(normalize(baseDirectory), true);
|
||||||
StringBuilder completePath = new StringBuilder(normalizedToken);
|
StringBuilder completePath = new StringBuilder(normalizedToken);
|
||||||
if(pathTokens!=null && pathTokens.length>0) {
|
if(pathTokens!=null && pathTokens.length>0) {
|
||||||
for(int i=0; i<pathTokens.length; i++) {
|
for(int i=0; i<pathTokens.length; i++) {
|
||||||
if(pathTokens[i]!=null) {
|
if(pathTokens[i]!=null) {
|
||||||
normalizedToken = removeFileSeparatorFromBorders(normalize(pathTokens[i]));
|
normalizedToken = removeFileSeparatorFromBorders(normalize(pathTokens[i]), false);
|
||||||
completePath.append(File.separator).append(normalizedToken);
|
completePath.append(File.separator).append(normalizedToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,16 +367,19 @@ public class FilesystemStorageStrategyImpl implements FilesystemStorageStrategy
|
||||||
* Remove leading and trailing {@link File.separator} character from the
|
* Remove leading and trailing {@link File.separator} character from the
|
||||||
* string.
|
* string.
|
||||||
* @param pathToBeCleaned
|
* @param pathToBeCleaned
|
||||||
|
* @param remove only trailing separator char from path
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private String removeFileSeparatorFromBorders(String pathToBeCleaned) {
|
private String removeFileSeparatorFromBorders(String pathToBeCleaned, boolean onlyTrailing) {
|
||||||
if (null == pathToBeCleaned || pathToBeCleaned.equals("")) return pathToBeCleaned;
|
if (null == pathToBeCleaned || pathToBeCleaned.equals("")) return pathToBeCleaned;
|
||||||
|
|
||||||
int beginIndex = 0;
|
int beginIndex = 0;
|
||||||
int endIndex = pathToBeCleaned.length();
|
int endIndex = pathToBeCleaned.length();
|
||||||
|
|
||||||
//search for separator chars
|
//search for separator chars
|
||||||
if (pathToBeCleaned.substring(0, 1).equals(File.separator)) beginIndex = 1;
|
if (!onlyTrailing) {
|
||||||
|
if (pathToBeCleaned.substring(0, 1).equals(File.separator)) beginIndex = 1;
|
||||||
|
}
|
||||||
if (pathToBeCleaned.substring(pathToBeCleaned.length() - 1).equals(File.separator)) endIndex--;
|
if (pathToBeCleaned.substring(pathToBeCleaned.length() - 1).equals(File.separator)) endIndex--;
|
||||||
|
|
||||||
return pathToBeCleaned.substring(beginIndex, endIndex);
|
return pathToBeCleaned.substring(beginIndex, endIndex);
|
||||||
|
|
|
@ -185,16 +185,8 @@ public class FilesystemAsyncBlobStoreTest {
|
||||||
/**
|
/**
|
||||||
* Test of list method, of class FilesystemAsyncBlobStore.
|
* Test of list method, of class FilesystemAsyncBlobStore.
|
||||||
*/
|
*/
|
||||||
public void testList_NoOptionSingleContainer() throws IOException {
|
public void testList_NoOptionSingleContainer()
|
||||||
|
throws IOException {
|
||||||
// Testing list for a not existing container
|
|
||||||
try {
|
|
||||||
blobStore.list(CONTAINER_NAME);
|
|
||||||
fail("Found a not existing container");
|
|
||||||
} catch(ContainerNotFoundException e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
blobStore.createContainerInLocation(null, CONTAINER_NAME);
|
blobStore.createContainerInLocation(null, CONTAINER_NAME);
|
||||||
// Testing list for an empty container
|
// Testing list for an empty container
|
||||||
checkForContainerContent(CONTAINER_NAME, null);
|
checkForContainerContent(CONTAINER_NAME, null);
|
||||||
|
@ -268,6 +260,29 @@ public class FilesystemAsyncBlobStoreTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testList_Subdirectory()
|
||||||
|
throws IOException {
|
||||||
|
blobStore.createContainerInLocation(null, CONTAINER_NAME);
|
||||||
|
// Testing list for an empty container
|
||||||
|
checkForContainerContent(CONTAINER_NAME, null);
|
||||||
|
|
||||||
|
//creates blobs in first container
|
||||||
|
Set<String> blobsExpected = TestUtils.createBlobsInContainer(
|
||||||
|
CONTAINER_NAME,
|
||||||
|
new String[] {
|
||||||
|
"bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg",
|
||||||
|
"4rrr.jpg",
|
||||||
|
"rrr" + File.separator + "sss" + File.separator + "788.jpg",
|
||||||
|
"rrr" + File.separator + "wert.kpg" }
|
||||||
|
);
|
||||||
|
|
||||||
|
//remove not expected values
|
||||||
|
blobsExpected.remove("bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg");
|
||||||
|
blobsExpected.remove("4rrr.jpg");
|
||||||
|
|
||||||
|
checkForContainerContent(CONTAINER_NAME, "rrr", blobsExpected);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
* Should throws an exception?
|
* Should throws an exception?
|
||||||
|
@ -809,12 +824,17 @@ public class FilesystemAsyncBlobStoreTest {
|
||||||
* @param expectedBlobKeys
|
* @param expectedBlobKeys
|
||||||
*/
|
*/
|
||||||
private void checkForContainerContent(final String containerName, Set<String> expectedBlobKeys) {
|
private void checkForContainerContent(final String containerName, Set<String> expectedBlobKeys) {
|
||||||
|
checkForContainerContent(containerName, null, expectedBlobKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkForContainerContent(final String containerName, String inDirectory, Set<String> expectedBlobKeys) {
|
||||||
ListContainerOptions options = ListContainerOptions.Builder.recursive();
|
ListContainerOptions options = ListContainerOptions.Builder.recursive();
|
||||||
|
if (null != inDirectory && !"".equals(inDirectory)) options.inDirectory(inDirectory);
|
||||||
|
|
||||||
PageSet<? extends StorageMetadata> blobsRetrieved = blobStore.list(containerName, options);
|
PageSet<? extends StorageMetadata> blobsRetrieved = blobStore.list(containerName, options);
|
||||||
|
|
||||||
//nothing expected
|
//nothing expected
|
||||||
if (null == expectedBlobKeys) {
|
if (null == expectedBlobKeys || 0 == expectedBlobKeys.size()) {
|
||||||
assertTrue(blobsRetrieved.isEmpty(), "Wrong blob number retrieved in the containter [" + containerName + "]");
|
assertTrue(blobsRetrieved.isEmpty(), "Wrong blob number retrieved in the containter [" + containerName + "]");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -417,6 +417,38 @@ public class FilesystemStorageStrategyImplTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testGetFileForBlobKey_AbsolutePath()
|
||||||
|
throws IOException {
|
||||||
|
String absoluteBasePath = (new File(getAbsoluteDirectory(), "basedir")).getAbsolutePath() + FS;
|
||||||
|
String absoluteContainerPath = absoluteBasePath + CONTAINER_NAME + FS;
|
||||||
|
|
||||||
|
//create storageStrategy with an absolute path
|
||||||
|
FilesystemStorageStrategy storageStrategyAbsolute = new FilesystemStorageStrategyImpl(
|
||||||
|
new Blob.Factory() {
|
||||||
|
@Override
|
||||||
|
public Blob create(MutableBlobMetadata metadata) {
|
||||||
|
return new BlobImpl(metadata != null ? metadata : new MutableBlobMetadataImpl());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
absoluteBasePath,
|
||||||
|
new FilesystemContainerNameValidatorImpl(),
|
||||||
|
new FilesystemBlobKeyValidatorImpl());
|
||||||
|
TestUtils.cleanDirectoryContent(absoluteContainerPath);
|
||||||
|
|
||||||
|
String blobKey;
|
||||||
|
File fileForPayload;
|
||||||
|
|
||||||
|
blobKey = TestUtils.createRandomBlobKey("getFileForBlobKey-", ".img");
|
||||||
|
fileForPayload = storageStrategyAbsolute.getFileForBlobKey(CONTAINER_NAME, blobKey);
|
||||||
|
assertNotNull(fileForPayload, "Result File object is null");
|
||||||
|
assertEquals(fileForPayload.getAbsolutePath(), absoluteContainerPath + blobKey, "Wrong file path");
|
||||||
|
|
||||||
|
blobKey = TestUtils.createRandomBlobKey("asd" + FS + "vmad" + FS + "andsnf" + FS + "getFileForBlobKey-", ".img");
|
||||||
|
fileForPayload = storageStrategyAbsolute.getFileForBlobKey(CONTAINER_NAME, blobKey);
|
||||||
|
assertEquals(fileForPayload.getAbsolutePath(), absoluteContainerPath + blobKey, "Wrong file path");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void testBlobExists() throws IOException {
|
public void testBlobExists() throws IOException {
|
||||||
String[] sourceBlobKeys = new String[]{
|
String[] sourceBlobKeys = new String[]{
|
||||||
TestUtils.createRandomBlobKey("blobExists-", ".jpg"),
|
TestUtils.createRandomBlobKey("blobExists-", ".jpg"),
|
||||||
|
@ -530,5 +562,16 @@ public class FilesystemStorageStrategyImplTest {
|
||||||
//---------------------------------------------------------- Private methods
|
//---------------------------------------------------------- Private methods
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates an absolute directory path that depends on operative system
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getAbsoluteDirectory() throws IOException {
|
||||||
|
File tempFile = File.createTempFile("prefix", "suffix");
|
||||||
|
String tempAbsolutePath = tempFile.getParent();
|
||||||
|
|
||||||
|
return tempAbsolutePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
</scm>
|
</scm>
|
||||||
<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.gogrid.endpoint>https://api.gogrid.com/api</test.gogrid.endpoint>
|
<test.gogrid.endpoint>https://api.gogrid.com/api</test.gogrid.endpoint>
|
||||||
<test.gogrid.apiversion>1.5</test.gogrid.apiversion>
|
<test.gogrid.apiversion>1.5</test.gogrid.apiversion>
|
||||||
<test.gogrid.identity>FIXME</test.gogrid.identity>
|
<test.gogrid.identity>FIXME</test.gogrid.identity>
|
||||||
|
@ -119,8 +119,8 @@
|
||||||
<value>${test.gogrid.credential}</value>
|
<value>${test.gogrid.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>jclouds.compute.blacklist.nodes</name>
|
<name>jclouds.compute.blacklist-nodes</name>
|
||||||
<value>${jclouds.compute.blacklist.nodes}</value>
|
<value>${jclouds.compute.blacklist-nodes}</value>
|
||||||
</property>
|
</property>
|
||||||
</systemProperties>
|
</systemProperties>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.jclouds.gogrid.compute.suppliers;
|
package org.jclouds.gogrid.compute.suppliers;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
@ -34,6 +35,7 @@ import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||||
|
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||||
import org.jclouds.gogrid.GoGridClient;
|
import org.jclouds.gogrid.GoGridClient;
|
||||||
import org.jclouds.gogrid.domain.ServerImage;
|
import org.jclouds.gogrid.domain.ServerImage;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
@ -56,9 +58,12 @@ public class GoGridImageSupplier implements Supplier<Set<? extends Image>> {
|
||||||
|
|
||||||
private final GoGridClient sync;
|
private final GoGridClient sync;
|
||||||
private final PopulateDefaultLoginCredentialsForImageStrategy authenticator;
|
private final PopulateDefaultLoginCredentialsForImageStrategy authenticator;
|
||||||
|
private final Map<OsFamily, Map<String, String>> osVersionMap;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GoGridImageSupplier(final GoGridClient sync, PopulateDefaultLoginCredentialsForImageStrategy authenticator) {
|
GoGridImageSupplier(GoGridClient sync, PopulateDefaultLoginCredentialsForImageStrategy authenticator,
|
||||||
|
Map<OsFamily, Map<String, String>> osVersionMap) {
|
||||||
|
this.osVersionMap = osVersionMap;
|
||||||
this.sync = sync;
|
this.sync = sync;
|
||||||
this.authenticator = authenticator;
|
this.authenticator = authenticator;
|
||||||
}
|
}
|
||||||
|
@ -85,29 +90,28 @@ public class GoGridImageSupplier implements Supplier<Set<? extends Image>> {
|
||||||
OsFamily osFamily = null;
|
OsFamily osFamily = null;
|
||||||
String osName = from.getOs().getName();
|
String osName = from.getOs().getName();
|
||||||
String osArch = from.getArchitecture().getDescription();
|
String osArch = from.getArchitecture().getDescription();
|
||||||
String osVersion = parseVersion(osName);
|
String osVersion = null;
|
||||||
String osDescription = from.getOs().getDescription();
|
String osDescription = from.getOs().getDescription();
|
||||||
boolean is64Bit = (from.getOs().getName().indexOf("64") != -1 || from.getDescription().indexOf("64") != -1);
|
boolean is64Bit = (from.getOs().getName().indexOf("64") != -1 || from.getDescription().indexOf("64") != -1);
|
||||||
|
|
||||||
Matcher matcher = GOGRID_OS_PATTERN.matcher(from.getName());
|
if (osName.startsWith("Windows")) {
|
||||||
if (matcher.find()) {
|
osFamily = OsFamily.WINDOWS;
|
||||||
try {
|
} else {
|
||||||
osFamily = OsFamily.fromValue(matcher.group(1).toLowerCase());
|
Matcher matcher = GOGRID_OS_PATTERN.matcher(from.getName());
|
||||||
} catch (IllegalArgumentException e) {
|
if (matcher.find()) {
|
||||||
logger.debug("<< didn't match os(%s)", from.getName());
|
try {
|
||||||
|
osFamily = OsFamily.fromValue(matcher.group(1).toLowerCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.debug("<< didn't match os(%s)", from.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Matcher matcher = GOGRID_VERSION_PATTERN.matcher(osName);
|
||||||
// TODO determine DC images are in
|
|
||||||
OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
static String parseVersion(String name) {
|
|
||||||
Matcher matcher = GOGRID_VERSION_PATTERN.matcher(name);
|
|
||||||
if (matcher.find()) {
|
if (matcher.find()) {
|
||||||
return matcher.group(1);
|
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(1), osVersionMap);
|
||||||
}
|
}
|
||||||
return null;
|
// TODO determine DC images are in
|
||||||
|
return new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -53,23 +53,17 @@ public class GoGridErrorHandler implements HttpErrorHandler {
|
||||||
try {
|
try {
|
||||||
Exception exception = new HttpResponseException(command, response);
|
Exception exception = new HttpResponseException(command, response);
|
||||||
Set<ErrorResponse> errors = parseErrorsFromContentOrNull(response);
|
Set<ErrorResponse> errors = parseErrorsFromContentOrNull(response);
|
||||||
|
if (errors != null)
|
||||||
|
exception = new GoGridResponseException(command, response, errors);
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
case 400:
|
case 400:
|
||||||
if (Iterables.get(errors, 0).getMessage()
|
if (Iterables.get(errors, 0).getMessage().indexOf("No object found") != -1) {
|
||||||
.indexOf("No object found") != -1) {
|
exception = new ResourceNotFoundException(Iterables.get(errors, 0).getMessage(), exception);
|
||||||
exception = new ResourceNotFoundException(Iterables.get(errors,
|
|
||||||
0).getMessage(), exception);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 403:
|
case 403:
|
||||||
|
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||||
exception = new AuthorizationException(command.getRequest(),
|
|
||||||
errors != null ? errors.toString() : response.getStatusLine());
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
exception = errors != null ? new GoGridResponseException(command,
|
|
||||||
response, errors) : new HttpResponseException(command,
|
|
||||||
response);
|
|
||||||
}
|
}
|
||||||
command.setException(exception);
|
command.setException(exception);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.gogrid.compute;
|
||||||
|
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||||
|
import org.jclouds.compute.OsFamilyVersion64Bit;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "gogrid.GoGridTemplateBuilderLiveTest")
|
||||||
|
public class GoGridTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
|
|
||||||
|
public GoGridTemplateBuilderLiveTest() {
|
||||||
|
provider = "gogrid";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||||
|
return new Predicate<OsFamilyVersion64Bit>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(OsFamilyVersion64Bit input) {
|
||||||
|
return ((input.family == OsFamily.RHEL && !input.version.equals("5.4")) || //
|
||||||
|
(input.family == OsFamily.CENTOS && input.version.matches("5.[54]")) || //
|
||||||
|
(input.family == OsFamily.CENTOS && input.is64Bit && input.version.equals("5.4")) || //
|
||||||
|
(input.family == OsFamily.UBUNTU) || //
|
||||||
|
(input.family == OsFamily.WINDOWS && input.version.equals("2008 SP2") || //
|
||||||
|
(input.family == OsFamily.WINDOWS && input.version.equals("2008 R2"))));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultTemplateBuilder() throws IOException {
|
||||||
|
Template defaultTemplate = context.getComputeService().templateBuilder().build();
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "5.3");
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS);
|
||||||
|
assertEquals(getCores(defaultTemplate.getHardware()), 0.5d);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -521,6 +521,10 @@ pageTracker._trackPageview();
|
||||||
<artifactId>maven-install-plugin</artifactId>
|
<artifactId>maven-install-plugin</artifactId>
|
||||||
<version>2.3</version>
|
<version>2.3</version>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
|
<version>2.1</version>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</pluginManagement>
|
</pluginManagement>
|
||||||
</build>
|
</build>
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<test.rackspace.credential>FIXME</test.rackspace.credential>
|
<test.rackspace.credential>FIXME</test.rackspace.credential>
|
||||||
<test.initializer>org.jclouds.rackspace.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer>
|
<test.initializer>org.jclouds.rackspace.cloudfiles.blobstore.integration.CloudFilesTestInitializer</test.initializer>
|
||||||
<!-- 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.cloudfiles.endpoint>${test.rackspace.endpoint}</test.cloudfiles.endpoint>
|
<test.cloudfiles.endpoint>${test.rackspace.endpoint}</test.cloudfiles.endpoint>
|
||||||
<test.cloudfiles.apiversion>${test.rackspace.apiversion}</test.cloudfiles.apiversion>
|
<test.cloudfiles.apiversion>${test.rackspace.apiversion}</test.cloudfiles.apiversion>
|
||||||
<test.cloudfiles.identity>${test.rackspace.identity}</test.cloudfiles.identity>
|
<test.cloudfiles.identity>${test.rackspace.identity}</test.cloudfiles.identity>
|
||||||
|
@ -151,8 +151,8 @@
|
||||||
<value>${test.cloudservers.credential}</value>
|
<value>${test.cloudservers.credential}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>jclouds.compute.blacklist.nodes</name>
|
<name>jclouds.compute.blacklist-nodes</name>
|
||||||
<value>${jclouds.compute.blacklist.nodes}</value>
|
<value>${jclouds.compute.blacklist-nodes}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>test.initializer</name>
|
<name>test.initializer</name>
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class ParseCloudFilesErrorFromHttpResponse implements HttpErrorHandler {
|
||||||
exception = content != null ? new HttpResponseException(command, response, content) : exception;
|
exception = content != null ? new HttpResponseException(command, response, content) : exception;
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
case 401:
|
case 401:
|
||||||
exception = new AuthorizationException(command.getRequest(), content, exception);
|
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||||
|
|
|
@ -19,14 +19,9 @@
|
||||||
|
|
||||||
package org.jclouds.rackspace.cloudservers.compute.config;
|
package org.jclouds.rackspace.cloudservers.compute.config;
|
||||||
|
|
||||||
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
|
||||||
|
|
||||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
|
||||||
import org.jclouds.compute.internal.BaseComputeService;
|
import org.jclouds.compute.internal.BaseComputeService;
|
||||||
|
|
||||||
import com.google.inject.Injector;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configures the {@link CloudServersComputeServiceContext}; requires {@link BaseComputeService}
|
* Configures the {@link CloudServersComputeServiceContext}; requires {@link BaseComputeService}
|
||||||
* bound.
|
* bound.
|
||||||
|
@ -43,8 +38,4 @@ public class CloudServersComputeServiceContextModule extends BaseComputeServiceC
|
||||||
super.configure();
|
super.configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
|
||||||
return template.osFamily(UBUNTU).imageNameMatches(".*10\\.?04.*");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,16 +19,19 @@
|
||||||
|
|
||||||
package org.jclouds.rackspace.cloudservers.compute.functions;
|
package org.jclouds.rackspace.cloudservers.compute.functions;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -40,11 +43,20 @@ import com.google.common.base.Function;
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CloudServersImageToOperatingSystem implements
|
public class CloudServersImageToOperatingSystem implements
|
||||||
Function<org.jclouds.rackspace.cloudservers.domain.Image, OperatingSystem> {
|
Function<org.jclouds.rackspace.cloudservers.domain.Image, OperatingSystem> {
|
||||||
public static final Pattern RACKSPACE_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)");
|
public static final Pattern DEFAULT_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)");
|
||||||
|
// Windows Server 2008 R2 x64
|
||||||
|
public static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows (.*) (x[86][64])");
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
private final Map<OsFamily, Map<String, String>> osVersionMap;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public CloudServersImageToOperatingSystem(Map<OsFamily, Map<String, String>> osVersionMap) {
|
||||||
|
this.osVersionMap = osVersionMap;
|
||||||
|
}
|
||||||
|
|
||||||
public OperatingSystem apply(final org.jclouds.rackspace.cloudservers.domain.Image from) {
|
public OperatingSystem apply(final org.jclouds.rackspace.cloudservers.domain.Image from) {
|
||||||
OsFamily osFamily = null;
|
OsFamily osFamily = null;
|
||||||
|
@ -53,21 +65,28 @@ public class CloudServersImageToOperatingSystem implements
|
||||||
String osVersion = null;
|
String osVersion = null;
|
||||||
String osDescription = from.getName();
|
String osDescription = from.getName();
|
||||||
boolean is64Bit = true;
|
boolean is64Bit = true;
|
||||||
Matcher matcher = RACKSPACE_PATTERN.matcher(from.getName());
|
|
||||||
if (from.getName().indexOf("Red Hat EL") != -1) {
|
if (from.getName().indexOf("Red Hat EL") != -1) {
|
||||||
osFamily = OsFamily.RHEL;
|
osFamily = OsFamily.RHEL;
|
||||||
} else if (from.getName().indexOf("Oracle EL") != -1) {
|
} else if (from.getName().indexOf("Oracle EL") != -1) {
|
||||||
osFamily = OsFamily.OEL;
|
osFamily = OsFamily.OEL;
|
||||||
}
|
} else if (from.getName().indexOf("Windows") != -1) {
|
||||||
if (matcher.find()) {
|
osFamily = OsFamily.WINDOWS;
|
||||||
try {
|
Matcher matcher = WINDOWS_PATTERN.matcher(from.getName());
|
||||||
osFamily = OsFamily.fromValue(matcher.group(2).toLowerCase());
|
if (matcher.find()) {
|
||||||
} catch (IllegalArgumentException e) {
|
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(1), osVersionMap);
|
||||||
logger.debug("<< didn't match os(%s)", matcher.group(2));
|
is64Bit = matcher.group(2).equals("x64");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Matcher matcher = DEFAULT_PATTERN.matcher(from.getName());
|
||||||
|
if (matcher.find()) {
|
||||||
|
try {
|
||||||
|
osFamily = OsFamily.fromValue(matcher.group(2).toLowerCase());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.debug("<< didn't match os(%s)", matcher.group(2));
|
||||||
|
}
|
||||||
|
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(3), osVersionMap);
|
||||||
}
|
}
|
||||||
osVersion = matcher.group(3);
|
|
||||||
}
|
}
|
||||||
OperatingSystem os = new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
|
return new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit);
|
||||||
return os;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -52,9 +52,10 @@ public class ParseCloudServersErrorFromHttpResponse implements HttpErrorHandler
|
||||||
Exception exception = new HttpResponseException(command, response);
|
Exception exception = new HttpResponseException(command, response);
|
||||||
try {
|
try {
|
||||||
String content = parseErrorFromContentOrNull(command, response);
|
String content = parseErrorFromContentOrNull(command, response);
|
||||||
|
exception = content != null ? new HttpResponseException(command, response, content) : exception;
|
||||||
switch (response.getStatusCode()) {
|
switch (response.getStatusCode()) {
|
||||||
case 401:
|
case 401:
|
||||||
exception = new AuthorizationException(command.getRequest(), content);
|
exception = new AuthorizationException(exception.getMessage(), exception);
|
||||||
break;
|
break;
|
||||||
case 404:
|
case 404:
|
||||||
if (!command.getRequest().getMethod().equals("DELETE")) {
|
if (!command.getRequest().getMethod().equals("DELETE")) {
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTe
|
||||||
public void testTemplateBuilder() {
|
public void testTemplateBuilder() {
|
||||||
Template defaultTemplate = client.templateBuilder().build();
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
assertEquals(defaultTemplate.getLocation().getId(), "DFW1");
|
assertEquals(defaultTemplate.getLocation().getId(), "DFW1");
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
|
@ -66,7 +66,7 @@ public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTe
|
||||||
public void testAssignability() throws Exception {
|
public void testAssignability() throws Exception {
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
RestContext<CloudServersClient, CloudServersAsyncClient> tmContext = new ComputeServiceContextFactory()
|
RestContext<CloudServersClient, CloudServersAsyncClient> tmContext = new ComputeServiceContextFactory()
|
||||||
.createContext(provider, identity, credential).getProviderSpecificContext();
|
.createContext(provider, identity, credential).getProviderSpecificContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -82,4 +82,21 @@ public class CloudServersComputeServiceLiveTest extends BaseComputeServiceLiveTe
|
||||||
super.testSuspendResume();
|
super.testSuspendResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||||
|
@Override
|
||||||
|
public void testGetNodesWithDetails() throws Exception {
|
||||||
|
super.testGetNodesWithDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||||
|
@Override
|
||||||
|
public void testListNodes() throws Exception {
|
||||||
|
super.testListNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
|
||||||
|
@Override
|
||||||
|
public void testDestroyNodes() {
|
||||||
|
super.testDestroyNodes();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.rackspace.cloudservers.compute;
|
||||||
|
|
||||||
|
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||||
|
import org.jclouds.compute.OsFamilyVersion64Bit;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "cloudservers.CloudServersTemplateBuilderLiveTest")
|
||||||
|
public class CloudServersTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
|
|
||||||
|
public CloudServersTemplateBuilderLiveTest() {
|
||||||
|
provider = "cloudservers";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||||
|
return new Predicate<OsFamilyVersion64Bit>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(OsFamilyVersion64Bit input) {
|
||||||
|
return (input.family != OsFamily.WINDOWS && !input.is64Bit) || //
|
||||||
|
input.family == OsFamily.RHEL || //
|
||||||
|
(input.family == OsFamily.UBUNTU && input.version.equals("11.04")) || //
|
||||||
|
(input.family == OsFamily.CENTOS && input.version.matches("5.[23]")) || //
|
||||||
|
(input.family == OsFamily.WINDOWS && input.version.equals("2008")) || //
|
||||||
|
(input.family == OsFamily.WINDOWS && input.version.equals("2008 R2") && !input.is64Bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,14 +23,20 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.ImageBuilder;
|
import org.jclouds.compute.domain.ImageBuilder;
|
||||||
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
import org.jclouds.compute.domain.OperatingSystemBuilder;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.domain.Credentials;
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.json.Json;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.rackspace.cloudservers.functions.ParseImageFromJsonResponseTest;
|
import org.jclouds.rackspace.cloudservers.functions.ParseImageFromJsonResponseTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
|
@ -52,7 +58,9 @@ public class CloudServersImageToImageTest {
|
||||||
public static Image convertImage() {
|
public static Image convertImage() {
|
||||||
org.jclouds.rackspace.cloudservers.domain.Image image = ParseImageFromJsonResponseTest.parseImage();
|
org.jclouds.rackspace.cloudservers.domain.Image image = ParseImageFromJsonResponseTest.parseImage();
|
||||||
|
|
||||||
CloudServersImageToImage parser = new CloudServersImageToImage(new CloudServersImageToOperatingSystem());
|
CloudServersImageToImage parser = new CloudServersImageToImage(new CloudServersImageToOperatingSystem(new BaseComputeServiceContextModule() {
|
||||||
|
}.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule())
|
||||||
|
.getInstance(Json.class))));
|
||||||
|
|
||||||
return parser.apply(image);
|
return parser.apply(image);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,129 +1,129 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
|
||||||
====================================================================
|
====================================================================
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
====================================================================
|
====================================================================
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.jclouds</groupId>
|
<groupId>org.jclouds</groupId>
|
||||||
<artifactId>jclouds-project</artifactId>
|
<artifactId>jclouds-project</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<relativePath>../project/pom.xml</relativePath>
|
<relativePath>../project/pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>jclouds-rimuhosting</artifactId>
|
<artifactId>jclouds-rimuhosting</artifactId>
|
||||||
<name>jclouds RimuHosting core</name>
|
<name>jclouds RimuHosting core</name>
|
||||||
<description>jclouds components to access RimuHosting</description>
|
<description>jclouds components to access RimuHosting</description>
|
||||||
|
|
||||||
<scm>
|
<scm>
|
||||||
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/rimuhosting</connection>
|
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/rimuhosting</connection>
|
||||||
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/rimuhosting</developerConnection>
|
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/rimuhosting</developerConnection>
|
||||||
<url>http://jclouds.googlecode.com/svn/trunk/rimuhosting</url>
|
<url>http://jclouds.googlecode.com/svn/trunk/rimuhosting</url>
|
||||||
</scm>
|
</scm>
|
||||||
<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.rimuhosting.endpoint>https://rimuhosting.com/r</test.rimuhosting.endpoint>
|
<test.rimuhosting.endpoint>https://api.rimuhosting.com/r</test.rimuhosting.endpoint>
|
||||||
<test.rimuhosting.apiversion>1.0</test.rimuhosting.apiversion>
|
<test.rimuhosting.apiversion>1.0</test.rimuhosting.apiversion>
|
||||||
<test.rimuhosting.identity>FIXME</test.rimuhosting.identity>
|
<test.rimuhosting.identity>FIXME</test.rimuhosting.identity>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-jsch</artifactId>
|
<artifactId>jclouds-jsch</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-core</artifactId>
|
<artifactId>jclouds-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-compute</artifactId>
|
<artifactId>jclouds-compute</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-compute</artifactId>
|
<artifactId>jclouds-compute</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>log4j</groupId>
|
<groupId>log4j</groupId>
|
||||||
<artifactId>log4j</artifactId>
|
<artifactId>log4j</artifactId>
|
||||||
<version>1.2.14</version>
|
<version>1.2.14</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>${project.groupId}</groupId>
|
<groupId>${project.groupId}</groupId>
|
||||||
<artifactId>jclouds-log4j</artifactId>
|
<artifactId>jclouds-log4j</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
<id>live</id>
|
<id>live</id>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<id>integration</id>
|
<id>integration</id>
|
||||||
<phase>integration-test</phase>
|
<phase>integration-test</phase>
|
||||||
<goals>
|
<goals>
|
||||||
<goal>test</goal>
|
<goal>test</goal>
|
||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<systemProperties>
|
<systemProperties>
|
||||||
<property>
|
<property>
|
||||||
<name>test.rimuhosting.endpoint</name>
|
<name>test.rimuhosting.endpoint</name>
|
||||||
<value>${test.rimuhosting.endpoint}</value>
|
<value>${test.rimuhosting.endpoint}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>test.rimuhosting.apiversion</name>
|
<name>test.rimuhosting.apiversion</name>
|
||||||
<value>${test.rimuhosting.apiversion}</value>
|
<value>${test.rimuhosting.apiversion}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>test.rimuhosting.identity</name>
|
<name>test.rimuhosting.identity</name>
|
||||||
<value>${test.rimuhosting.identity}</value>
|
<value>${test.rimuhosting.identity}</value>
|
||||||
</property>
|
</property>
|
||||||
<property>
|
<property>
|
||||||
<name>jclouds.compute.blacklist.nodes</name>
|
<name>jclouds.compute.blacklist-nodes</name>
|
||||||
<value>${jclouds.compute.blacklist.nodes}</value>
|
<value>${jclouds.compute.blacklist-nodes}</value>
|
||||||
</property>
|
</property>
|
||||||
</systemProperties>
|
</systemProperties>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
|
@ -39,6 +39,7 @@ import org.jclouds.rest.annotations.MatrixParams;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.annotations.Unwrap;
|
import org.jclouds.rest.annotations.Unwrap;
|
||||||
|
import org.jclouds.rest.annotations.VirtualHost;
|
||||||
import org.jclouds.rimuhosting.miro.binder.CreateServerOptions;
|
import org.jclouds.rimuhosting.miro.binder.CreateServerOptions;
|
||||||
import org.jclouds.rimuhosting.miro.binder.RimuHostingRebootJsonBinder;
|
import org.jclouds.rimuhosting.miro.binder.RimuHostingRebootJsonBinder;
|
||||||
import org.jclouds.rimuhosting.miro.domain.Image;
|
import org.jclouds.rimuhosting.miro.domain.Image;
|
||||||
|
@ -66,6 +67,7 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||||
* @see <a href="http://apidocs.rimuhosting.com" />
|
* @see <a href="http://apidocs.rimuhosting.com" />
|
||||||
*/
|
*/
|
||||||
@RequestFilters(RimuHostingAuthentication.class)
|
@RequestFilters(RimuHostingAuthentication.class)
|
||||||
|
@VirtualHost
|
||||||
public interface RimuHostingAsyncClient {
|
public interface RimuHostingAsyncClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -74,7 +76,6 @@ public interface RimuHostingAsyncClient {
|
||||||
@GET
|
@GET
|
||||||
@Path("/distributions")
|
@Path("/distributions")
|
||||||
@ResponseParser(ParseImagesFromJsonResponse.class)
|
@ResponseParser(ParseImagesFromJsonResponse.class)
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@ExceptionParser(ParseRimuHostingException.class)
|
@ExceptionParser(ParseRimuHostingException.class)
|
||||||
ListenableFuture<Set<Image>> getImageList();
|
ListenableFuture<Set<Image>> getImageList();
|
||||||
|
@ -86,7 +87,6 @@ public interface RimuHostingAsyncClient {
|
||||||
@Path("/orders")
|
@Path("/orders")
|
||||||
@ResponseParser(ParseServersFromJsonResponse.class)
|
@ResponseParser(ParseServersFromJsonResponse.class)
|
||||||
@MatrixParams(keys = "include_inactive", values = "N")
|
@MatrixParams(keys = "include_inactive", values = "N")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@ExceptionParser(ParseRimuHostingException.class)
|
@ExceptionParser(ParseRimuHostingException.class)
|
||||||
ListenableFuture<Set<Server>> getServerList();
|
ListenableFuture<Set<Server>> getServerList();
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class RimuHostingPropertiesBuilder extends PropertiesBuilder {
|
||||||
protected Properties defaultProperties() {
|
protected Properties defaultProperties() {
|
||||||
Properties properties = super.defaultProperties();
|
Properties properties = super.defaultProperties();
|
||||||
properties.setProperty(PROPERTY_API_VERSION, "TODO");
|
properties.setProperty(PROPERTY_API_VERSION, "TODO");
|
||||||
properties.setProperty(PROPERTY_ENDPOINT, "https://rimuhosting.com/r");
|
properties.setProperty(PROPERTY_ENDPOINT, "https://api.rimuhosting.com/r");
|
||||||
properties.setProperty(PROPERTY_RIMUHOSTING_DEFAULT_DC, "DCDALLAS");
|
properties.setProperty(PROPERTY_RIMUHOSTING_DEFAULT_DC, "DCDALLAS");
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,6 @@
|
||||||
|
|
||||||
package org.jclouds.rimuhosting.miro.compute.config;
|
package org.jclouds.rimuhosting.miro.compute.config;
|
||||||
|
|
||||||
import static org.jclouds.compute.domain.OsFamily.UBUNTU;
|
|
||||||
|
|
||||||
|
|
||||||
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
import org.jclouds.compute.config.BaseComputeServiceContextModule;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
|
|
||||||
|
@ -45,7 +42,7 @@ public class RimuHostingComputeServiceContextModule extends BaseComputeServiceCo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) {
|
||||||
return template.hardwareId("MIRO1B").osFamily(UBUNTU).os64Bit(false).osVersionMatches("9.10");
|
return super.provideTemplate(injector, template).hardwareId("MIRO4B");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,8 +64,8 @@ public class ParseRimuHostingException implements Function<Exception, Object> {
|
||||||
RimuHostingResponse firstResponse = Iterables.get(responseMap.values(), 0);
|
RimuHostingResponse firstResponse = Iterables.get(responseMap.values(), 0);
|
||||||
String errorClass = firstResponse.getErrorInfo().getErrorClass();
|
String errorClass = firstResponse.getErrorInfo().getErrorClass();
|
||||||
if (errorClass.equals("PermissionException"))
|
if (errorClass.equals("PermissionException"))
|
||||||
throw new AuthorizationException(responseException.getCommand().getRequest(),
|
throw new AuthorizationException(
|
||||||
firstResponse.getErrorInfo().getErrorMessage());
|
firstResponse.getErrorInfo().getErrorMessage(), responseException);
|
||||||
throw new RuntimeException(firstResponse.getErrorInfo().getErrorMessage(), e);
|
throw new RuntimeException(firstResponse.getErrorInfo().getErrorMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,13 +51,13 @@ public class RimuHostingAsyncClientTest extends RestClientTest<RimuHostingAsyncC
|
||||||
Method method = RimuHostingAsyncClient.class.getMethod("createServer", String.class, String.class, String.class,
|
Method method = RimuHostingAsyncClient.class.getMethod("createServer", String.class, String.class, String.class,
|
||||||
CreateServerOptions[].class);
|
CreateServerOptions[].class);
|
||||||
GeneratedHttpRequest<RimuHostingAsyncClient> httpRequest = processor.createRequest(method, "test.ivan.api.com",
|
GeneratedHttpRequest<RimuHostingAsyncClient> httpRequest = processor.createRequest(method, "test.ivan.api.com",
|
||||||
"lenny", "MIRO1B");
|
"lenny", "MIRO4B");
|
||||||
|
|
||||||
assertRequestLineEquals(httpRequest, "POST https://rimuhosting.com/r/orders/new-vps HTTP/1.1");
|
assertRequestLineEquals(httpRequest, "POST https://api.rimuhosting.com/r/orders/new-vps HTTP/1.1");
|
||||||
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n");
|
assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\nHost: api.rimuhosting.com\n");
|
||||||
assertPayloadEquals(
|
assertPayloadEquals(
|
||||||
httpRequest,
|
httpRequest,
|
||||||
"{\"request\":{\"instantiation_options\":{\"distro\":\"lenny\",\"domain_name\":\"test.ivan.api.com\"},\"pricing_plan_code\":\"MIRO1B\",\"meta_data\":[]}}",
|
"{\"request\":{\"instantiation_options\":{\"distro\":\"lenny\",\"domain_name\":\"test.ivan.api.com\"},\"pricing_plan_code\":\"MIRO4B\",\"meta_data\":[]}}",
|
||||||
"application/json", false);
|
"application/json", false);
|
||||||
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyJsonValue.class);
|
assertResponseParserClassEquals(method, httpRequest, UnwrapOnlyJsonValue.class);
|
||||||
assertSaxResponseParserClassEquals(method, null);
|
assertSaxResponseParserClassEquals(method, null);
|
||||||
|
|
|
@ -115,7 +115,7 @@ public class RimuHostingClientLiveTest {
|
||||||
@Test
|
@Test
|
||||||
public void testLifeCycle() {
|
public void testLifeCycle() {
|
||||||
// Get the first image, we dont really care what it is in this test.
|
// Get the first image, we dont really care what it is in this test.
|
||||||
NewServerResponse serverResponse = connection.createServer("test.ivan.api.com", "lenny", "MIRO1B");
|
NewServerResponse serverResponse = connection.createServer("test.ivan.api.com", "lenny", "MIRO4B");
|
||||||
Server server = serverResponse.getServer();
|
Server server = serverResponse.getServer();
|
||||||
// Now we have the server, lets restart it
|
// Now we have the server, lets restart it
|
||||||
assertNotNull(server.getId());
|
assertNotNull(server.getId());
|
||||||
|
|
|
@ -48,10 +48,10 @@ public class RimuHostingComputeServiceLiveTest extends BaseComputeServiceLiveTes
|
||||||
public void testTemplateBuilder() {
|
public void testTemplateBuilder() {
|
||||||
Template defaultTemplate = client.templateBuilder().build();
|
Template defaultTemplate = client.templateBuilder().build();
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), false);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), false);
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "9.10");
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04");
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
assertEquals(defaultTemplate.getLocation().getId(), "DCDALLAS");
|
assertEquals(defaultTemplate.getLocation().getId(), "DCDALLAS");
|
||||||
assertEquals(defaultTemplate.getHardware().getProviderId(), "MIRO1B");
|
assertEquals(defaultTemplate.getHardware().getProviderId(), "MIRO4B");
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,4 +60,4 @@ public class RimuHostingComputeServiceLiveTest extends BaseComputeServiceLiveTes
|
||||||
return new JschSshClientModule();
|
return new JschSshClientModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.rimuhosting.miro.compute;
|
||||||
|
|
||||||
|
import org.jclouds.compute.BaseTemplateBuilderLiveTest;
|
||||||
|
import org.jclouds.compute.OsFamilyVersion64Bit;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", testName = "rimuhosting.RimuHostingTemplateBuilderLiveTest")
|
||||||
|
public class RimuHostingTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
|
|
||||||
|
public RimuHostingTemplateBuilderLiveTest() {
|
||||||
|
provider = "rimuhosting";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Predicate<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
|
||||||
|
return new Predicate<OsFamilyVersion64Bit>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(OsFamilyVersion64Bit input) {
|
||||||
|
return input.family != OsFamily.UBUNTU || //
|
||||||
|
Float.parseFloat(input.version) > 10.04 || //
|
||||||
|
(!(input.is64Bit) && Float.parseFloat(input.version) < 8.10);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,139 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright (C) 2010 Cloud Conscious, LLC <info@cloudconscious.com>
|
||||||
|
|
||||||
|
====================================================================
|
||||||
|
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.html
|
||||||
|
|
||||||
|
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.
|
||||||
|
====================================================================
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-project</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<relativePath>../project/pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.jclouds</groupId>
|
||||||
|
<artifactId>jclouds-elastichosts</artifactId>
|
||||||
|
<name>jclouds ElasticHosts core</name>
|
||||||
|
<description>jclouds components to access ElasticHosts</description>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>scm:svn:http://jclouds.googlecode.com/svn/trunk/elastichosts</connection>
|
||||||
|
<developerConnection>scm:svn:https://jclouds.googlecode.com/svn/trunk/elastichosts</developerConnection>
|
||||||
|
<url>http://jclouds.googlecode.com/svn/trunk/elastichosts</url>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<!-- bootstrapping: need to fetch the project POM -->
|
||||||
|
<repositories>
|
||||||
|
<repository>
|
||||||
|
<id>jclouds-googlecode-deploy</id>
|
||||||
|
<url>http://jclouds.googlecode.com/svn/repo</url>
|
||||||
|
</repository>
|
||||||
|
<repository>
|
||||||
|
<id>jclouds-rimu-snapshots-nexus</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
<snapshots>
|
||||||
|
<enabled>true</enabled>
|
||||||
|
</snapshots>
|
||||||
|
</repository>
|
||||||
|
</repositories>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- when instances are hung, open a ticket and add here -->
|
||||||
|
<jclouds.compute.blacklist-nodes>trmkrun-ccc,test.trmk-924</jclouds.compute.blacklist-nodes>
|
||||||
|
<test.elastichosts.endpoint>https://api.cloudsigma.com</test.elastichosts.endpoint>
|
||||||
|
<test.elastichosts.apiversion>1.0</test.elastichosts.apiversion>
|
||||||
|
<test.elastichosts.identity>FIXME</test.elastichosts.identity>
|
||||||
|
<test.elastichosts.credential>FIXME</test.elastichosts.credential>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>1.2.14</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>jclouds-log4j</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>live</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>integration</id>
|
||||||
|
<phase>integration-test</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<systemProperties>
|
||||||
|
<property>
|
||||||
|
<name>test.elastichosts.endpoint</name>
|
||||||
|
<value>${test.elastichosts.endpoint}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.elastichosts.apiversion</name>
|
||||||
|
<value>${test.elastichosts.apiversion}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.elastichosts.identity</name>
|
||||||
|
<value>${test.elastichosts.identity}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>test.elastichosts.credential</name>
|
||||||
|
<value>${test.elastichosts.credential}</value>
|
||||||
|
</property>
|
||||||
|
<property>
|
||||||
|
<name>jclouds.compute.blacklist-nodes</name>
|
||||||
|
<value>${jclouds.compute.blacklist-nodes}</value>
|
||||||
|
</property>
|
||||||
|
</systemProperties>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
|
@ -0,0 +1,199 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* 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.elastichosts;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
import org.jclouds.elastichosts.binders.BindCreateDriveRequestToPlainTextString;
|
||||||
|
import org.jclouds.elastichosts.binders.BindDriveDataToPlainTextString;
|
||||||
|
import org.jclouds.elastichosts.binders.BindReadDriveOptionsToPath;
|
||||||
|
import org.jclouds.elastichosts.domain.CreateDriveRequest;
|
||||||
|
import org.jclouds.elastichosts.domain.DriveData;
|
||||||
|
import org.jclouds.elastichosts.domain.DriveInfo;
|
||||||
|
import org.jclouds.elastichosts.domain.ImageConversionType;
|
||||||
|
import org.jclouds.elastichosts.functions.KeyValuesDelimitedByBlankLinesToDriveInfo;
|
||||||
|
import org.jclouds.elastichosts.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet;
|
||||||
|
import org.jclouds.elastichosts.functions.ReturnPayload;
|
||||||
|
import org.jclouds.elastichosts.functions.SplitNewlines;
|
||||||
|
import org.jclouds.elastichosts.options.ReadDriveOptions;
|
||||||
|
import org.jclouds.http.filters.BasicAuthentication;
|
||||||
|
import org.jclouds.io.Payload;
|
||||||
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to ElasticHosts via their REST API.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see ElasticHostsClient
|
||||||
|
* @see <a href="TODO: insert URL of provider documentation" />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@RequestFilters(BasicAuthentication.class)
|
||||||
|
@Consumes(MediaType.TEXT_PLAIN)
|
||||||
|
public interface ElasticHostsAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#listDrives()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/drives/list")
|
||||||
|
@ResponseParser(SplitNewlines.class)
|
||||||
|
ListenableFuture<Set<String>> listDrives();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#listStandardDrives()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/drives/standard/list")
|
||||||
|
@ResponseParser(SplitNewlines.class)
|
||||||
|
ListenableFuture<Set<String>> listStandardDrives();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#listStandardCds()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/drives/standard/cd/list")
|
||||||
|
@ResponseParser(SplitNewlines.class)
|
||||||
|
ListenableFuture<Set<String>> listStandardCds();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#listStandardImages()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/drives/standard/img/list")
|
||||||
|
@ResponseParser(SplitNewlines.class)
|
||||||
|
ListenableFuture<Set<String>> listStandardImages();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#listDriveInfo()
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/drives/info")
|
||||||
|
@ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet.class)
|
||||||
|
ListenableFuture<Set<DriveInfo>> listDriveInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#getDriveInfo
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||||
|
@Path("/drives/{uuid}/info")
|
||||||
|
ListenableFuture<DriveInfo> getDriveInfo(@PathParam("uuid") String uuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#createDrive
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||||
|
@Path("/drives/create")
|
||||||
|
ListenableFuture<DriveInfo> createDrive(
|
||||||
|
@BinderParam(BindCreateDriveRequestToPlainTextString.class) CreateDriveRequest createDrive);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#setDriveData
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
@ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class)
|
||||||
|
@Path("/drives/{uuid}/set")
|
||||||
|
ListenableFuture<DriveInfo> setDriveData(@PathParam("uuid") String uuid,
|
||||||
|
@BinderParam(BindDriveDataToPlainTextString.class) DriveData createDrive);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#destroyDrive
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/drives/{uuid}/destroy")
|
||||||
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Void> destroyDrive(@PathParam("uuid") String uuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#imageDrive(String,String)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/drives/{destination}/image/{source}")
|
||||||
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Void> imageDrive(@PathParam("source") String source, @PathParam("destination") String destination);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#imageDrive(String,String,ImageConversionType)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/drives/{destination}/image/{source}/{conversion}")
|
||||||
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Void> imageDrive(@PathParam("source") String source, @PathParam("destination") String destination,
|
||||||
|
@PathParam("conversion") ImageConversionType conversionType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#readDrive(String)
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
@Path("/drives/{uuid}/read")
|
||||||
|
@ResponseParser(ReturnPayload.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Payload> readDrive(@PathParam("uuid") String uuid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#readDrive(String,ReadDriveOptions)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
@Path("/drives/{uuid}/read")
|
||||||
|
@ResponseParser(ReturnPayload.class)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Payload> readDrive(@PathParam("uuid") String uuid,
|
||||||
|
@BinderParam(BindReadDriveOptionsToPath.class) ReadDriveOptions options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#writeDrive(String, Payload)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
@Path("/drives/{uuid}/write")
|
||||||
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Void> writeDrive(@PathParam("uuid") String uuid, Payload content);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticHostsClient#writeDrive(String, Payload, long)
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Produces(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
|
@Path("/drives/{uuid}/write/{offset}")
|
||||||
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Void> writeDrive(@PathParam("uuid") String uuid, Payload content, @PathParam("offset") long offset);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue