Merge branch 'master' of github.com:jclouds/jclouds

This commit is contained in:
Lili Nader 2010-11-22 12:44:15 -08:00
commit 8b716a06d8
212 changed files with 11360 additions and 3565 deletions

View File

@ -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

View File

@ -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>

View File

@ -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);

View File

@ -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

View File

@ -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;
}
} }

View File

@ -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);

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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;
} }
} }

View File

@ -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

View File

@ -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;

View File

@ -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;
} }
} }

View File

@ -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;
} }

View File

@ -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 + "]"));
} }
} }

View File

@ -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);

View File

@ -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)));
} }
} }

View File

@ -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());

View File

@ -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))

View File

@ -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");

View File

@ -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)) {

View File

@ -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();
} }
} }

View File

@ -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);
} }
} }

View File

@ -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()));

View File

@ -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);
}
} }

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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

View File

@ -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());

View File

@ -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() {

View File

@ -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);

View File

@ -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;

View File

@ -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>

View File

@ -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" />

View File

@ -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);

View File

@ -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();

View File

@ -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

View File

@ -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;
} }

View File

@ -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();
} }

View File

@ -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);
} }
/** /**

View File

@ -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());

View File

@ -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;

View File

@ -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

View File

@ -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;
}
}
} }

View File

@ -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;
} }

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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();

View File

@ -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";
}
}

View File

@ -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();
}
}
}

View File

@ -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 &lt; &gt; 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);
}
}
}
}

View File

@ -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;
} }

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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;
} }
} }
} }

View File

@ -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;

View File

@ -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;

View File

@ -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);
} }

View File

@ -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);

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
} }
} }

View File

@ -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);
} }

View File

@ -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>

View File

@ -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;
} }
} }

View File

@ -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();

View File

@ -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);
} }

View File

@ -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"));
} }
} }

View File

@ -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";
} }

View File

@ -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);

View File

@ -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;
} }

View File

@ -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;
}
} }

View File

@ -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>

View File

@ -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);
} }
} }

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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")) {

View File

@ -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.*");
}
} }

View File

@ -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;
} }
} }

View File

@ -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")) {

View File

@ -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();
}
} }

View File

@ -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);
}
};
}
}

View File

@ -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);
} }

View File

@ -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>

View File

@ -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();

View File

@ -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;
} }

View File

@ -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");
} }
} }

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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());

View File

@ -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();
} }
} }

View File

@ -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);
}
};
}
}

View File

@ -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>

View File

@ -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