diff --git a/README.txt b/README.txt index 305e4514d0..31b58f721a 100644 --- a/README.txt +++ b/README.txt @@ -26,32 +26,30 @@ 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-8 +our current version is 1.0-beta-9a our dev version is 1.0-SNAPSHOT -our compute api supports: aws-ec2, gogrid, cloudservers (generic), cloudservers-us, - cloudservers-uk, vcloud (generic), ec2 (generic), +our compute api supports: aws-ec2, gogrid, cloudservers-us, stub (in-memory), + cloudservers-uk, vcloud (generic), ec2 (generic), byon, trmk-ecloud, trmk-vcloudexpress, eucalyptus (generic), cloudsigma-zrh, elasticstack(generic), bluelock-vclouddirector, slicehost, eucalyptus-partnercloud-ec2, elastichosts-lon-p (Peer 1), elastichosts-sat-p (Peer 1), elastichosts-lon-b (BlueSquare), - openhosting-east1, serverlove-z1-man, skalicloud-sdg-my, - vcloudexpress (generic), stub (in-memory) + openhosting-east1, serverlove-z1-man, skalicloud-sdg-my * note * the pom dependency org.jclouds/jclouds-allcompute gives you access to to all of these providers -our blobstore api supports: aws-s3, cloudfiles (generic), cloudfiles-us, cloudfiles-uk, - azureblob, atmos (generic), synaptic-storage, - cloudonestorage, s3 (generic), walrus(generic), googlestorage, - eucalyptus-partnercloud-s3, swift (generic), transient (in-mem), - filesystem (on-disk) +our blobstore api supports: aws-s3, cloudfiles-us, cloudfiles-uk, filesystem, + azureblob, atmos (generic), synaptic-storage, scaleup-storage, + cloudonestorage, walrus(generic), googlestorage, + eucalyptus-partnercloud-s3, swift (generic), transient (in-mem) * note * the pom dependency org.jclouds/jclouds-allblobstore gives you access to to all of these providers we also have support for: ibmdev, mezeo, nirvanix, boxdotnet, rimuhosting, openstack nova, - azurequeue, simpledb, scaleup-storage as well as a async-http-client + azurequeue, simpledb, cloudstack as well as a async-http-client driver in the sandbox @@ -61,7 +59,7 @@ If you want access to all jclouds components, include the maven dependency org.j BlobStore Example (Java): // init context = new BlobStoreContextFactory().createContext( - "s3", + "aws-s3", accesskeyid, secretaccesskey); blobStore = context.getBlobStore(); @@ -84,7 +82,7 @@ BlobStore Example (Clojure): Compute Example (Java): // init context = new ComputeServiceContextFactory().createContext( - "ec2", + "aws-ec2", accesskeyid, secretaccesskey, ImmutableSet.of(new Log4JLoggingModule(), @@ -95,28 +93,28 @@ Compute Example (Java): template = client.templateBuilder().osFamily(UBUNTU).smallest().build(); // these nodes will be accessible via ssh when the call returns - nodes = client.runNodesWithTag("mycluster", 2, template); + nodes = client.createNodesInGroup("mycluster", 2, template); Compute Example (Clojure): (use 'org.jclouds.compute) ; create a compute service using ssh and log4j extensions (def compute - (compute-service "terremark" "user" "password" :ssh :log4j)) + (compute-service "trmk`-ecloud" "user" "password" :ssh :log4j)) ; use the default node template and launch a couple nodes ; these will have your ~/.ssh/id_rsa.pub authorized when complete (with-compute-service [compute] - (run-nodes "mycluster" 2)) + (create-nodes "mycluster" 2)) Downloads: - * distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-8.zip + * distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-9a.zip * maven repo: http://repo2.maven.org/maven2 (maven central - the default repository) * snapshot repo: https://oss.sonatype.org/content/repositories/snapshots Links: * project page: http://code.google.com/p/jclouds/ - * javadocs (1.0-beta-8): http://jclouds.rimuhosting.com/apidocs/ + * javadocs (1.0-beta-9a): http://jclouds.rimuhosting.com/apidocs/ * javadocs (1.0-SNAPSHOT): http://jclouds.rimuhosting.com/apidocs-SNAPSHOT/ * community: http://code.google.com/p/jclouds/wiki/AppsThatUseJClouds * user group: http://groups.google.com/group/jclouds diff --git a/all/pom.xml b/all/pom.xml index 4b2172267d..51f0aab3ea 100644 --- a/all/pom.xml +++ b/all/pom.xml @@ -39,10 +39,5 @@ jclouds-allblobstore ${project.version} - - org.jclouds.provider - aws-elb - ${project.version} - diff --git a/allblobstore/pom.xml b/allblobstore/pom.xml index 704d223ee3..3ff8086a9b 100644 --- a/allblobstore/pom.xml +++ b/allblobstore/pom.xml @@ -44,6 +44,11 @@ googlestorage ${project.version} + + org.jclouds.provider + scaleup-storage + ${project.version} + org.jclouds.provider synaptic-storage diff --git a/allcompute/pom.xml b/allcompute/pom.xml index c66adca6ca..9e145f8790 100644 --- a/allcompute/pom.xml +++ b/allcompute/pom.xml @@ -39,6 +39,11 @@ aws-ec2 ${project.version} + + org.jclouds.api + byon + ${project.version} + org.jclouds.api ec2 diff --git a/antcontrib/pom.xml b/antcontrib/pom.xml index 318d2cf12d..7dd7471a6e 100644 --- a/antcontrib/pom.xml +++ b/antcontrib/pom.xml @@ -63,7 +63,7 @@ com.jcraft jsch - 0.1.42 + 0.1.44 diff --git a/antcontrib/samples/cargooverssh/build.properties.bluelock-vclouddirector b/antcontrib/samples/cargooverssh/build.properties.bluelock-vclouddirector deleted file mode 100644 index 097c905ee2..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.bluelock-vclouddirector +++ /dev/null @@ -1,5 +0,0 @@ -provider=bluelock-vcloudirector -driver=bluelock -identity=user@your_org -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/cargooverssh/build.properties.ec2 b/antcontrib/samples/cargooverssh/build.properties.ec2 deleted file mode 100644 index 80d6a63cba..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.ec2 +++ /dev/null @@ -1,5 +0,0 @@ -provider=ec2 -driver=aws -identity=accesscredentialid -credential=secretaccesscredential -tag=we_create_and_delete_based_on_credential_and_security_group_name_not_instance_id diff --git a/antcontrib/samples/cargooverssh/build.properties.eucalyptus b/antcontrib/samples/cargooverssh/build.properties.eucalyptus deleted file mode 100644 index 0d7950a850..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.eucalyptus +++ /dev/null @@ -1,7 +0,0 @@ -provider=eucalyptus -driver=aws -# note you need to change this to the correct endpoint -eucalyptus.endpoint=http://173.205.188.130:8773/services/Eucalyptus -identity=accesskey -credential=secret -tag=name_of_your_cluster_or_instance diff --git a/antcontrib/samples/cargooverssh/build.properties.gogrid b/antcontrib/samples/cargooverssh/build.properties.gogrid deleted file mode 100644 index 240ed0f4fc..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.gogrid +++ /dev/null @@ -1,5 +0,0 @@ -provider=gogrid -driver=gogrid -identity=apikey -credential=secret -tag=name_of_your_server diff --git a/antcontrib/samples/cargooverssh/build.properties.rackspacecloudservers b/antcontrib/samples/cargooverssh/build.properties.rackspacecloudservers deleted file mode 100644 index 37848da0b4..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.rackspacecloudservers +++ /dev/null @@ -1,5 +0,0 @@ -provider=cloudservers -driver=rackspace -identity=user -credential=your_credential -tag=name_of_your_server diff --git a/antcontrib/samples/cargooverssh/build.properties.rimuhosting b/antcontrib/samples/cargooverssh/build.properties.rimuhosting deleted file mode 100644 index c76f9e0322..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.rimuhosting +++ /dev/null @@ -1,5 +0,0 @@ -provider=rimuhosting -driver=rimuhosting -identity=apicredential -credential=apicredential -tag=name_of_your_server diff --git a/antcontrib/samples/cargooverssh/build.properties.trmk-ecloud b/antcontrib/samples/cargooverssh/build.properties.trmk-ecloud deleted file mode 100644 index f122fa79c4..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.trmk-ecloud +++ /dev/null @@ -1,5 +0,0 @@ -provider=trmk-ecloud -driver=terremark -identity=user@youregistered.com -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/cargooverssh/build.properties.trmk-vcloudexpress b/antcontrib/samples/cargooverssh/build.properties.trmk-vcloudexpress deleted file mode 100644 index b3a67a75d1..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.trmk-vcloudexpress +++ /dev/null @@ -1,5 +0,0 @@ -provider=trmk-vcloudexpress -driver=terremark -identity=user@youregistered.com -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/cargooverssh/build.properties.vcloud b/antcontrib/samples/cargooverssh/build.properties.vcloud deleted file mode 100644 index 9d99604052..0000000000 --- a/antcontrib/samples/cargooverssh/build.properties.vcloud +++ /dev/null @@ -1,7 +0,0 @@ -provider=vcloud -driver=vcloud -# note you need to change this to the correct endpoint -vcloud.endpoint=https://vcloud_host_you_want/api -identity=user@your_org -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/cargooverssh/build.xml b/antcontrib/samples/cargooverssh/build.xml deleted file mode 100644 index 5a07095dc1..0000000000 --- a/antcontrib/samples/cargooverssh/build.xml +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/antcontrib/samples/cargooverssh/runscript.sh b/antcontrib/samples/cargooverssh/runscript.sh deleted file mode 100644 index 6c3f1505f6..0000000000 --- a/antcontrib/samples/cargooverssh/runscript.sh +++ /dev/null @@ -1,29 +0,0 @@ -# -# -# Copyright (C) 2010 Cloud Conscious, LLC. -# -# ==================================================================== -# 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. -# ==================================================================== -# - -echo nameserver 208.67.222.222 >> /etc/resolv.conf -apt-get update -qq -apt-get upgrade -y -qq -apt-get install -y -qq wget -apt-get install -y -qq openjdk-6-jdk -wget -q http://mirrors.axint.net/apache/tomcat/tomcat-6/v6.0.29/bin/apache-tomcat-6.0.29.tar.gz -tar xzf apache-tomcat-6.0.29.tar.gz -mkdir -p /tmp/cargo/containers -chmod 1777 /tmp/cargo -mv apache-tomcat-6.0.29 /tmp/cargo/containers/tomcat6x diff --git a/antcontrib/samples/compute/build.properties.bluelock-vclouddirector b/antcontrib/samples/compute/build.properties.bluelock-vclouddirector deleted file mode 100644 index 097c905ee2..0000000000 --- a/antcontrib/samples/compute/build.properties.bluelock-vclouddirector +++ /dev/null @@ -1,5 +0,0 @@ -provider=bluelock-vcloudirector -driver=bluelock -identity=user@your_org -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/compute/build.properties.ec2 b/antcontrib/samples/compute/build.properties.ec2 deleted file mode 100644 index 80d6a63cba..0000000000 --- a/antcontrib/samples/compute/build.properties.ec2 +++ /dev/null @@ -1,5 +0,0 @@ -provider=ec2 -driver=aws -identity=accesscredentialid -credential=secretaccesscredential -tag=we_create_and_delete_based_on_credential_and_security_group_name_not_instance_id diff --git a/antcontrib/samples/compute/build.properties.eucalyptus b/antcontrib/samples/compute/build.properties.eucalyptus deleted file mode 100644 index 0d7950a850..0000000000 --- a/antcontrib/samples/compute/build.properties.eucalyptus +++ /dev/null @@ -1,7 +0,0 @@ -provider=eucalyptus -driver=aws -# note you need to change this to the correct endpoint -eucalyptus.endpoint=http://173.205.188.130:8773/services/Eucalyptus -identity=accesskey -credential=secret -tag=name_of_your_cluster_or_instance diff --git a/antcontrib/samples/compute/build.properties.gogrid b/antcontrib/samples/compute/build.properties.gogrid deleted file mode 100644 index 240ed0f4fc..0000000000 --- a/antcontrib/samples/compute/build.properties.gogrid +++ /dev/null @@ -1,5 +0,0 @@ -provider=gogrid -driver=gogrid -identity=apikey -credential=secret -tag=name_of_your_server diff --git a/antcontrib/samples/compute/build.properties.rackspacecloudservers b/antcontrib/samples/compute/build.properties.rackspacecloudservers deleted file mode 100644 index 37848da0b4..0000000000 --- a/antcontrib/samples/compute/build.properties.rackspacecloudservers +++ /dev/null @@ -1,5 +0,0 @@ -provider=cloudservers -driver=rackspace -identity=user -credential=your_credential -tag=name_of_your_server diff --git a/antcontrib/samples/compute/build.properties.rimuhosting b/antcontrib/samples/compute/build.properties.rimuhosting deleted file mode 100644 index c76f9e0322..0000000000 --- a/antcontrib/samples/compute/build.properties.rimuhosting +++ /dev/null @@ -1,5 +0,0 @@ -provider=rimuhosting -driver=rimuhosting -identity=apicredential -credential=apicredential -tag=name_of_your_server diff --git a/antcontrib/samples/compute/build.properties.terremark b/antcontrib/samples/compute/build.properties.terremark deleted file mode 100644 index dc814ea2af..0000000000 --- a/antcontrib/samples/compute/build.properties.terremark +++ /dev/null @@ -1,5 +0,0 @@ -service=terremark -driver=terremark -account=user@youregistered.com -key=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/compute/build.properties.trmk-ecloud b/antcontrib/samples/compute/build.properties.trmk-ecloud deleted file mode 100644 index f122fa79c4..0000000000 --- a/antcontrib/samples/compute/build.properties.trmk-ecloud +++ /dev/null @@ -1,5 +0,0 @@ -provider=trmk-ecloud -driver=terremark -identity=user@youregistered.com -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/compute/build.properties.trmk-vcloudexpress b/antcontrib/samples/compute/build.properties.trmk-vcloudexpress deleted file mode 100644 index b3a67a75d1..0000000000 --- a/antcontrib/samples/compute/build.properties.trmk-vcloudexpress +++ /dev/null @@ -1,5 +0,0 @@ -provider=trmk-vcloudexpress -driver=terremark -identity=user@youregistered.com -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/compute/build.properties.vcloud b/antcontrib/samples/compute/build.properties.vcloud deleted file mode 100644 index 9d99604052..0000000000 --- a/antcontrib/samples/compute/build.properties.vcloud +++ /dev/null @@ -1,7 +0,0 @@ -provider=vcloud -driver=vcloud -# note you need to change this to the correct endpoint -vcloud.endpoint=https://vcloud_host_you_want/api -identity=user@your_org -credential=password -tag=name_of_your_vapp diff --git a/antcontrib/samples/compute/build.xml b/antcontrib/samples/compute/build.xml index 854e60fd53..4b03b93149 100644 --- a/antcontrib/samples/compute/build.xml +++ b/antcontrib/samples/compute/build.xml @@ -21,7 +21,7 @@ - + @@ -30,29 +30,21 @@ - - - - + - @@ -94,9 +86,9 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - \ No newline at end of file + diff --git a/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java b/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java index 072dc04401..8e59ed055a 100644 --- a/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java +++ b/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/ComputeTask.java @@ -189,19 +189,19 @@ public class ComputeTask extends Task { private void list(ComputeService computeService) { log("list"); for (ComputeMetadata node : computeService.listNodes()) { - log(String.format(" location=%s, id=%s, tag=%s", node.getLocation(), node.getProviderId(), node.getName())); + log(String.format(" location=%s, id=%s, group=%s", node.getLocation(), node.getProviderId(), node.getName())); } } private void create(ComputeService computeService) throws RunNodesException, IOException { - String tag = nodeElement.getTag(); + String group = nodeElement.getGroup(); - log(String.format("create tag: %s, count: %d, hardware: %s, os: %s", tag, nodeElement.getCount(), nodeElement + log(String.format("create group: %s, count: %d, hardware: %s, os: %s", group, nodeElement.getCount(), nodeElement .getHardware(), nodeElement.getOs())); Template template = createTemplateFromElement(nodeElement, computeService); - for (NodeMetadata createdNode : computeService.runNodesWithTag(tag, nodeElement.getCount(), template)) { + for (NodeMetadata createdNode : computeService.createNodesInGroup(group, nodeElement.getCount(), template)) { logDetails(computeService, createdNode); addNodeDetailsAsProjectProperties(createdNode); } @@ -223,8 +223,8 @@ public class ComputeTask extends Task { log(String.format("reboot id: %s", nodeElement.getId())); computeService.rebootNode(nodeElement.getId()); } else { - log(String.format("reboot tag: %s", nodeElement.getTag())); - computeService.rebootNodesMatching(NodePredicates.withTag(nodeElement.getTag())); + log(String.format("reboot group: %s", nodeElement.getGroup())); + computeService.rebootNodesMatching(NodePredicates.inGroup(nodeElement.getGroup())); } } @@ -233,8 +233,8 @@ public class ComputeTask extends Task { log(String.format("destroy id: %s", nodeElement.getId())); computeService.destroyNode(nodeElement.getId()); } else { - log(String.format("destroy tag: %s", nodeElement.getTag())); - computeService.destroyNodesMatching(NodePredicates.withTag(nodeElement.getTag())); + log(String.format("destroy group: %s", nodeElement.getGroup())); + computeService.destroyNodesMatching(NodePredicates.inGroup(nodeElement.getGroup())); } } @@ -243,9 +243,9 @@ public class ComputeTask extends Task { log(String.format("get id: %s", nodeElement.getId())); logDetails(computeService, computeService.getNodeMetadata(nodeElement.getId())); } else { - log(String.format("get tag: %s", nodeElement.getTag())); + log(String.format("get group: %s", nodeElement.getGroup())); for (ComputeMetadata node : Iterables.filter(computeService.listNodesDetailsMatching(NodePredicates.all()), - NodePredicates.withTag(nodeElement.getTag()))) { + NodePredicates.inGroup(nodeElement.getGroup()))) { logDetails(computeService, node); } } @@ -254,8 +254,8 @@ public class ComputeTask extends Task { private void logDetails(ComputeService computeService, ComputeMetadata node) { NodeMetadata metadata = node instanceof NodeMetadata ? NodeMetadata.class.cast(node) : computeService .getNodeMetadata(node.getId()); - log(String.format(" node id=%s, name=%s, tag=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, hardware=%s", - metadata.getProviderId(), metadata.getName(), metadata.getTag(), metadata.getLocation(), metadata + log(String.format(" node id=%s, name=%s, group=%s, location=%s, state=%s, publicIp=%s, privateIp=%s, hardware=%s", + metadata.getProviderId(), metadata.getName(), metadata.getGroup(), metadata.getLocation(), metadata .getState(), ComputeTaskUtils.ipOrEmptyString(metadata.getPublicAddresses()), ipOrEmptyString(metadata.getPrivateAddresses()), metadata.getHardware())); } diff --git a/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java b/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java index 70050c35a2..40049a974d 100644 --- a/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java +++ b/antcontrib/src/main/java/org/jclouds/tools/ant/taskdefs/compute/NodeElement.java @@ -27,7 +27,7 @@ import java.io.File; */ public class NodeElement { private String id; - private String tag; + private String group; private String hardware; private String os; private String image; @@ -147,12 +147,12 @@ public class NodeElement { return count; } - public void setTag(String tag) { - this.tag = tag; + public void setGroup(String group) { + this.group = group; } - public String getTag() { - return tag; + public String getGroup() { + return group; } public void setPrivatekeyfile(File privatekeyfile) { diff --git a/apis/atmos/README.txt b/apis/atmos/README.txt index d4792984b6..e871588a07 100644 --- a/apis/atmos/README.txt +++ b/apis/atmos/README.txt @@ -18,7 +18,7 @@ ==== # -# The jclouds provider for EMC's Atmos Online Storage (http://www.emccis.com/). +# The jclouds API for EMC's Atmos Online Storage (http://www.emccis.com/). # # TODO: Implementation status. # TODO: Supported features. diff --git a/apis/atmos/pom.xml b/apis/atmos/pom.xml index 48b43fed4c..1d905ff05b 100644 --- a/apis/atmos/pom.xml +++ b/apis/atmos/pom.xml @@ -61,7 +61,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java index a2482df1e2..11514e1977 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/config/AtmosBlobStoreContextModule.java @@ -19,10 +19,6 @@ package org.jclouds.atmos.blobstore.config; -import java.util.Set; - -import javax.inject.Singleton; - import org.jclouds.atmos.AtmosAsyncClient; import org.jclouds.atmos.AtmosClient; import org.jclouds.atmos.blobstore.AtmosAsyncBlobStore; @@ -37,17 +33,9 @@ import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.config.BlobStoreMapModule; import org.jclouds.blobstore.internal.BlobStoreContextImpl; import org.jclouds.blobstore.strategy.ContainsValueInListStrategy; -import org.jclouds.collect.Memoized; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.location.Provider; +import org.jclouds.location.config.JustProviderLocationModule; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; -import com.google.inject.Provides; import com.google.inject.Scopes; import com.google.inject.TypeLiteral; @@ -64,24 +52,10 @@ public class AtmosBlobStoreContextModule extends AbstractModule { bind(ConsistencyModel.class).toInstance(ConsistencyModel.EVENTUAL); bind(AsyncBlobStore.class).to(AtmosAsyncBlobStore.class).in(Scopes.SINGLETON); bind(BlobStore.class).to(AtmosBlobStore.class).in(Scopes.SINGLETON); - bind(BlobStoreContext.class).to( - new TypeLiteral>() { - }).in(Scopes.SINGLETON); + bind(BlobStoreContext.class).to(new TypeLiteral>() { + }).in(Scopes.SINGLETON); bind(ContainsValueInListStrategy.class).to(FindMD5InUserMetadata.class); bind(BlobRequestSigner.class).to(AtmosBlobRequestSigner.class); - } - - @Provides - @Singleton - @Memoized - Supplier> provideLocations(Supplier defaultLocation) { - return Suppliers.> ofInstance(ImmutableSet.of(defaultLocation.get())); - } - - @Provides - @Singleton - Supplier provideDefaultLocation(@Provider String providerName) { - return Suppliers - . ofInstance(new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null)); + install(new JustProviderLocationModule()); } } diff --git a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/functions/ObjectToBlob.java b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/functions/ObjectToBlob.java index 4b5d96b628..93327c5477 100644 --- a/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/functions/ObjectToBlob.java +++ b/apis/atmos/src/main/java/org/jclouds/atmos/blobstore/functions/ObjectToBlob.java @@ -36,7 +36,7 @@ import com.google.common.base.Function; */ @Singleton public class ObjectToBlob implements Function { - private final Blob.Factory blobFactory; + private final Factory blobFactory; private final ObjectToBlobMetadata object2BlobMd; @Inject diff --git a/apis/byon/README.txt b/apis/byon/README.txt new file mode 100644 index 0000000000..1efc0b5f06 --- /dev/null +++ b/apis/byon/README.txt @@ -0,0 +1,94 @@ += Bring Your Own Nodes to the jclouds ComputeService = +The bring your own node provider (byon) allows you to specify a source which jclouds will read +nodes from. Using this, you can have jclouds control your standalone machines, or even cloud +hosts that are sitting idle. + +== Constraints == +The byon provider only supports the following functions of ComputeService: + * listNodes + * listNodesDetailsMatching + * getNodeMetadata + * runScriptOnNodesMatching + +== How to use the byon provider == +The byon provider requires you supply a list of nodes using a property. Here are +the valid properties you can use: + * byon.endpoint - url to access the list, can be http://, file://, classpath:// + * byon.nodes - inline defined yaml in string form. + +Note: + +The identity and credential fields of the ComputeServiceContextFactory are ignored. + +=== Java example === + +Properties props = new Properties(); + +// if you built the yaml string by hand +props.setProperty("byon.nodes", stringLiteral); + +// or you can specify an external reference +props.setProperty("byon.endpoint", "file://path/to/byon.yaml"); + +// or you can specify a file in your classpath +props.setProperty("byon.endpoint", "classpath:///byon.yaml"); + +context = new ComputeServiceContextFactory().createContext("byon", "foo", "bar", + ImmutableSet. of(new JschSshClientModule()), props); + +== File format == +You must define your nodes in yaml, and they must be in a collection called nodes. + +Here are the properties: + + * id - opaque unique id + * name - optional; user specified name + * description - optional; long description of this node + * note this is not yet in jclouds NodeMetadata + * hostname - name or ip address to contact the node on + * os_arch - ex. x86 + * os_family - must conform to org.jclouds.compute.domain.OsFamily in lower-hyphen format + ex. rhel, ubuntu, centos, debian, amzn-linux + * os_description - long description of the os ex. Ubuntu with lamp stack + * os_version - normalized to numbers when possible. ex. for centos: 5.3, ubuntu: 10.10 + * group - primary group of the machine. ex. hadoop + * tags - optional; list of arbitrary tags. + * note this list is not yet in jclouds NodeMetadata + * username - primary login user. ex. ubuntu, vcloud, toor, root + * sudo_password - optional; when a script is run with the "runAsRoot" option true, yet the + username is not root, a sudo command is invoked. If sudo_password + is set, the contents will be passed to sudo -S. + Ex. echo 'foobar'| sudo -S init 5 + + one of: + + * credential - RSA private key or password + * credential_url - location of plain-text RSA private key or password. + ex. file:///home/me/.ssh/id_rsa + classpath:///id_rsa + +Note that username and credentials are optional if a CredentialStoreModule is configured in +jclouds. + +=== Example File === + +nodes: + - id: i-sdfkjh7 + name: cluster-1 + description: accounting analytics cluster + hostname: cluster-1.mydomain.com + os_arch: x86 + os_family: rhel + os_description: redhat with CDH + os_version: 5.3 + group: hadoop + tags: + - vanilla + username: myUser + credential: | + -----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2 + u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ + lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o + -----END RSA PRIVATE KEY----- + sudo_password: go panthers! diff --git a/sandbox-apis/byon/pom.xml b/apis/byon/pom.xml similarity index 95% rename from sandbox-apis/byon/pom.xml rename to apis/byon/pom.xml index dd1741abc6..f6e5151af2 100644 --- a/sandbox-apis/byon/pom.xml +++ b/apis/byon/pom.xml @@ -58,7 +58,7 @@ log4j log4j - 1.2.14 + 1.2.16 test @@ -73,6 +73,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + org.yaml snakeyaml diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/BYONComputeServiceContextBuilder.java b/apis/byon/src/main/java/org/jclouds/byon/BYONComputeServiceContextBuilder.java similarity index 100% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/BYONComputeServiceContextBuilder.java rename to apis/byon/src/main/java/org/jclouds/byon/BYONComputeServiceContextBuilder.java diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/BYONPropertiesBuilder.java b/apis/byon/src/main/java/org/jclouds/byon/BYONPropertiesBuilder.java similarity index 100% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/BYONPropertiesBuilder.java rename to apis/byon/src/main/java/org/jclouds/byon/BYONPropertiesBuilder.java diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/Node.java b/apis/byon/src/main/java/org/jclouds/byon/Node.java similarity index 69% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/Node.java rename to apis/byon/src/main/java/org/jclouds/byon/Node.java index e5032843f6..9eecd2e87b 100644 --- a/sandbox-apis/byon/src/main/java/org/jclouds/byon/Node.java +++ b/apis/byon/src/main/java/org/jclouds/byon/Node.java @@ -19,6 +19,7 @@ package org.jclouds.byon; +import java.net.URI; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -35,48 +36,57 @@ public class Node { public Node() { } - public Node(String id, String description, String hostname, String osArch, String osFamily, String osName, - String osVersion, String group, List tags, String username, String credential, String sudo_password) { + public Node(String id, String name, String description, String hostname, String osArch, String osFamily, + String osDescription, String osVersion, String group, List tags, String username, + String credential, URI credentialUrl, String sudo_password) { this.id = id; + this.name = name; this.description = description; this.hostname = hostname; this.os_arch = osArch; this.os_family = osFamily; - this.os_name = osName; + this.os_description = osDescription; this.os_version = osVersion; this.group = group; this.tags = ImmutableList.copyOf(tags); this.username = username; this.credential = credential; + this.credential_url = credentialUrl != null ? credentialUrl.toASCIIString() : null; this.sudo_password = sudo_password; } // public due to snakeyaml public String id; + public String name; public String description; public String hostname; public String os_arch; public String os_family; - public String os_name; + public String os_description; public String os_version; public String group; public List tags; public String username; public String credential; + public String credential_url; public String sudo_password; public String getId() { return id; } - public String getGroup() { - return group; + public String getName() { + return name; } public String getDescription() { return description; } + public String getGroup() { + return group; + } + public String getHostname() { return hostname; } @@ -89,8 +99,8 @@ public class Node { return os_family; } - public String getOsName() { - return os_name; + public String getOsDescription() { + return os_description; } public String getOsVersion() { @@ -112,6 +122,10 @@ public class Node { return credential; } + public URI getCredentialUrl() { + return credential_url != null ? URI.create(credential_url) : null; + } + @Override public int hashCode() { return Objects.hashCode(id); @@ -130,10 +144,11 @@ public class Node { @Override public String toString() { - return Objects.toStringHelper(this).add("id", id).add("description", description).add("hostname", hostname).add( - "osArch", os_arch).add("osFamily", os_family).add("osName", os_name).add("osVersion", os_version).add( - "group", group).add("tags", tags).add("username", username).add("hasCredential", credential != null) - .add("hasSudoPassword", sudo_password != null).toString(); + return Objects.toStringHelper(this).add("id", id).add("name", name).add("description", description).add( + "hostname", hostname).add("osArch", os_arch).add("osFamily", os_family).add("osDescription", + os_description).add("osVersion", os_version).add("group", group).add("tags", tags).add("username", + username).add("hasCredential", credential != null || credential_url != null).add("hasSudoPassword", + sudo_password != null).toString(); } } diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java b/apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java similarity index 88% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java rename to apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java index dc7cdb1cd1..e29ad113b2 100644 --- a/sandbox-apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java +++ b/apis/byon/src/main/java/org/jclouds/byon/config/BYONComputeServiceContextModule.java @@ -20,6 +20,7 @@ package org.jclouds.byon.config; import java.io.InputStream; +import java.net.URI; import java.util.Map; import javax.inject.Singleton; @@ -31,7 +32,9 @@ import org.jclouds.byon.suppliers.NodesParsedFromSupplier; import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty; import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule; import org.jclouds.concurrent.SingleThreaded; +import org.jclouds.domain.Location; import org.jclouds.location.Provider; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; import com.google.common.base.Function; import com.google.common.base.Supplier; @@ -61,10 +64,14 @@ public class BYONComputeServiceContextModule extends @Override protected void configure() { super.configure(); + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZone.class); bind(new TypeLiteral>>() { }).to(NodesParsedFromSupplier.class); bind(new TypeLiteral>() { }).annotatedWith(Provider.class).to(SupplyFromProviderURIOrNodesProperty.class); + bind(new TypeLiteral>() { + }).to(SupplyFromProviderURIOrNodesProperty.class); // TODO make this somehow overridable via user request bind(new TypeLiteral>>() { }).to(NodesFromYaml.class); diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java b/apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java similarity index 61% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java rename to apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java index 078a2ede31..f1d819fd77 100644 --- a/sandbox-apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java +++ b/apis/byon/src/main/java/org/jclouds/byon/functions/NodeToNodeMetadata.java @@ -21,8 +21,12 @@ package org.jclouds.byon.functions; import static com.google.common.base.Preconditions.checkNotNull; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; import java.util.Map; +import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Singleton; @@ -32,11 +36,11 @@ import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.OperatingSystemBuilder; import org.jclouds.compute.domain.OsFamily; -import org.jclouds.crypto.CryptoStreams; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.logging.Logger; +import org.jclouds.util.Strings2; -import com.google.common.base.Charsets; import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; @@ -46,35 +50,54 @@ import com.google.common.collect.ImmutableSet; */ @Singleton public class NodeToNodeMetadata implements Function { + @Resource + protected Logger logger = Logger.NULL; + private final Supplier location; private final Map credentialStore; + private final Function slurp; @Inject - NodeToNodeMetadata(Supplier location, Map credentialStore) { + NodeToNodeMetadata(Supplier location, Function slurp, + Map credentialStore) { this.location = checkNotNull(location, "location"); this.credentialStore = checkNotNull(credentialStore, "credentialStore"); + this.slurp = checkNotNull(slurp, "slurp"); } @Override public NodeMetadata apply(Node from) { NodeMetadataBuilder builder = new NodeMetadataBuilder(); builder.ids(from.getId()); - builder.name(from.getDescription()); + builder.name(from.getName()); builder.location(location.get()); - builder.tag(from.getGroup()); + builder.group(from.getGroup()); // TODO add tags! builder.operatingSystem(new OperatingSystemBuilder().arch(from.getOsArch()).family( - OsFamily.fromValue(from.getOsFamily())).name(from.getOsName()).version(from.getOsVersion()).description( - from.getDescription()).build()); + OsFamily.fromValue(from.getOsFamily())).description(from.getOsDescription()) + .version(from.getOsVersion()).build()); builder.state(NodeState.RUNNING); builder.publicAddresses(ImmutableSet. of(from.getHostname())); - Credentials creds = new Credentials(from.getUsername(), new String(CryptoStreams.base64(from.getCredential()), - Charsets.UTF_8)); - builder.credentials(creds); + + if (from.getUsername() != null) { + Credentials creds = null; + if (from.getCredentialUrl() != null) { + try { + creds = new Credentials(from.getUsername(), Strings2.toStringAndClose(slurp.apply(from + .getCredentialUrl()))); + } catch (IOException e) { + logger.error(e, "URI could not be read: %s", from.getCredentialUrl()); + } + } else if (from.getCredential() != null) { + creds = new Credentials(from.getUsername(), from.getCredential()); + } + if (creds != null) + builder.credentials(creds); + credentialStore.put("node#" + from.getId(), creds); + } + if (from.getSudoPassword() != null) - builder.adminPassword(new String(CryptoStreams.base64(from.getSudoPassword()), Charsets.UTF_8)); - credentialStore.put("node#" + from.getId(), creds); + builder.adminPassword(from.getSudoPassword()); return builder.build(); } - } diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java b/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java similarity index 67% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java rename to apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java index 1dcfa29295..fd6d15843b 100644 --- a/sandbox-apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java +++ b/apis/byon/src/main/java/org/jclouds/byon/functions/NodesFromYaml.java @@ -22,6 +22,7 @@ package org.jclouds.byon.functions; import static com.google.common.base.Preconditions.checkState; import java.io.InputStream; +import java.util.List; import java.util.Map; import javax.inject.Singleton; @@ -33,26 +34,29 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; import com.google.common.base.Function; +import com.google.common.collect.Maps; /** * Parses the following syntax. * *
  * nodes:
- *     cluster-1:
- *         id: cluster-1
- *         description: xyz
- *         hostname: cluster-1.mydomain.com
- *         os_arch: x86
- *         os_family: linux
- *         os_name: redhat
- *         os_version: 5.3
- *         group: hadoop
- *         tags:
- *             - vanilla
- *         username: kelvin
- *         credential: password_or_rsa_in_base64
- *         sudo_password: password_in_base64
+ *     - id: cluster-1:
+ *       name: cluster-1
+ *       description: xyz
+ *       hostname: cluster-1.mydomain.com
+ *       os_arch: x86
+ *       os_family: linux
+ *       os_description: redhat
+ *       os_version: 5.3
+ *       group: hadoop
+ *       tags:
+ *           - vanilla
+ *       username: kelvin
+ *       credential: password_or_rsa
+ *         or
+ *       credential_url: password_or_rsa_file ex. resource:///id_rsa will get the classpath /id_rsa; file://path/to/id_rsa
+ *       sudo_password: password
  * 
* * @author Kelvin Kakugawa @@ -65,7 +69,7 @@ public class NodesFromYaml implements Function> { * */ public static class Config { - public Map nodes; + public List nodes; } @Override @@ -77,12 +81,18 @@ public class NodesFromYaml implements Function> { constructor.addTypeDescription(nodeDesc); TypeDescription configDesc = new TypeDescription(Config.class); - configDesc.putMapPropertyType("nodes", String.class, Node.class); + configDesc.putListPropertyType("nodes", Node.class); constructor.addTypeDescription(configDesc); Yaml yaml = new Yaml(new Loader(constructor)); Config config = (Config) yaml.load(source); - checkState(config != null, "missing nodes: collection"); - return config.nodes; + checkState(config != null, "missing config: class"); + checkState(config.nodes != null, "missing nodes: collection"); + + return Maps.uniqueIndex(config.nodes, new Function() { + public String apply(Node node) { + return node.getId(); + } + }); } -} \ No newline at end of file +} diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java similarity index 86% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java rename to apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java index f6bc145379..092c9bba2e 100644 --- a/sandbox-apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java +++ b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java @@ -35,8 +35,7 @@ import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; +import org.jclouds.location.suppliers.JustProvider; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; @@ -50,18 +49,18 @@ import com.google.common.collect.Iterables; public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAdapter { private final Supplier> nodes; private final NodeToNodeMetadata converter; - private final String providerName; + private final JustProvider locationSupplier; @Inject public BYONComputeServiceAdapter(Supplier> nodes, NodeToNodeMetadata converter, - @org.jclouds.location.Provider String providerName) { + JustProvider locationSupplier) { this.nodes = checkNotNull(nodes, "nodes"); this.converter = checkNotNull(converter, "converter"); - this.providerName = checkNotNull(providerName, "providerName"); + this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier"); } @Override - public NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, + public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, Map credentialStore) { throw new UnsupportedOperationException(); } @@ -81,9 +80,10 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda return Iterables.transform(nodes.get().values(), converter); } + @SuppressWarnings("unchecked") @Override public Iterable listLocations() { - return ImmutableSet. of(new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null)); + return (Iterable) locationSupplier.get(); } @Override diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/suppliers/NodesParsedFromSupplier.java b/apis/byon/src/main/java/org/jclouds/byon/suppliers/NodesParsedFromSupplier.java similarity index 100% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/suppliers/NodesParsedFromSupplier.java rename to apis/byon/src/main/java/org/jclouds/byon/suppliers/NodesParsedFromSupplier.java diff --git a/sandbox-apis/byon/src/main/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesProperty.java b/apis/byon/src/main/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesProperty.java similarity index 82% rename from sandbox-apis/byon/src/main/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesProperty.java rename to apis/byon/src/main/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesProperty.java index b54fcceb21..0bbd3f5b61 100644 --- a/sandbox-apis/byon/src/main/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesProperty.java +++ b/apis/byon/src/main/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesProperty.java @@ -32,6 +32,7 @@ import org.jclouds.logging.Logger; import org.jclouds.util.Strings2; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.base.Throwables; import com.google.inject.Inject; @@ -40,7 +41,7 @@ import com.google.inject.name.Named; /** * @author Adrian Cole */ -public class SupplyFromProviderURIOrNodesProperty implements Supplier { +public class SupplyFromProviderURIOrNodesProperty implements Supplier, Function { @Resource protected Logger logger = Logger.NULL; private final URI url; @@ -51,7 +52,7 @@ public class SupplyFromProviderURIOrNodesProperty implements Supplier of(NodesFromYamlTest.TEST1.id, NodesFromYamlTest.TEST1)); - assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(NodeToNodeMetadataTest.TEST1)); + assertEquals(context.getComputeService().listNodes(), ImmutableSet.of(NodeToNodeMetadataTest + .expectedNodeMetadataFromResource(endpoint))); } finally { if (context != null) context.close(); } } - } diff --git a/sandbox-apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java b/apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java similarity index 56% rename from sandbox-apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java rename to apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java index f7ab227b0a..0a1186664d 100644 --- a/sandbox-apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java +++ b/apis/byon/src/test/java/org/jclouds/byon/functions/NodeToNodeMetadataTest.java @@ -21,8 +21,10 @@ package org.jclouds.byon.functions; import static org.testng.Assert.assertEquals; +import java.net.URI; import java.util.Map; +import org.jclouds.byon.suppliers.SupplyFromProviderURIOrNodesProperty; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.NodeState; @@ -30,8 +32,8 @@ import org.jclouds.compute.domain.OperatingSystemBuilder; import org.jclouds.compute.domain.OsFamily; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.testng.annotations.Test; import com.google.common.base.Suppliers; @@ -44,23 +46,31 @@ import com.google.common.collect.Maps; * @author Adrian Cole */ public class NodeToNodeMetadataTest { - public static final Location location = new LocationImpl(LocationScope.PROVIDER, "byon", "byon", null); + public static Location expectedLocationFromResource(String resource) { + return new LocationBuilder().scope(LocationScope.PROVIDER).id("byon").description(resource).build(); + } - public static final NodeMetadata TEST1 = new NodeMetadataBuilder().ids("cluster-1").tag("hadoop").name("xyz").location( - location).state(NodeState.RUNNING).operatingSystem( - new OperatingSystemBuilder().name("redhat").family(OsFamily.RHEL).arch("x86").version("5.3").description( - "xyz").build()).publicAddresses(ImmutableSet.of("cluster-1.mydomain.com")).credentials( - new Credentials("myUser", "fancyfoot")).adminPassword("sudo").build(); + public static NodeMetadata expectedNodeMetadataFromResource(String resource) { + Location location = expectedLocationFromResource(resource); + + return new NodeMetadataBuilder().ids("cluster-1").group("hadoop").name("cluster-1").location(location).state( + NodeState.RUNNING).operatingSystem( + new OperatingSystemBuilder().description("redhat").family(OsFamily.RHEL).arch("x86").version("5.3") + .build()).publicAddresses(ImmutableSet.of("cluster-1.mydomain.com")).credentials( + new Credentials("myUser", NodesFromYamlTest.key)).adminPassword("happy bear").build(); + } @Test public void testNodesParse() throws Exception { Map credentialStore = Maps.newLinkedHashMap(); - NodeToNodeMetadata parser = new NodeToNodeMetadata(Suppliers.ofInstance(location), credentialStore); + NodeToNodeMetadata parser = new NodeToNodeMetadata( + Suppliers.ofInstance(expectedLocationFromResource("location")), + new SupplyFromProviderURIOrNodesProperty(URI.create("test")), credentialStore); - assertEquals(parser.apply(NodesFromYamlTest.TEST1), TEST1); - assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", "fancyfoot"))); + assertEquals(parser.apply(NodesFromYamlTest.TEST1), expectedNodeMetadataFromResource("location")); + assertEquals(credentialStore, ImmutableMap.of("node#cluster-1", new Credentials("myUser", NodesFromYamlTest.key))); } } diff --git a/sandbox-apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java b/apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java similarity index 62% rename from sandbox-apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java rename to apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java index 12e20a9e7b..614e67acee 100644 --- a/sandbox-apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java +++ b/apis/byon/src/test/java/org/jclouds/byon/functions/NodesFromYamlTest.java @@ -24,7 +24,6 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import org.jclouds.byon.Node; -import org.jclouds.crypto.CryptoStreams; import org.jclouds.util.Strings2; import org.testng.annotations.Test; @@ -36,10 +35,15 @@ import com.google.common.collect.ImmutableMap; * @author Adrian Cole */ public class NodesFromYamlTest { + public static final String key = new StringBuilder().append("-----BEGIN RSA PRIVATE KEY-----\n").append( + "MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2\n").append( + "u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ\n").append( + "lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o\n").append("-----END RSA PRIVATE KEY-----\n") + .toString(); - public static final Node TEST1 = new Node("cluster-1", "xyz", "cluster-1.mydomain.com", "x86", "rhel", "redhat", - "5.3", "hadoop", ImmutableList.of("vanilla"), "myUser", CryptoStreams.base64("fancyfoot".getBytes()), - CryptoStreams.base64("sudo".getBytes())); + public static final Node TEST1 = new Node("cluster-1", "cluster-1", "accounting analytics cluster", + "cluster-1.mydomain.com", "x86", "rhel", "redhat", "5.3", "hadoop", ImmutableList.of("vanilla"), "myUser", + key, null, "happy bear"); @Test public void testNodesParse() throws Exception { @@ -50,6 +54,15 @@ public class NodesFromYamlTest { assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1)); } + @Test + public void testNodesParseWhenCredentialInUrl() throws Exception { + + InputStream is = getClass().getResourceAsStream("/test_with_url.yaml"); + NodesFromYaml parser = new NodesFromYaml(); + + assertEquals(parser.apply(is), ImmutableMap.of(TEST1.getId(), TEST1)); + } + @Test(expectedExceptions = IllegalStateException.class) public void testMustParseSomething() throws Exception { new NodesFromYaml().apply(Strings2.toInputStream("")); diff --git a/sandbox-apis/byon/src/test/java/org/jclouds/byon/suppliers/NodesParsedFromSupplierTest.java b/apis/byon/src/test/java/org/jclouds/byon/suppliers/NodesParsedFromSupplierTest.java similarity index 85% rename from sandbox-apis/byon/src/test/java/org/jclouds/byon/suppliers/NodesParsedFromSupplierTest.java rename to apis/byon/src/test/java/org/jclouds/byon/suppliers/NodesParsedFromSupplierTest.java index cfb036a1f8..c94e008db5 100644 --- a/sandbox-apis/byon/src/test/java/org/jclouds/byon/suppliers/NodesParsedFromSupplierTest.java +++ b/apis/byon/src/test/java/org/jclouds/byon/suppliers/NodesParsedFromSupplierTest.java @@ -37,11 +37,4 @@ public class NodesParsedFromSupplierTest { new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n")), new NodesFromYaml()).get(); } - - public void testCanParseSomething() throws Exception { - - new NodesParsedFromSupplier(Suppliers.ofInstance(Strings2.toInputStream("nodes:\n first:\n")), - new NodesFromYaml()).get(); - - } } diff --git a/sandbox-apis/byon/src/test/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesPropertyTest.java b/apis/byon/src/test/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesPropertyTest.java similarity index 86% rename from sandbox-apis/byon/src/test/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesPropertyTest.java rename to apis/byon/src/test/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesPropertyTest.java index 0ad987aa76..9bbfae02c0 100644 --- a/sandbox-apis/byon/src/test/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesPropertyTest.java +++ b/apis/byon/src/test/java/org/jclouds/byon/suppliers/SupplyFromProviderURIOrNodesPropertyTest.java @@ -44,6 +44,17 @@ public class SupplyFromProviderURIOrNodesPropertyTest { } + @Test + public void testFromURIClasspath() throws Exception { + + SupplyFromProviderURIOrNodesProperty supplier = new SupplyFromProviderURIOrNodesProperty(URI + .create("classpath:///test1.yaml")); + + assertEquals(Strings2.toStringAndClose(supplier.get()), Strings2.toStringAndClose(getClass().getResourceAsStream( + "/test1.yaml"))); + + } + @Test public void testFromProperty() throws Exception { diff --git a/sandbox-apis/byon/src/test/resources/log4j.xml b/apis/byon/src/test/resources/log4j.xml similarity index 100% rename from sandbox-apis/byon/src/test/resources/log4j.xml rename to apis/byon/src/test/resources/log4j.xml diff --git a/apis/byon/src/test/resources/test1.yaml b/apis/byon/src/test/resources/test1.yaml new file mode 100644 index 0000000000..2711c5989b --- /dev/null +++ b/apis/byon/src/test/resources/test1.yaml @@ -0,0 +1,20 @@ +nodes: + - id: cluster-1 + name: cluster-1 + description: accounting analytics cluster + hostname: cluster-1.mydomain.com + os_arch: x86 + os_family: rhel + os_description: redhat + os_version: 5.3 + group: hadoop + tags: + - vanilla + username: myUser + credential: | + -----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2 + u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ + lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o + -----END RSA PRIVATE KEY----- + sudo_password: happy bear diff --git a/apis/byon/src/test/resources/test_with_url.yaml b/apis/byon/src/test/resources/test_with_url.yaml new file mode 100644 index 0000000000..4819f1ffa8 --- /dev/null +++ b/apis/byon/src/test/resources/test_with_url.yaml @@ -0,0 +1,15 @@ +nodes: + - id: cluster-1 + name: cluster-1 + description: accounting analytics cluster + hostname: cluster-1.mydomain.com + os_arch: x86 + os_family: rhel + os_description: redhat + os_version: 5.3 + group: hadoop + tags: + - vanilla + username: myUser + credential_url: classpath:///testkey.txt + sudo_password: happy bear diff --git a/apis/byon/src/test/resources/testkey.txt b/apis/byon/src/test/resources/testkey.txt new file mode 100644 index 0000000000..4402ea1f8c --- /dev/null +++ b/apis/byon/src/test/resources/testkey.txt @@ -0,0 +1,5 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuzaE6azgUxwESX1rCGdJ5xpdrc1XC311bOGZBCE8NA+CpFh2 +u01Vfv68NC4u6LFgdXSY1vQt6hiA5TNqQk0TyVfFAunbXgTekF6XqDPQUf1nq9aZ +lMvo4vlaLDKBkhG5HJE/pIa0iB+RMZLS0GhxsIWerEDmYdHKM25o +-----END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/demos/createandlistbuckets/README.txt b/apis/cloudfiles/README.txt old mode 100755 new mode 100644 similarity index 68% rename from demos/createandlistbuckets/README.txt rename to apis/cloudfiles/README.txt index e21edf3a3a..f45ece8e49 --- a/demos/createandlistbuckets/README.txt +++ b/apis/cloudfiles/README.txt @@ -18,8 +18,8 @@ ==== # -# this is a simple example command line client that creates a bucket, then displays all buckets you own -# 1. execute 'mvn install' to build the sample -# 2. invoke the jar, passing your aws credentials and the bucket you wish to create -# ex. -# java -jar target/jclouds-aws-demo-createandlistbuckets-jar-with-dependencies.jar $AWS_USER $AWS_PWD testbucketmeo +# The jclouds API for Rackspace's Cloud Files (http://www.rackspacecloud.com/cloud_hosting_products/files/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/antcontrib/samples/cargooverssh/README.txt b/apis/cloudservers/README.txt similarity index 65% rename from antcontrib/samples/cargooverssh/README.txt rename to apis/cloudservers/README.txt index 5d37a807a3..b89f80ab55 100644 --- a/antcontrib/samples/cargooverssh/README.txt +++ b/apis/cloudservers/README.txt @@ -17,13 +17,9 @@ ==================================================================== ==== -Note that the following are prerequisites: -1. Ant 1.7.1 is installed and in your path - wget http://archive.apache.org/dist/ant/binaries/apache-ant-1.7.1-bin.zip - jar -xf apache-ant-1.7.1-bin.zip - chmod 755 apache-ant-1.7.1/bin/* - export PATH=apache-ant-1.7.1/bin:$PATH -2. jsch 0.1.42 is in $ANT_HOME/lib - cd apache-ant-1.7.1/lib - wget https://sourceforge.net/projects/jsch/files/jsch/jsch-0.1.42.jar - +# +# The jclouds API for Rackspace's Cloud Server (http://www.rackspacecloud.com/cloud_hosting_products/servers/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/cloudservers/pom.xml b/apis/cloudservers/pom.xml index 9b08f1f501..63a91b426c 100644 --- a/apis/cloudservers/pom.xml +++ b/apis/cloudservers/pom.xml @@ -79,6 +79,12 @@ ${project.version} test
+ + com.jcraft + jsch + 0.1.44 + test + org.jclouds.driver jclouds-log4j diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java index 9b9009779e..76026dba58 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/CloudServersAsyncClient.java @@ -32,16 +32,7 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; -import org.jclouds.http.functions.ReturnFalseOn404; -import org.jclouds.cloudservers.binders.BindAdminPassToJsonPayload; import org.jclouds.cloudservers.binders.BindBackupScheduleToJsonPayload; -import org.jclouds.cloudservers.binders.BindConfirmResizeToJsonPayload; -import org.jclouds.cloudservers.binders.BindCreateImageToJsonPayload; -import org.jclouds.cloudservers.binders.BindRebootTypeToJsonPayload; -import org.jclouds.cloudservers.binders.BindResizeFlavorToJsonPayload; -import org.jclouds.cloudservers.binders.BindRevertResizeToJsonPayload; -import org.jclouds.cloudservers.binders.BindServerNameToJsonPayload; -import org.jclouds.cloudservers.binders.BindSharedIpGroupToJsonPayload; import org.jclouds.cloudservers.domain.Addresses; import org.jclouds.cloudservers.domain.BackupSchedule; import org.jclouds.cloudservers.domain.Flavor; @@ -53,13 +44,15 @@ import org.jclouds.cloudservers.options.CreateServerOptions; import org.jclouds.cloudservers.options.CreateSharedIpGroupOptions; import org.jclouds.cloudservers.options.ListOptions; import org.jclouds.cloudservers.options.RebuildServerOptions; +import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.openstack.filters.AddTimestampQuery; import org.jclouds.openstack.filters.AuthenticateRequest; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.Payload; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.SkipEncoding; @@ -82,8 +75,8 @@ import com.google.common.util.concurrent.ListenableFuture; * @see * @author Adrian Cole */ -@SkipEncoding( { '/', '=' }) -@RequestFilters( { AuthenticateRequest.class, AddTimestampQuery.class }) +@SkipEncoding({ '/', '=' }) +@RequestFilters({ AuthenticateRequest.class, AddTimestampQuery.class }) @Endpoint(ServerManagement.class) public interface CloudServersAsyncClient { @@ -123,8 +116,9 @@ public interface CloudServersAsyncClient { @POST @QueryParams(keys = "format", values = "json") @Path("/servers/{id}/action") - ListenableFuture rebootServer(@PathParam("id") int id, - @BinderParam(BindRebootTypeToJsonPayload.class) RebootType rebootType); + @Produces(MediaType.APPLICATION_JSON) + @Payload("%7B\"reboot\":%7B\"type\":\"{type}\"%7D%7D") + ListenableFuture rebootServer(@PathParam("id") int id, @PayloadParam("type") RebootType rebootType); /** * @see CloudServersClient#resizeServer @@ -132,8 +126,9 @@ public interface CloudServersAsyncClient { @POST @QueryParams(keys = "format", values = "json") @Path("/servers/{id}/action") - ListenableFuture resizeServer(@PathParam("id") int id, - @BinderParam(BindResizeFlavorToJsonPayload.class) int flavorId); + @Produces(MediaType.APPLICATION_JSON) + @Payload("%7B\"resize\":%7B\"flavorId\":{flavorId}%7D%7D") + ListenableFuture resizeServer(@PathParam("id") int id, @PayloadParam("flavorId") int flavorId); /** * @see CloudServersClient#confirmResizeServer @@ -142,7 +137,8 @@ public interface CloudServersAsyncClient { @QueryParams(keys = "format", values = "json") @Path("/servers/{id}/action") @Produces(MediaType.APPLICATION_JSON) - ListenableFuture confirmResizeServer(@PathParam("id") @BinderParam(BindConfirmResizeToJsonPayload.class) int id); + @Payload("{\"confirmResize\":null}") + ListenableFuture confirmResizeServer(@PathParam("id") int id); /** * @see CloudServersClient#revertResizeServer @@ -151,7 +147,8 @@ public interface CloudServersAsyncClient { @QueryParams(keys = "format", values = "json") @Path("/servers/{id}/action") @Produces(MediaType.APPLICATION_JSON) - ListenableFuture revertResizeServer(@PathParam("id") @BinderParam(BindRevertResizeToJsonPayload.class) int id); + @Payload("{\"revertResize\":null}") + ListenableFuture revertResizeServer(@PathParam("id") int id); /** * @see CloudServersClient#createServer @@ -162,8 +159,8 @@ public interface CloudServersAsyncClient { @QueryParams(keys = "format", values = "json") @Path("/servers") @MapBinder(CreateServerOptions.class) - ListenableFuture createServer(@MapPayloadParam("name") String name, @MapPayloadParam("imageId") int imageId, - @MapPayloadParam("flavorId") int flavorId, CreateServerOptions... options); + ListenableFuture createServer(@PayloadParam("name") String name, @PayloadParam("imageId") int imageId, + @PayloadParam("flavorId") int flavorId, CreateServerOptions... options); /** * @see CloudServersClient#rebuildServer @@ -179,10 +176,11 @@ public interface CloudServersAsyncClient { */ @PUT @Path("/servers/{id}/ips/public/{address}") - @MapBinder(BindSharedIpGroupToJsonPayload.class) + @Produces(MediaType.APPLICATION_JSON) + @Payload("%7B\"shareIp\":%7B\"sharedIpGroupId\":{sharedIpGroupId},\"configureServer\":{configureServer}%7D%7D") ListenableFuture shareIp(@PathParam("address") String addressToShare, - @PathParam("id") int serverToTosignBindressTo, @MapPayloadParam("sharedIpGroupId") int sharedIpGroup, - @MapPayloadParam("configureServer") boolean configureServer); + @PathParam("id") int serverToTosignBindressTo, @PayloadParam("sharedIpGroupId") int sharedIpGroup, + @PayloadParam("configureServer") boolean configureServer); /** * @see CloudServersClient#unshareIp @@ -191,23 +189,25 @@ public interface CloudServersAsyncClient { @Path("/servers/{id}/ips/public/{address}") @ExceptionParser(ReturnVoidOnNotFoundOr404.class) ListenableFuture unshareIp(@PathParam("address") String addressToShare, - @PathParam("id") int serverToTosignBindressTo); + @PathParam("id") int serverToTosignBindressTo); /** * @see CloudServersClient#changeAdminPass */ @PUT @Path("/servers/{id}") - ListenableFuture changeAdminPass(@PathParam("id") int id, - @BinderParam(BindAdminPassToJsonPayload.class) String adminPass); + @Produces(MediaType.APPLICATION_JSON) + @Payload("%7B\"server\":%7B\"adminPass\":\"{adminPass}\"%7D%7D") + ListenableFuture changeAdminPass(@PathParam("id") int id, @PayloadParam("adminPass") String adminPass); /** * @see CloudServersClient#renameServer */ @PUT @Path("/servers/{id}") - ListenableFuture renameServer(@PathParam("id") int id, - @BinderParam(BindServerNameToJsonPayload.class) String newName); + @Produces(MediaType.APPLICATION_JSON) + @Payload("%7B\"server\":%7B\"name\":\"{name}\"%7D%7D") + ListenableFuture renameServer(@PathParam("id") int id, @PayloadParam("name") String newName); /** * @see CloudServersClient#listFlavors @@ -268,10 +268,11 @@ public interface CloudServersAsyncClient { @Unwrap @Consumes(MediaType.APPLICATION_JSON) @QueryParams(keys = "format", values = "json") - @MapBinder(BindCreateImageToJsonPayload.class) @Path("/images") - ListenableFuture createImageFromServer(@MapPayloadParam("imageName") String imageName, - @MapPayloadParam("serverId") int serverId); + @Produces(MediaType.APPLICATION_JSON) + @Payload("%7B\"image\":%7B\"serverId\":{serverId},\"name\":\"{name}\"%7D%7D") + ListenableFuture createImageFromServer(@PayloadParam("name") String imageName, + @PayloadParam("serverId") int serverId); /** * @see CloudServersClient#listSharedIpGroups @@ -304,8 +305,8 @@ public interface CloudServersAsyncClient { @QueryParams(keys = "format", values = "json") @Path("/shared_ip_groups") @MapBinder(CreateSharedIpGroupOptions.class) - ListenableFuture createSharedIpGroup(@MapPayloadParam("name") String name, - CreateSharedIpGroupOptions... options); + ListenableFuture createSharedIpGroup(@PayloadParam("name") String name, + CreateSharedIpGroupOptions... options); /** * @see CloudServersClient#deleteSharedIpGroup @@ -340,7 +341,7 @@ public interface CloudServersAsyncClient { @ExceptionParser(ReturnFalseOn404.class) @Path("/servers/{id}/backup_schedule") ListenableFuture replaceBackupSchedule(@PathParam("id") int id, - @BinderParam(BindBackupScheduleToJsonPayload.class) BackupSchedule backupSchedule); + @BinderParam(BindBackupScheduleToJsonPayload.class) BackupSchedule backupSchedule); /** * @see CloudServersClient#listAddresses diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindCreateImageToJsonPayload.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindCreateImageToJsonPayload.java deleted file mode 100644 index bb5e038c2b..0000000000 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindCreateImageToJsonPayload.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.BindToJsonPayload; - -import com.google.common.collect.ImmutableMap; - -/** - * - * @author Adrian Cole - * - */ -@Singleton -public class BindCreateImageToJsonPayload extends BindToJsonPayload { - - @SuppressWarnings("unused") - private class CreateImageRequest { - final int serverId; - final String name; - - private CreateImageRequest(int serverId, String name) { - this.serverId = serverId; - this.name = name; - } - - } - - @Override - public R bindToRequest(R request, Map postParams) { - CreateImageRequest createRequest = new CreateImageRequest(Integer - .parseInt(checkNotNull(postParams.get("serverId"))), checkNotNull(postParams - .get("imageName"))); - return super.bindToRequest(request, ImmutableMap.of("image", createRequest)); - } - - @Override - public R bindToRequest(R request, Object toBind) { - throw new IllegalArgumentException("image is needs parameters"); - } -} diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindRebootTypeToJsonPayload.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindRebootTypeToJsonPayload.java deleted file mode 100644 index 98902075cc..0000000000 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindRebootTypeToJsonPayload.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpRequest; -import org.jclouds.cloudservers.domain.RebootType; -import org.jclouds.rest.binders.BindToJsonPayload; - -import com.google.common.collect.ImmutableMap; - -/** - * - * @author Adrian Cole - * - */ -@Singleton -public class BindRebootTypeToJsonPayload extends BindToJsonPayload { - - @Override - public R bindToRequest(R request, Map postParams) { - throw new IllegalStateException("Reboot doesn't take map parameters"); - } - - @Override - public R bindToRequest(R request, Object toBind) { - checkArgument(toBind instanceof RebootType, "this binder is only valid for RebootTypes!"); - return super.bindToRequest(request, ImmutableMap.of("reboot", ImmutableMap.of("type", checkNotNull( - toBind, "type")))); - } -} diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindResizeFlavorToJsonPayload.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindResizeFlavorToJsonPayload.java deleted file mode 100644 index 053383552a..0000000000 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindResizeFlavorToJsonPayload.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.BindToJsonPayload; - -import com.google.common.collect.ImmutableMap; - -/** - * - * @author Adrian Cole - * - */ -@Singleton -public class BindResizeFlavorToJsonPayload extends BindToJsonPayload { - - @Override - public R bindToRequest(R request, Map postParams) { - throw new IllegalStateException("Resize doesn't take map parameters"); - } - - @Override - public R bindToRequest(R request, Object toBind) { - checkArgument(toBind instanceof Integer, "this binder is only valid for integers!"); - return super.bindToRequest(request, ImmutableMap.of("resize", ImmutableMap.of("flavorId", - (Integer) checkNotNull(toBind, "flavorId")))); - } -} diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindSharedIpGroupToJsonPayload.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindSharedIpGroupToJsonPayload.java deleted file mode 100644 index 332d667e96..0000000000 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindSharedIpGroupToJsonPayload.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.BindToJsonPayload; - -import com.google.common.collect.ImmutableMap; - -/** - * - * @author Adrian Cole - * - */ -@Singleton -public class BindSharedIpGroupToJsonPayload extends BindToJsonPayload { - - @SuppressWarnings("unused") - private class ShareIpRequest { - final int sharedIpGroupId; - Boolean configureServer; - - private ShareIpRequest(int sharedIpGroupId) { - this.sharedIpGroupId = sharedIpGroupId; - } - - } - - @Override - public R bindToRequest(R request, Map postParams) { - ShareIpRequest createRequest = new ShareIpRequest(Integer.parseInt(checkNotNull(postParams - .get("sharedIpGroupId")))); - if (Boolean.parseBoolean(checkNotNull(postParams.get("configureServer")))) { - createRequest.configureServer = new Boolean(true); - } - return super.bindToRequest(request, ImmutableMap.of("shareIp", createRequest)); - } - - @Override - public R bindToRequest(R request, Object toBind) { - throw new IllegalStateException("shareIp is needs parameters"); - } -} diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeStrategiesByClass.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeStrategiesByClass.java index 99923bde57..f864b75430 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeStrategiesByClass.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeStrategiesByClass.java @@ -20,14 +20,14 @@ package org.jclouds.cloudservers.compute.config; import org.jclouds.compute.config.BindComputeStrategiesByClass; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.cloudservers.compute.strategy.CloudServersAddNodeWithTagStrategy; +import org.jclouds.cloudservers.compute.strategy.CloudServersCreateNodeWithGroupEncodedIntoName; import org.jclouds.cloudservers.compute.strategy.CloudServersDestroyNodeStrategy; import org.jclouds.cloudservers.compute.strategy.CloudServersGetNodeMetadataStrategy; import org.jclouds.cloudservers.compute.strategy.CloudServersListNodesStrategy; @@ -41,8 +41,8 @@ import org.jclouds.cloudservers.compute.strategy.CloudServersLifeCycleStrategy; public class CloudServersBindComputeStrategiesByClass extends BindComputeStrategiesByClass { @Override - protected Class defineAddNodeWithTagStrategy() { - return CloudServersAddNodeWithTagStrategy.class; + protected Class defineAddNodeWithTagStrategy() { + return CloudServersCreateNodeWithGroupEncodedIntoName.class; } @Override diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeSuppliersByClass.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeSuppliersByClass.java index ba33a9b224..9e5e99b984 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeSuppliersByClass.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersBindComputeSuppliersByClass.java @@ -21,13 +21,13 @@ package org.jclouds.cloudservers.compute.config; import java.util.Set; +import org.jclouds.cloudservers.compute.suppliers.CloudServersHardwareSupplier; +import org.jclouds.cloudservers.compute.suppliers.CloudServersImageSupplier; import org.jclouds.compute.config.BindComputeSuppliersByClass; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.domain.Location; -import org.jclouds.cloudservers.compute.suppliers.CloudServersHardwareSupplier; -import org.jclouds.cloudservers.compute.suppliers.CloudServersImageSupplier; -import org.jclouds.location.suppliers.SupplyPredefinedRegions; +import org.jclouds.location.suppliers.JustProvider; import com.google.common.base.Supplier; @@ -49,6 +49,6 @@ public class CloudServersBindComputeSuppliersByClass extends BindComputeSupplier @Override protected Class>> defineLocationSupplier() { - return SupplyPredefinedRegions.class; + return JustProvider.class; } } diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersComputeServiceDependenciesModule.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersComputeServiceDependenciesModule.java index 684b7517f1..c9bda3e9c4 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersComputeServiceDependenciesModule.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/config/CloudServersComputeServiceDependenciesModule.java @@ -20,7 +20,6 @@ package org.jclouds.cloudservers.compute.config; import java.util.Map; -import java.util.Set; import javax.inject.Singleton; @@ -41,8 +40,6 @@ import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.internal.BaseComputeService; import org.jclouds.compute.internal.ComputeServiceContextImpl; -import org.jclouds.location.Region; -import org.jclouds.location.config.ProvideRegionsViaProperties; import org.jclouds.rest.RestContext; import org.jclouds.rest.internal.RestContextImpl; @@ -82,8 +79,6 @@ public class CloudServersComputeServiceDependenciesModule extends AbstractModule bind(new TypeLiteral>() { }).to(new TypeLiteral>() { }).in(Scopes.SINGLETON); - bind(new TypeLiteral>() { - }).annotatedWith(Region.class).toProvider(ProvideRegionsViaProperties.class).in(Scopes.SINGLETON); } @VisibleForTesting diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadata.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadata.java index 968d9ca4d8..4ea7a23122 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadata.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadata.java @@ -20,7 +20,7 @@ package org.jclouds.cloudservers.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import java.util.Map; import java.util.NoSuchElementException; @@ -31,6 +31,8 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import org.jclouds.cloudservers.domain.Server; +import org.jclouds.cloudservers.domain.ServerStatus; import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; @@ -41,11 +43,9 @@ import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.logging.Logger; -import org.jclouds.cloudservers.domain.Server; -import org.jclouds.cloudservers.domain.ServerStatus; import com.google.common.base.Function; import com.google.common.base.Predicate; @@ -60,7 +60,7 @@ public class ServerToNodeMetadata implements Function { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; - + protected final Supplier location; protected final Map credentialStore; protected final Map serverToNodeState; @@ -109,9 +109,10 @@ public class ServerToNodeMetadata implements Function { NodeMetadataBuilder builder = new NodeMetadataBuilder(); builder.ids(from.getId() + ""); builder.name(from.getName()); - builder.location(new LocationImpl(LocationScope.HOST, from.getHostId(), from.getHostId(), location.get())); + builder.location(new LocationBuilder().scope(LocationScope.HOST).id(from.getHostId()).description( + from.getHostId()).parent(location.get()).build()); builder.userMetadata(from.getMetadata()); - builder.tag(parseTagFromName(from.getName())); + builder.group(parseGroupFromName(from.getName())); builder.imageId(from.getImageId() + ""); builder.operatingSystem(parseOperatingSystem(from)); builder.hardware(parseHardware(from)); diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersAddNodeWithTagStrategy.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersCreateNodeWithGroupEncodedIntoName.java similarity index 83% rename from apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersAddNodeWithTagStrategy.java rename to apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersCreateNodeWithGroupEncodedIntoName.java index 781155ede1..e99e0316a3 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersAddNodeWithTagStrategy.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersCreateNodeWithGroupEncodedIntoName.java @@ -28,7 +28,7 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.domain.Credentials; import org.jclouds.cloudservers.CloudServersClient; import org.jclouds.cloudservers.domain.Server; @@ -39,13 +39,13 @@ import com.google.common.base.Function; * @author Adrian Cole */ @Singleton -public class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrategy { +public class CloudServersCreateNodeWithGroupEncodedIntoName implements CreateNodeWithGroupEncodedIntoName { protected final CloudServersClient client; protected final Map credentialStore; protected final Function serverToNodeMetadata; @Inject - protected CloudServersAddNodeWithTagStrategy(CloudServersClient client, Map credentialStore, + protected CloudServersCreateNodeWithGroupEncodedIntoName(CloudServersClient client, Map credentialStore, Function serverToNodeMetadata) { this.client = checkNotNull(client, "client"); this.credentialStore = checkNotNull(credentialStore, "credentialStore"); @@ -53,7 +53,7 @@ public class CloudServersAddNodeWithTagStrategy implements AddNodeWithTagStrateg } @Override - public NodeMetadata addNodeWithTag(String tag, String name, Template template) { + public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { Server from = client.createServer(name, Integer.parseInt(template.getImage().getProviderId()), Integer .parseInt(template.getHardware().getProviderId())); credentialStore.put("node#" + from.getId(), new Credentials("root", from.getAdminPass())); diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/domain/BackupSchedule.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/domain/BackupSchedule.java index e8d8df6af2..0c63c4f588 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/domain/BackupSchedule.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/domain/BackupSchedule.java @@ -65,7 +65,7 @@ public class BackupSchedule { @Override public String toString() { - return "BackupSchedule [daily=" + daily + ", enabled=" + enabled + ", weekly=" + weekly + "]"; + return "[daily=" + daily + ", enabled=" + enabled + ", weekly=" + weekly + "]"; } @Override diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersAsyncClientTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersAsyncClientTest.java index a625496ea4..09fb445b02 100644 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersAsyncClientTest.java +++ b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/CloudServersAsyncClientTest.java @@ -20,7 +20,6 @@ package org.jclouds.cloudservers; import static org.jclouds.Constants.PROPERTY_API_VERSION; -import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withFile; import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withMetadata; import static org.jclouds.cloudservers.options.CreateServerOptions.Builder.withSharedIpGroup; @@ -55,8 +54,8 @@ import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReturnFalseOn404; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.UnwrapOnlyJsonValue; -import org.jclouds.openstack.TestOpenStackAuthenticationModule; import org.jclouds.openstack.OpenStackAuthAsyncClient.AuthenticationResponse; +import org.jclouds.openstack.TestOpenStackAuthenticationModule; import org.jclouds.openstack.filters.AddTimestampQuery; import org.jclouds.openstack.filters.AuthenticateRequest; import org.jclouds.rest.ConfiguresRestClient; @@ -85,17 +84,17 @@ import com.google.inject.TypeLiteral; public class CloudServersAsyncClientTest extends RestClientTest { private static final Class listOptionsVarargsClass = new ListOptions[] {}.getClass(); private static final Class createServerOptionsVarargsClass = new CreateServerOptions[] {} - .getClass(); + .getClass(); public void testCreateServer() throws IOException, SecurityException, NoSuchMethodException { Method method = CloudServersAsyncClient.class.getMethod("createServer", String.class, int.class, int.class, - createServerOptionsVarargsClass); + createServerOptionsVarargsClass); HttpRequest request = processor.createRequest(method, "ralphie", 2, 1); assertRequestLineEquals(request, "POST http://serverManagementUrl/servers?format=json HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Accept: application/json\n"); assertPayloadEquals(request, "{\"server\":{\"name\":\"ralphie\",\"imageId\":2,\"flavorId\":1}}", - "application/json", false); + "application/json", false); assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValue.class); assertSaxResponseParserClassEquals(method, null); @@ -107,14 +106,14 @@ public class CloudServersAsyncClientTest extends RestClientTest createSharedIpGroupOptionsVarargsClass = new CreateSharedIpGroupOptions[] {} - .getClass(); + .getClass(); public void testCreateSharedIpGroup() throws IOException, SecurityException, NoSuchMethodException { Method method = CloudServersAsyncClient.class.getMethod("createSharedIpGroup", String.class, - createSharedIpGroupOptionsVarargsClass); + createSharedIpGroupOptionsVarargsClass); HttpRequest request = processor.createRequest(method, "ralphie"); assertRequestLineEquals(request, "POST http://serverManagementUrl/shared_ip_groups?format=json HTTP/1.1"); @@ -650,13 +650,13 @@ public class CloudServersAsyncClientTest extends RestClientTest rebuildServerOptionsVarargsClass = new RebuildServerOptions[] {} - .getClass(); + .getClass(); public void testRebuildServer() throws IOException, SecurityException, NoSuchMethodException { Method method = CloudServersAsyncClient.class.getMethod("rebuildServer", int.class, - rebuildServerOptionsVarargsClass); + rebuildServerOptionsVarargsClass); HttpRequest request = processor.createRequest(method, 3); assertRequestLineEquals(request, "POST http://serverManagementUrl/servers/3/action?format=json HTTP/1.1"); @@ -778,7 +778,7 @@ public class CloudServersAsyncClientTest extends RestClientTest createContextSpec() { - return new RestContextFactory().createContextSpec(provider, "user", "password", new Properties()); + public RestContextSpec createContextSpec() { + return new RestContextFactory(getProperties()).createContextSpec(provider, "user", "password", new Properties()); } @Override protected Properties getProperties() { - Properties properties = new Properties(); - properties.setProperty(PROPERTY_REGIONS, "US"); - properties.setProperty(PROPERTY_ENDPOINT, "https://auth"); - properties.setProperty(PROPERTY_API_VERSION, "1"); - return properties; + Properties overrides = new Properties(); + overrides.setProperty(PROPERTY_REGIONS, "US"); + overrides.setProperty(PROPERTY_API_VERSION, "1"); + overrides.setProperty(provider + ".endpoint", "https://auth"); + overrides.setProperty(provider + ".contextbuilder", CloudServersContextBuilder.class.getName()); + return overrides; } } diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindAdminPassToJsonPayloadTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindAdminPassToJsonPayloadTest.java deleted file mode 100644 index 1a2e8b4013..0000000000 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindAdminPassToJsonPayloadTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static org.testng.Assert.assertEquals; - -import java.io.File; -import java.net.URI; - -import javax.ws.rs.HttpMethod; - -import org.jclouds.http.HttpRequest; -import org.jclouds.json.config.GsonModule; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Guice; -import com.google.inject.Injector; - -/** - * Tests behavior of {@code BindAdminPassToJsonPayload} - * - * @author Adrian Cole - */ -@Test(groups = "unit") -public class BindAdminPassToJsonPayloadTest { - - Injector injector = Guice.createInjector(new GsonModule()); - - @Test(expectedExceptions = IllegalStateException.class) - public void testPostIsIncorrect() { - BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, ImmutableMap.of("adminPass", "foo")); - } - - @Test(expectedExceptions = IllegalArgumentException.class) - public void testMustBeString() { - BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, new File("foo")); - } - - @Test - public void testCorrect() { - BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.bindToRequest(request, "foo"); - assertEquals("{\"server\":{\"adminPass\":\"foo\"}}", request.getPayload().getRawContent()); - } - - @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) - public void testNullIsBad() { - BindAdminPassToJsonPayload binder = new BindAdminPassToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.bindToRequest(request, null); - } -} diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindCreateImageToJsonPayloadTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindCreateImageToJsonPayloadTest.java deleted file mode 100644 index e2244b0d90..0000000000 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindCreateImageToJsonPayloadTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static org.testng.Assert.assertEquals; - -import java.io.File; -import java.net.URI; - -import javax.ws.rs.HttpMethod; - -import org.jclouds.http.HttpRequest; -import org.jclouds.json.config.GsonModule; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Guice; -import com.google.inject.Injector; - -/** - * Tests behavior of {@code BindCreateImageToJsonPayload} - * - * @author Adrian Cole - */ -@Test(groups = "unit") -public class BindCreateImageToJsonPayloadTest { - - Injector injector = Guice.createInjector(new GsonModule()); - - @Test(expectedExceptions = IllegalArgumentException.class) - public void testMustBeMap() { - BindCreateImageToJsonPayload binder = new BindCreateImageToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, new File("foo")); - } - - @Test - public void testCorrect() { - BindCreateImageToJsonPayload binder = new BindCreateImageToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.bindToRequest(request, ImmutableMap.of("imageName", "foo", "serverId", "2")); - assertEquals("{\"image\":{\"serverId\":2,\"name\":\"foo\"}}", request.getPayload() - .getRawContent()); - } - - @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) - public void testNullIsBad() { - BindCreateImageToJsonPayload binder = new BindCreateImageToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.bindToRequest(request, null); - } -} diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindRebootTypeToJsonPayloadTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindRebootTypeToJsonPayloadTest.java deleted file mode 100644 index 29d845f8d2..0000000000 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindRebootTypeToJsonPayloadTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static org.testng.Assert.assertEquals; - -import java.io.File; -import java.net.URI; - -import javax.ws.rs.HttpMethod; - -import org.jclouds.http.HttpRequest; -import org.jclouds.json.config.GsonModule; -import org.jclouds.cloudservers.domain.RebootType; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Guice; -import com.google.inject.Injector; - -/** - * Tests behavior of {@code BindRebootTypeToJsonPayload} - * - * @author Adrian Cole - */ -@Test(groups = "unit") -public class BindRebootTypeToJsonPayloadTest { - - Injector injector = Guice.createInjector(new GsonModule()); - - @Test(expectedExceptions = IllegalStateException.class) - public void testPostIsIncorrect() { - BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, ImmutableMap.of("adminPass", "foo")); - } - - @Test(expectedExceptions = IllegalArgumentException.class) - public void testMustBeRebootType() { - BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, new File("foo")); - } - - @Test - public void testHard() { - BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, RebootType.HARD); - assertEquals("{\"reboot\":{\"type\":\"HARD\"}}", request.getPayload().getRawContent()); - } - - @Test - public void testSoft() { - BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, RebootType.SOFT); - assertEquals("{\"reboot\":{\"type\":\"SOFT\"}}", request.getPayload().getRawContent()); - } - - @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) - public void testNullIsBad() { - BindRebootTypeToJsonPayload binder = new BindRebootTypeToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, null); - } -} diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindServerNameToJsonPayloadTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindServerNameToJsonPayloadTest.java deleted file mode 100644 index 26b897e940..0000000000 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/binders/BindServerNameToJsonPayloadTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.binders; - -import static org.testng.Assert.assertEquals; - -import java.io.File; -import java.net.URI; - -import javax.ws.rs.HttpMethod; - -import org.jclouds.http.HttpRequest; -import org.jclouds.json.config.GsonModule; -import org.testng.annotations.Test; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Guice; -import com.google.inject.Injector; - -/** - * Tests behavior of {@code BindServerNameToJsonPayload} - * - * @author Adrian Cole - */ -@Test(groups = "unit") -public class BindServerNameToJsonPayloadTest { - - Injector injector = Guice.createInjector(new GsonModule()); - - @Test(expectedExceptions = IllegalStateException.class) - public void testPostIsIncorrect() { - BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, ImmutableMap.of("name", "foo")); - } - - @Test(expectedExceptions = IllegalArgumentException.class) - public void testMustBeString() { - BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.POST, URI.create("http://localhost")); - binder.bindToRequest(request, new File("foo")); - } - - @Test - public void testCorrect() { - BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.bindToRequest(request, "foo"); - assertEquals("{\"server\":{\"name\":\"foo\"}}", request.getPayload().getRawContent()); - } - - @Test(expectedExceptions = { NullPointerException.class, IllegalStateException.class }) - public void testNullIsBad() { - BindServerNameToJsonPayload binder = new BindServerNameToJsonPayload(); - injector.injectMembers(binder); - HttpRequest request = new HttpRequest(HttpMethod.PUT, URI.create("http://localhost")); - binder.bindToRequest(request, null); - } -} diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/CloudServersTemplateBuilderLiveTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/CloudServersTemplateBuilderLiveTest.java deleted file mode 100644 index 6ef10ca2b4..0000000000 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/CloudServersTemplateBuilderLiveTest.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.cloudservers.compute; - -import org.jclouds.compute.BaseTemplateBuilderLiveTest; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; -import org.testng.annotations.Test; - -import com.google.common.base.Predicate; - -/** - * - * @author Adrian Cole - */ -@Test(groups = "live") -public class CloudServersTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { - - public CloudServersTemplateBuilderLiveTest() { - provider = "cloudservers"; - } - - @Override - protected Predicate defineUnsupportedOperatingSystems() { - return new Predicate() { - - @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); - } - - }; - } - -} diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/FlavorToHardwareTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/FlavorToHardwareTest.java index 729be37094..d5974d371f 100644 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/FlavorToHardwareTest.java +++ b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/FlavorToHardwareTest.java @@ -23,16 +23,16 @@ import static org.testng.Assert.assertEquals; import java.net.UnknownHostException; +import org.jclouds.cloudservers.domain.Flavor; +import org.jclouds.cloudservers.functions.ParseFlavorFromJsonResponseTest; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.Processor; import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.VolumeBuilder; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.cloudservers.domain.Flavor; -import org.jclouds.cloudservers.functions.ParseFlavorFromJsonResponseTest; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; @@ -42,20 +42,14 @@ import com.google.common.collect.ImmutableList; */ @Test(groups = "unit") public class FlavorToHardwareTest { - Location provider = new LocationImpl(LocationScope.ZONE, "dallas", "description", null); + Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build(); @Test public void test() throws UnknownHostException { - assertEquals( - convertFlavor(), - new HardwareBuilder() - .ids("1") - .name("256 MB Server") - .processors(ImmutableList.of(new Processor(1.0, 1.0))) - .ram(256) - .volumes( - ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true) - .bootDevice(true).build())).build()); + assertEquals(convertFlavor(), new HardwareBuilder().ids("1").name("256 MB Server").processors( + ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes( + ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true).bootDevice(true) + .build())).build()); } public static Hardware convertFlavor() { diff --git a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadataTest.java b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadataTest.java index 47eb79ddaa..e190a00f0e 100644 --- a/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadataTest.java +++ b/apis/cloudservers/src/test/java/org/jclouds/cloudservers/compute/functions/ServerToNodeMetadataTest.java @@ -25,6 +25,10 @@ import java.net.UnknownHostException; import java.util.Map; import java.util.Set; +import org.jclouds.cloudservers.compute.config.CloudServersComputeServiceDependenciesModule; +import org.jclouds.cloudservers.domain.Server; +import org.jclouds.cloudservers.domain.ServerStatus; +import org.jclouds.cloudservers.functions.ParseServerFromJsonResponseTest; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.HardwareBuilder; import org.jclouds.compute.domain.Image; @@ -38,12 +42,8 @@ import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.VolumeBuilder; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.cloudservers.compute.config.CloudServersComputeServiceDependenciesModule; -import org.jclouds.cloudservers.domain.Server; -import org.jclouds.cloudservers.domain.ServerStatus; -import org.jclouds.cloudservers.functions.ParseServerFromJsonResponseTest; import org.testng.annotations.Test; import com.google.common.base.Suppliers; @@ -56,7 +56,7 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit") public class ServerToNodeMetadataTest { - Location provider = new LocationImpl(LocationScope.ZONE, "dallas", "description", null); + Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build(); @Test public void testApplyWhereImageAndHardwareNotFoundButCredentialsFound() throws UnknownHostException { @@ -68,19 +68,17 @@ public class ServerToNodeMetadataTest { Server server = ParseServerFromJsonResponseTest.parseServer(); ServerToNodeMetadata parser = new ServerToNodeMetadata(serverStateToNodeState, ImmutableMap - . of("node#1234", creds), Suppliers.> ofInstance(images), Suppliers - .ofInstance(provider), Suppliers.> ofInstance(hardwares)); + . of("node#1234", creds), Suppliers.> ofInstance(images), + Suppliers.ofInstance(provider), Suppliers.> ofInstance(hardwares)); NodeMetadata metadata = parser.apply(server); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag( - "NOTAG#sample-server").imageId("2").id("1234").providerId("1234").name("sample-server").credentials( - creds).location( - new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0", - "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas", - "description", null))).userMetadata( - ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); + ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")) + .imageId("2").id("1234").providerId("1234").name("sample-server").credentials(creds).location( + new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0") + .description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build()) + .userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); } @Test @@ -97,12 +95,11 @@ public class ServerToNodeMetadataTest { NodeMetadata metadata = parser.apply(server); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag( - "NOTAG#sample-server").imageId("2").id("1234").providerId("1234").name("sample-server").location( - new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0", - "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas", - "description", null))).userMetadata( - ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); + ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")) + .imageId("2").id("1234").providerId("1234").name("sample-server").location( + new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0") + .description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build()) + .userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); } @@ -121,14 +118,13 @@ public class ServerToNodeMetadataTest { NodeMetadata metadata = parser.apply(server); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag( - "NOTAG#sample-server").imageId("2").operatingSystem( - new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit( - true).build()).id("1234").providerId("1234").name("sample-server").location( - new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0", - "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas", - "description", null))).userMetadata( - ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); + ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")) + .imageId("2").operatingSystem( + new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2") + .is64Bit(true).build()).id("1234").providerId("1234").name("sample-server").location( + new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0") + .description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build()) + .userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); } @@ -146,17 +142,16 @@ public class ServerToNodeMetadataTest { NodeMetadata metadata = parser.apply(server); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")).tag( - "NOTAG#sample-server").imageId("2").hardware( - new HardwareBuilder().ids("1").name("256 MB Server").processors( - ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes( - ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true) - .bootDevice(true).build())).build()).operatingSystem( - new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2").is64Bit( - true).build()).id("1234").providerId("1234").name("sample-server").location( - new LocationImpl(LocationScope.HOST, "e4d909c290d0fb1ca068ffaddf22cbd0", - "e4d909c290d0fb1ca068ffaddf22cbd0", new LocationImpl(LocationScope.ZONE, "dallas", - "description", null))).userMetadata( - ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); + ImmutableSet.of("67.23.10.132", "67.23.10.131")).privateAddresses(ImmutableSet.of("10.176.42.16")) + .imageId("2").hardware( + new HardwareBuilder().ids("1").name("256 MB Server").processors( + ImmutableList.of(new Processor(1.0, 1.0))).ram(256).volumes( + ImmutableList.of(new VolumeBuilder().type(Volume.Type.LOCAL).size(10.0f).durable(true) + .bootDevice(true).build())).build()).operatingSystem( + new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2") + .is64Bit(true).build()).id("1234").providerId("1234").name("sample-server").location( + new LocationBuilder().scope(LocationScope.HOST).id("e4d909c290d0fb1ca068ffaddf22cbd0") + .description("e4d909c290d0fb1ca068ffaddf22cbd0").parent(provider).build()) + .userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); } } diff --git a/demos/createlamp/README.txt b/apis/ec2/README.txt old mode 100755 new mode 100644 similarity index 61% rename from demos/createlamp/README.txt rename to apis/ec2/README.txt index e0f3656a75..92364d368a --- a/demos/createlamp/README.txt +++ b/apis/ec2/README.txt @@ -18,9 +18,8 @@ ==== # -# this is a simple example command line client that creates a lamp server and everything you need to do that in ec2 -# 1. execute 'mvn install' to build the sample -# 2. invoke the jar, passing your aws credentials and the name you wish to create or destroy -# ex. -# java -jar target/jclouds-aws-demo-createlamp-jar-with-dependencies.jar accesskey secretkey create adrianalmighty -# java -jar target/jclouds-aws-demo-createlamp-jar-with-dependencies.jar accesskey secretkey destroy adrianalmighty +# The jclouds API for Amazon's EC2 service (http://aws.amazon.com/ec2/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/ec2/pom.xml b/apis/ec2/pom.xml index e4ce128ad0..50d5ccff0d 100644 --- a/apis/ec2/pom.xml +++ b/apis/ec2/pom.xml @@ -82,6 +82,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java index b35b176d6a..4d775e5319 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2AsyncClient.java @@ -25,8 +25,6 @@ import org.jclouds.ec2.services.ElasticBlockStoreAsyncClient; import org.jclouds.ec2.services.ElasticIPAddressAsyncClient; import org.jclouds.ec2.services.InstanceAsyncClient; import org.jclouds.ec2.services.KeyPairAsyncClient; -import org.jclouds.ec2.services.MonitoringAsyncClient; -import org.jclouds.ec2.services.PlacementGroupAsyncClient; import org.jclouds.ec2.services.SecurityGroupAsyncClient; import org.jclouds.ec2.services.WindowsAsyncClient; import org.jclouds.rest.annotations.Delegate; @@ -69,18 +67,6 @@ public interface EC2AsyncClient { @Delegate SecurityGroupAsyncClient getSecurityGroupServices(); - /** - * Provides asynchronous access to PlacementGroup services. - */ - @Delegate - PlacementGroupAsyncClient getPlacementGroupServices(); - - /** - * Provides asynchronous access to Monitoring services. - */ - @Delegate - MonitoringAsyncClient getMonitoringServices(); - /** * Provides asynchronous access to Windows services. */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java index f02e5cf528..d7f7e175e2 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2Client.java @@ -21,17 +21,15 @@ package org.jclouds.ec2; import java.util.concurrent.TimeUnit; +import org.jclouds.concurrent.Timeout; import org.jclouds.ec2.services.AMIClient; import org.jclouds.ec2.services.AvailabilityZoneAndRegionClient; import org.jclouds.ec2.services.ElasticBlockStoreClient; import org.jclouds.ec2.services.ElasticIPAddressClient; import org.jclouds.ec2.services.InstanceClient; import org.jclouds.ec2.services.KeyPairClient; -import org.jclouds.ec2.services.MonitoringClient; -import org.jclouds.ec2.services.PlacementGroupClient; import org.jclouds.ec2.services.SecurityGroupClient; import org.jclouds.ec2.services.WindowsClient; -import org.jclouds.concurrent.Timeout; import org.jclouds.rest.annotations.Delegate; /** @@ -71,18 +69,6 @@ public interface EC2Client { @Delegate SecurityGroupClient getSecurityGroupServices(); - /** - * Provides synchronous access to PlacementGroup services. - */ - @Delegate - PlacementGroupClient getPlacementGroupServices(); - - /** - * Provides synchronous access to Monitoring services. - */ - @Delegate - MonitoringClient getMonitoringServices(); - /** * Provides asynchronous access to Windows services. */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java index 1237e31c11..8a4c5f32e9 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2ContextBuilder.java @@ -63,7 +63,7 @@ public class EC2ContextBuilder extends ComputeServiceContextBuilder modules) { - modules.add(new EC2RestClientModule()); + modules.add(EC2RestClientModule.create()); } @Override diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java b/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java index 21433ebd5f..92f02e6b47 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/EC2PropertiesBuilder.java @@ -20,11 +20,9 @@ package org.jclouds.ec2; import static org.jclouds.Constants.PROPERTY_API_VERSION; -import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import java.util.Properties; @@ -41,10 +39,8 @@ public class EC2PropertiesBuilder extends PropertiesBuilder { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_AUTH_TAG, "AWS"); properties.setProperty(PROPERTY_HEADER_TAG, "amz"); - properties.setProperty(PROPERTY_ENDPOINT, "https://ec2.us-east-1.amazonaws.com"); properties.setProperty(PROPERTY_API_VERSION, EC2AsyncClient.VERSION); properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "*"); - properties.setProperty(PROPERTY_EC2_CC_AMIs, ""); return properties; } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java index 044cf0bdbe..8d558c79ca 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/binders/BindBlockDeviceMappingToIndexedFormParams.java @@ -45,10 +45,10 @@ public class BindBlockDeviceMappingToIndexedFormParams implements Binder { private static final String volumeIdPattern = "BlockDeviceMapping.%d.Ebs.VolumeId"; private static final String deleteOnTerminationPattern = "BlockDeviceMapping.%d.Ebs.DeleteOnTermination"; + @SuppressWarnings("unchecked") @Override public R bindToRequest(R request, Object input) { checkArgument(checkNotNull(input, "input") instanceof Map, "this binder is only valid for Map"); - @SuppressWarnings("unchecked") Map blockDeviceMapping = (Map) input; com.google.common.collect.ImmutableMap.Builder builder = ImmutableMap. builder(); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java index 3481944a91..9a83767055 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java @@ -19,8 +19,6 @@ package org.jclouds.ec2.compute; -import static com.google.common.base.Preconditions.checkState; - import java.util.Map; import java.util.Set; import java.util.Map.Entry; @@ -32,7 +30,6 @@ import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.Constants; -import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.util.AWSUtils; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceContext; @@ -49,7 +46,7 @@ import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; @@ -58,9 +55,6 @@ import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.jclouds.ec2.domain.KeyPair; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; -import org.jclouds.http.HttpResponseException; import org.jclouds.util.Preconditions2; import com.google.common.annotations.VisibleForTesting; @@ -76,14 +70,12 @@ public class EC2ComputeService extends BaseComputeService { private final EC2Client ec2Client; private final Map credentialsMap; private final Map securityGroupMap; - private final Map placementGroupMap; - private final Predicate placementGroupDeleted; @Inject protected EC2ComputeService(ComputeServiceContext context, Map credentialStore, @Memoized Supplier> images, @Memoized Supplier> sizes, @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, + GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy, Provider templateBuilderProvider, Provider templateOptionsProvider, @@ -92,9 +84,7 @@ public class EC2ComputeService extends BaseComputeService { @Named("NODE_SUSPENDED") Predicate nodeSuspended, InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client, - Map credentialsMap, @Named("SECURITY") Map securityGroupMap, - @Named("PLACEMENT") Map placementGroupMap, - @Named("DELETED") Predicate placementGroupDeleted) { + Map credentialsMap, @Named("SECURITY") Map securityGroupMap) { super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, @@ -102,57 +92,30 @@ public class EC2ComputeService extends BaseComputeService { this.ec2Client = ec2Client; this.credentialsMap = credentialsMap; this.securityGroupMap = securityGroupMap; - this.placementGroupMap = placementGroupMap; - this.placementGroupDeleted = placementGroupDeleted; + } @VisibleForTesting - void deletePlacementGroup(String region, String tag) { - Preconditions2.checkNotEmpty(tag, "tag"); - String group = String.format("jclouds#%s#%s", tag, region); - try { - if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) { - logger.debug(">> deleting placementGroup(%s)", group); - try { - ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group); - checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)), - String.format("placementGroup region(%s) name(%s) failed to delete", region, group)); - placementGroupMap.remove(new RegionAndName(region, group)); - logger.debug("<< deleted placementGroup(%s)", group); - } catch (AWSResponseException e) { - if (e.getError().getCode().equals("InvalidPlacementGroup.InUse")) { - logger.debug("<< inUse placementGroup(%s)", group); - } else { - throw e; - } - } + void deleteSecurityGroup(String region, String group) { + Preconditions2.checkNotEmpty(group, "group"); + String groupName = String.format("jclouds#%s#%s", group, region); + if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, groupName).size() > 0) { + logger.debug(">> deleting securityGroup(%s)", groupName); + try { + ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, groupName); + // TODO: test this clear happens + securityGroupMap.remove(new RegionNameAndIngressRules(region, groupName, null, false)); + logger.debug("<< deleted securityGroup(%s)", groupName); + } catch (IllegalStateException e) { + logger.debug("<< inUse securityGroup(%s)", groupName); } - } catch (UnsupportedOperationException e) { - } catch (HttpResponseException e) { - // Eucalyptus does not support placement groups yet. - if (!(e.getResponse().getStatusCode() == 400 && context.getProviderSpecificContext().getProvider().equals( - "eucalyptus"))) - throw e; } } @VisibleForTesting - void deleteSecurityGroup(String region, String tag) { - Preconditions2.checkNotEmpty(tag, "tag"); - String group = String.format("jclouds#%s#%s", tag, region); - if (ec2Client.getSecurityGroupServices().describeSecurityGroupsInRegion(region, group).size() > 0) { - logger.debug(">> deleting securityGroup(%s)", group); - ec2Client.getSecurityGroupServices().deleteSecurityGroupInRegion(region, group); - // TODO: test this clear happens - securityGroupMap.remove(new RegionNameAndIngressRules(region, group, null, false)); - logger.debug("<< deleted securityGroup(%s)", group); - } - } - - @VisibleForTesting - void deleteKeyPair(String region, String tag) { + void deleteKeyPair(String region, String group) { for (KeyPair keyPair : ec2Client.getKeyPairServices().describeKeyPairsInRegion(region)) { - if (keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", tag, region, "[0-9a-f]+"))) { + if (keyPair.getKeyName().matches(String.format("jclouds#%s#%s#%s", group, region, "[0-9a-f]+"))) { logger.debug(">> deleting keyPair(%s)", keyPair.getKeyName()); ec2Client.getKeyPairServices().deleteKeyPairInRegion(region, keyPair.getKeyName()); // TODO: test this clear happens @@ -171,17 +134,20 @@ public class EC2ComputeService extends BaseComputeService { Set deadOnes = super.destroyNodesMatching(filter); Map regionTags = Maps.newHashMap(); for (NodeMetadata nodeMetadata : deadOnes) { - if (nodeMetadata.getTag() != null) - regionTags.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getTag()); + if (nodeMetadata.getGroup() != null) + regionTags.put(AWSUtils.parseHandle(nodeMetadata.getId())[0], nodeMetadata.getGroup()); } for (Entry regionTag : regionTags.entrySet()) { - deleteKeyPair(regionTag.getKey(), regionTag.getValue()); - deleteSecurityGroup(regionTag.getKey(), regionTag.getValue()); - deletePlacementGroup(regionTag.getKey(), regionTag.getValue()); + cleanUpIncidentalResources(regionTag); } return deadOnes; } + protected void cleanUpIncidentalResources(Entry regionTag) { + deleteKeyPair(regionTag.getKey(), regionTag.getValue()); + deleteSecurityGroup(regionTag.getKey(), regionTag.getValue()); + } + /** * returns template options, except of type {@link EC2TemplateOptions}. */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java index ae05dedee9..48983704a4 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java @@ -23,16 +23,16 @@ import org.jclouds.ec2.compute.strategy.EC2DestroyNodeStrategy; import org.jclouds.ec2.compute.strategy.EC2GetNodeMetadataStrategy; import org.jclouds.ec2.compute.strategy.EC2ListNodesStrategy; import org.jclouds.ec2.compute.strategy.EC2RebootNodeStrategy; -import org.jclouds.ec2.compute.strategy.EC2RunNodesAndAddToSetStrategy; +import org.jclouds.ec2.compute.strategy.EC2CreateNodesInGroupThenAddToSet; import org.jclouds.ec2.compute.strategy.EC2ResumeNodeStrategy; import org.jclouds.ec2.compute.strategy.EC2SuspendNodeStrategy; import org.jclouds.compute.config.BindComputeStrategiesByClass; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; @@ -41,23 +41,23 @@ import org.jclouds.compute.strategy.SuspendNodeStrategy; */ public class EC2BindComputeStrategiesByClass extends BindComputeStrategiesByClass { @Override - protected Class defineRunNodesAndAddToSetStrategy() { - return EC2RunNodesAndAddToSetStrategy.class; + protected Class defineRunNodesAndAddToSetStrategy() { + return EC2CreateNodesInGroupThenAddToSet.class; } /** - * not needed, as {@link EC2RunNodesAndAddToSetStrategy} is used and is already set-based. + * not needed, as {@link EC2CreateNodesInGroupThenAddToSet} is used and is already set-based. */ @Override - protected Class defineAddNodeWithTagStrategy() { + protected Class defineAddNodeWithTagStrategy() { return null; } /** - * not needed, as {@link EC2RunNodesAndAddToSetStrategy} is used and is already set-based. + * not needed, as {@link EC2CreateNodesInGroupThenAddToSet} is used and is already set-based. */ @Override - protected void bindAddNodeWithTagStrategy(Class clazz) { + protected void bindAddNodeWithTagStrategy(Class clazz) { } @Override diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java index 5f6d312820..dc545e3a52 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceContextModule.java @@ -45,11 +45,15 @@ import com.google.inject.Provides; public class EC2ComputeServiceContextModule extends BaseComputeServiceContextModule { @Override protected void configure() { - install(new EC2ComputeServiceDependenciesModule()); + installDependencies(); install(new EC2BindComputeStrategiesByClass()); install(new EC2BindComputeSuppliersByClass()); super.configure(); } + + protected void installDependencies(){ + install(new EC2ComputeServiceDependenciesModule()); + } @Provides @Singleton diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java index 175270982a..6d17a4dddc 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java @@ -22,7 +22,6 @@ package org.jclouds.ec2.compute.config; import static com.google.common.collect.Iterables.toArray; import static com.google.common.collect.Maps.newLinkedHashMap; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import java.security.SecureRandom; import java.util.Map; @@ -31,25 +30,6 @@ import java.util.concurrent.TimeUnit; import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.ec2.EC2AsyncClient; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.compute.EC2ComputeService; -import org.jclouds.ec2.compute.domain.RegionAndName; -import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded; -import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; -import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; -import org.jclouds.ec2.compute.functions.CredentialsForInstance; -import org.jclouds.ec2.compute.functions.RegionAndIdToImage; -import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; -import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; -import org.jclouds.ec2.domain.InstanceState; -import org.jclouds.ec2.domain.KeyPair; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.ec2.predicates.InstancePresent; -import org.jclouds.ec2.predicates.PlacementGroupAvailable; -import org.jclouds.ec2.predicates.PlacementGroupDeleted; import org.jclouds.compute.ComputeService; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.domain.Image; @@ -59,6 +39,21 @@ import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.domain.Credentials; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.ec2.EC2Client; +import org.jclouds.ec2.compute.EC2ComputeService; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.functions.CredentialsForInstance; +import org.jclouds.ec2.compute.functions.RegionAndIdToImage; +import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.predicates.InstancePresent; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.rest.RestContext; import org.jclouds.rest.internal.RestContextImpl; @@ -100,20 +95,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule { return new RetryablePredicate(present, 5000, 200, TimeUnit.MILLISECONDS); } - @Provides - @Singleton - @Named("AVAILABLE") - protected Predicate placementGroupAvailable(PlacementGroupAvailable available) { - return new RetryablePredicate(available, 60, 1, TimeUnit.SECONDS); - } - - @Provides - @Singleton - @Named("DELETED") - protected Predicate placementGroupDeleted(PlacementGroupDeleted deleted) { - return new RetryablePredicate(deleted, 60, 1, TimeUnit.SECONDS); - } - @Override protected void configure() { bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class); @@ -162,14 +143,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule { return newLinkedHashMap(); } - @Provides - @Singleton - @Named("PLACEMENT") - protected final Map placementGroupMap(CreatePlacementGroupIfNeeded in) { - // doesn't seem to clear when someone issues remove(key) - // return new MapMaker().makeComputingMap(in); - return newLinkedHashMap(); - } @Provides @Singleton @@ -180,14 +153,6 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule { return toArray(Splitter.on(',').split(amiOwners), String.class); } - @Provides - @Singleton - @Named(PROPERTY_EC2_CC_AMIs) - String[] ccAmis(@Named(PROPERTY_EC2_CC_AMIs) String ccAmis) { - if (ccAmis.trim().equals("")) - return new String[] {}; - return toArray(Splitter.on(',').split(ccAmis), String.class); - } @Provides @Singleton diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java index a000772aa3..17670dc8bd 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/EC2ImageParser.java @@ -40,12 +40,11 @@ import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.compute.util.ComputeServiceUtils; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.ec2.compute.strategy.ReviseParsedImage; import org.jclouds.ec2.domain.Image.Architecture; import org.jclouds.ec2.domain.Image.ImageType; -import org.jclouds.location.Provider; import org.jclouds.logging.Logger; import com.google.common.base.Function; @@ -66,19 +65,16 @@ public class EC2ImageParser implements Function> locations; private final Supplier defaultLocation; - private final String provider; private final Map> osVersionMap; private final ReviseParsedImage reviseParsedImage; @Inject - public - EC2ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, + public EC2ImageParser(PopulateDefaultLoginCredentialsForImageStrategy credentialProvider, Map> osVersionMap, @Memoized Supplier> locations, - Supplier defaultLocation, @Provider String provider, ReviseParsedImage reviseParsedImage) { + Supplier defaultLocation, ReviseParsedImage reviseParsedImage) { this.credentialProvider = checkNotNull(credentialProvider, "credentialProvider"); this.locations = checkNotNull(locations, "locations"); this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation"); - this.provider = checkNotNull(provider, "provider"); this.osVersionMap = checkNotNull(osVersionMap, "osVersionMap"); this.reviseParsedImage = checkNotNull(reviseParsedImage, "reviseParsedImage"); } @@ -98,7 +94,7 @@ public class EC2ImageParser implements Function() { + group = Iterables.getOnlyElement(Iterables.filter(instance.getGroupIds(), new Predicate() { @Override public boolean apply(String input) { @@ -169,13 +169,13 @@ public class RunningInstanceToNodeMetadata implements Function 0) + eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings()); if (!eFrom.shouldAutomaticallyCreateKeyPair()) eTo.noKeyPair(); - if (eFrom.getSubnetId() != null) - eTo.subnetId(eFrom.getSubnetId()); - eTo.blockDeviceMappings(eFrom.getBlockDeviceMappings()); - if (eFrom.isMonitoringEnabled()) - eTo.enableMonitoring(); if (eFrom.getUserData() != null) eTo.userData(eFrom.getUserData()); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java index be4932c2d4..858575bcc9 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/options/EC2TemplateOptions.java @@ -24,7 +24,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import java.util.Arrays; -import java.util.HashSet; import java.util.Set; import javax.annotation.Nullable; @@ -65,10 +64,6 @@ public class EC2TemplateOptions extends TemplateOptions { private Set groupIds = ImmutableSet.of(); private String keyPair = null; private boolean noKeyPair; - private boolean monitoringEnabled; - private String placementGroup = null; - private boolean noPlacementGroup; - private String subnetId; private byte[] userData; private Set blockDeviceMappings = ImmutableSet.of(); @@ -93,22 +88,12 @@ public class EC2TemplateOptions extends TemplateOptions { return this; } - /** - * Enable Cloudwatch monitoring - * - * @see CloudWatchClient - */ - public EC2TemplateOptions enableMonitoring() { - this.monitoringEnabled = true; - return this; - } - /** * Unencoded data */ public EC2TemplateOptions userData(byte[] unencodedData) { checkArgument(checkNotNull(unencodedData, "unencodedData").length <= 16 * 1024, - "userData cannot be larger than 16kb"); + "userData cannot be larger than 16kb"); this.userData = unencodedData; return this; } @@ -133,68 +118,38 @@ public class EC2TemplateOptions extends TemplateOptions { return this; } - /** - * Specifies the keypair used to run instances with - */ - public EC2TemplateOptions placementGroup(String placementGroup) { - checkNotNull(placementGroup, "use noPlacementGroup option to request boot without a keypair"); - checkState(!noPlacementGroup, "you cannot specify both options placementGroup and noPlacementGroup"); - Preconditions2.checkNotEmpty(placementGroup, "placementGroup must be non-empty"); - this.placementGroup = placementGroup; - return this; - } - - /** - * Do not use a keypair on instances - */ - public EC2TemplateOptions noPlacementGroup() { - checkState(placementGroup == null, "you cannot specify both options placementGroup and noPlacementGroup"); - this.noPlacementGroup = true; - return this; - } - - /** - * Specifies the subnetId used to run instances in - */ - public EC2TemplateOptions subnetId(String subnetId) { - checkNotNull(subnetId, "subnetId cannot be null"); - Preconditions2.checkNotEmpty(subnetId, "subnetId must be non-empty"); - this.subnetId = subnetId; - return this; - } - /** * Specifies the block device mappings to be used to run the instance */ public EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId, - @Nullable Integer sizeInGib, @Nullable Boolean deleteOnTermination) { + @Nullable Integer sizeInGib, boolean deleteOnTermination) { checkNotNull(deviceName, "deviceName cannot be null"); Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty"); checkNotNull(snapshotId, "snapshotId cannot be null"); Preconditions2.checkNotEmpty(snapshotId, "snapshotId must be non-empty"); - Set mappings = new HashSet(); + com.google.common.collect.ImmutableSet.Builder mappings = ImmutableSet + . builder(); mappings.addAll(blockDeviceMappings); MapEBSSnapshotToDevice mapping = new MapEBSSnapshotToDevice(deviceName, snapshotId, sizeInGib, - deleteOnTermination); + deleteOnTermination); mappings.add(mapping); - blockDeviceMappings = ImmutableSet.copyOf(mappings); + blockDeviceMappings = mappings.build(); return this; } /** * Specifies the block device mappings to be used to run the instance */ - public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, Integer sizeInGib, - @Nullable Boolean deleteOnTermination) { + public EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, boolean deleteOnTermination) { checkNotNull(deviceName, "deviceName cannot be null"); Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty"); - checkNotNull(sizeInGib, "sizeInGib cannot be null"); - Set mappings = new HashSet(); + com.google.common.collect.ImmutableSet.Builder mappings = ImmutableSet + . builder(); mappings.addAll(blockDeviceMappings); MapNewVolumeToDevice mapping = new MapNewVolumeToDevice(deviceName, sizeInGib, deleteOnTermination); mappings.add(mapping); - blockDeviceMappings = ImmutableSet.copyOf(mappings); + blockDeviceMappings = mappings.build(); return this; } @@ -207,11 +162,12 @@ public class EC2TemplateOptions extends TemplateOptions { checkNotNull(virtualName, "virtualName cannot be null"); Preconditions2.checkNotEmpty(virtualName, "virtualName must be non-empty"); - Set mappings = new HashSet(); + com.google.common.collect.ImmutableSet.Builder mappings = ImmutableSet + . builder(); mappings.addAll(blockDeviceMappings); MapEphemeralDeviceToDevice mapping = new MapEphemeralDeviceToDevice(deviceName, virtualName); mappings.add(mapping); - blockDeviceMappings = ImmutableSet.copyOf(mappings); + blockDeviceMappings = mappings.build(); return this; } @@ -222,11 +178,12 @@ public class EC2TemplateOptions extends TemplateOptions { checkNotNull(deviceName, "deviceName cannot be null"); Preconditions2.checkNotEmpty(deviceName, "deviceName must be non-empty"); - Set mappings = new HashSet(); + com.google.common.collect.ImmutableSet.Builder mappings = ImmutableSet + . builder(); mappings.addAll(blockDeviceMappings); UnmapDeviceNamed mapping = new UnmapDeviceNamed(deviceName); mappings.add(mapping); - blockDeviceMappings = ImmutableSet.copyOf(mappings); + blockDeviceMappings = mappings.build(); return this; } @@ -239,6 +196,47 @@ public class EC2TemplateOptions extends TemplateOptions { } public static class Builder { + /** + * @see EC2TemplateOptions#blockDeviceMappings + */ + public static EC2TemplateOptions blockDeviceMappings(Set blockDeviceMappings) { + EC2TemplateOptions options = new EC2TemplateOptions(); + return options.blockDeviceMappings(blockDeviceMappings); + } + + /** + * @see EC2TemplateOptions#mapEBSSnapshotToDeviceName + */ + public static EC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId, + @Nullable Integer sizeInGib, boolean deleteOnTermination) { + EC2TemplateOptions options = new EC2TemplateOptions(); + return options.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib, deleteOnTermination); + } + + /** + * @see EC2TemplateOptions#mapNewVolumeToDeviceName + */ + public static EC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, + boolean deleteOnTermination) { + EC2TemplateOptions options = new EC2TemplateOptions(); + return options.mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination); + } + + /** + * @see EC2TemplateOptions#mapEphemeralDeviceToDeviceName + */ + public static EC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) { + EC2TemplateOptions options = new EC2TemplateOptions(); + return options.mapEphemeralDeviceToDeviceName(deviceName, virtualName); + } + + /** + * @see EC2TemplateOptions#unmapDeviceNamed + */ + public static EC2TemplateOptions unmapDeviceNamed(String deviceName) { + EC2TemplateOptions options = new EC2TemplateOptions(); + return options.unmapDeviceNamed(deviceName); + } /** * @see EC2TemplateOptions#securityGroups(Iterable) @@ -280,30 +278,6 @@ public class EC2TemplateOptions extends TemplateOptions { return EC2TemplateOptions.class.cast(options.noKeyPair()); } - /** - * @see EC2TemplateOptions#placementGroup - */ - public static EC2TemplateOptions placementGroup(String placementGroup) { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.placementGroup(placementGroup)); - } - - /** - * @see EC2TemplateOptions#noPlacementGroup - */ - public static EC2TemplateOptions noPlacementGroup() { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.noPlacementGroup()); - } - - /** - * @see EC2TemplateOptions#enableMonitoring - */ - public static EC2TemplateOptions enableMonitoring() { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.enableMonitoring()); - } - // methods that only facilitate returning the correct object type /** * @see TemplateOptions#inboundPorts @@ -353,13 +327,6 @@ public class EC2TemplateOptions extends TemplateOptions { return EC2TemplateOptions.class.cast(options.withMetadata()); } - /** - * @see TemplateOptions#withSubnetId - */ - public static EC2TemplateOptions subnetId(String subnetId) { - EC2TemplateOptions options = new EC2TemplateOptions(); - return EC2TemplateOptions.class.cast(options.subnetId(subnetId)); - } } // methods that only facilitate returning the correct object type @@ -509,34 +476,6 @@ public class EC2TemplateOptions extends TemplateOptions { return !noKeyPair; } - /** - * @return placementGroup to use when running the instance or null, to generate a placementGroup. - */ - public String getPlacementGroup() { - return placementGroup; - } - - /** - * @return true (default) if we are supposed to use a placementGroup - */ - public boolean shouldAutomaticallyCreatePlacementGroup() { - return !noPlacementGroup; - } - - /** - * @return true (default) if we are supposed to enable cloudwatch - */ - public boolean isMonitoringEnabled() { - return monitoringEnabled; - } - - /** - * @return subnetId to use when running the instance or null. - */ - public String getSubnetId() { - return subnetId; - } - /** * @return unencoded user data. */ @@ -559,11 +498,7 @@ public class EC2TemplateOptions extends TemplateOptions { result = prime * result + ((blockDeviceMappings == null) ? 0 : blockDeviceMappings.hashCode()); result = prime * result + ((groupIds == null) ? 0 : groupIds.hashCode()); result = prime * result + ((keyPair == null) ? 0 : keyPair.hashCode()); - result = prime * result + (monitoringEnabled ? 1231 : 1237); result = prime * result + (noKeyPair ? 1231 : 1237); - result = prime * result + (noPlacementGroup ? 1231 : 1237); - result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); - result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); result = prime * result + Arrays.hashCode(userData); return result; } @@ -592,22 +527,7 @@ public class EC2TemplateOptions extends TemplateOptions { return false; } else if (!keyPair.equals(other.keyPair)) return false; - if (monitoringEnabled != other.monitoringEnabled) - return false; - if (noKeyPair != other.noKeyPair) - return false; - if (noPlacementGroup != other.noPlacementGroup) - return false; - if (placementGroup == null) { - if (other.placementGroup != null) - return false; - } else if (!placementGroup.equals(other.placementGroup)) - return false; - if (subnetId == null) { - if (other.subnetId != null) - return false; - } else if (!subnetId.equals(other.subnetId)) - return false; + if (!Arrays.equals(userData, other.userData)) return false; @@ -616,11 +536,7 @@ public class EC2TemplateOptions extends TemplateOptions { @Override public String toString() { - - return "EC2TemplateOptions [groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair - + ", monitoringEnabled=" + monitoringEnabled + ", placementGroup=" + placementGroup + ", noPlacementGroup=" - + noPlacementGroup + ", subnetId=" + subnetId + ", userData=" + Arrays.toString(userData) - + ", blockDeviceMappings=" + blockDeviceMappings + "]"; + return "[groupIds=" + groupIds + ", keyPair=" + keyPair + ", noKeyPair=" + noKeyPair + ", userData=" + + Arrays.toString(userData) + ", blockDeviceMappings=" + blockDeviceMappings + "]"; } - } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java new file mode 100644 index 0000000000..26b35e34e7 --- /dev/null +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -0,0 +1,166 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.ec2.compute.strategy; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.options.RunInstancesOptions; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.Sets; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { + + @VisibleForTesting + public final Map credentialsMap; + @VisibleForTesting + public final Map securityGroupMap; + @VisibleForTesting + public final CreateUniqueKeyPair createUniqueKeyPair; + @VisibleForTesting + public final CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded; + private final javax.inject.Provider optionsProvider; + + @Inject + public CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(Map credentialsMap, + @Named("SECURITY") Map securityGroupMap, CreateUniqueKeyPair createUniqueKeyPair, + CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded, + javax.inject.Provider optionsProvider) { + this.credentialsMap = credentialsMap; + this.securityGroupMap = securityGroupMap; + this.createUniqueKeyPair = createUniqueKeyPair; + this.createSecurityGroupIfNeeded = createSecurityGroupIfNeeded; + this.optionsProvider = optionsProvider; + } + + public RunInstancesOptions execute(String region, String tag, Template template) { + + RunInstancesOptions instanceOptions = getOptionsProvider().get().asType(template.getHardware().getId()); + + String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, template.getOptions()); + + addSecurityGroups(region, tag, template, instanceOptions); + if (template.getOptions() instanceof EC2TemplateOptions) { + + if (keyPairName != null) + instanceOptions.withKeyName(keyPairName); + + byte[] userData = EC2TemplateOptions.class.cast(template.getOptions()).getUserData(); + + if (userData != null) + instanceOptions.withUserData(userData); + + Set blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions()) + .getBlockDeviceMappings(); + if (blockDeviceMappings.size() > 0) { + checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")), + "BlockDeviceMapping only available on ebs boot"); + instanceOptions.withBlockDeviceMappings(blockDeviceMappings); + } + } + return instanceOptions; + } + + protected void addSecurityGroups(String region, String tag, Template template, RunInstancesOptions instanceOptions) { + Set groups = getSecurityGroupsForTagAndOptions(region, tag, template.getOptions()); + instanceOptions.withSecurityGroups(groups); + } + + @VisibleForTesting + public String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { + String keyPairName = null; + boolean shouldAutomaticallyCreateKeyPair = true; + if (options instanceof EC2TemplateOptions) { + keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair(); + if (keyPairName == null) + shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options) + .shouldAutomaticallyCreateKeyPair(); + } + if (keyPairName == null && shouldAutomaticallyCreateKeyPair) { + RegionAndName regionAndName = new RegionAndName(region, tag); + KeyPair keyPair = createUniqueKeyPair.apply(regionAndName); + // get or create incidental resources + // TODO race condition. we were using MapMaker, but it doesn't seem to + // refresh properly + // when + // another thread + // deletes a key + credentialsMap.put(new RegionAndName(region, keyPair.getKeyName()), keyPair); + keyPairName = keyPair.getKeyName(); + } + return keyPairName; + } + + @VisibleForTesting + public Set getSecurityGroupsForTagAndOptions(String region, @Nullable String tag, TemplateOptions options) { + Set groups = Sets.newLinkedHashSet(); + + if (tag != null) { + String markerGroup = String.format("jclouds#%s#%s", tag, region); + groups.add(markerGroup); + + RegionNameAndIngressRules regionNameAndIngessRulesForMarkerGroup; + + if (options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroupIds().size() > 0) { + regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {}, + false); + groups.addAll(EC2TemplateOptions.class.cast(options).getGroupIds()); + + } else { + regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, options + .getInboundPorts(), true); + } + + if (!securityGroupMap.containsKey(regionNameAndIngessRulesForMarkerGroup)) { + securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup, createSecurityGroupIfNeeded + .apply(regionNameAndIngessRulesForMarkerGroup)); + } + } + return groups; + } + + // allows us to mock this method + @VisibleForTesting + public javax.inject.Provider getOptionsProvider() { + return optionsProvider; + } +} \ No newline at end of file diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java deleted file mode 100644 index 6da51f0e16..0000000000 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java +++ /dev/null @@ -1,201 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.ec2.compute.strategy; - -import static com.google.common.base.Preconditions.checkState; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType; - -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.options.TemplateOptions; -import org.jclouds.ec2.compute.domain.RegionAndName; -import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; -import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded; -import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; -import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; -import org.jclouds.ec2.domain.BlockDeviceMapping; -import org.jclouds.ec2.domain.KeyPair; -import org.jclouds.ec2.options.RunInstancesOptions; -import org.jclouds.location.Provider; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.Sets; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions { - @VisibleForTesting - final String provider; - @VisibleForTesting - final Map credentialsMap; - @VisibleForTesting - final Map securityGroupMap; - @VisibleForTesting - final Map placementGroupMap; - @VisibleForTesting - final CreateUniqueKeyPair createUniqueKeyPair; - @VisibleForTesting - final CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded; - @VisibleForTesting - final CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded; - - @Inject - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(@Provider String provider, - Map credentialsMap, @Named("SECURITY") Map securityGroupMap, - @Named("PLACEMENT") Map placementGroupMap, CreateUniqueKeyPair createUniqueKeyPair, - CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded, - CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded) { - this.provider = provider; - this.credentialsMap = credentialsMap; - this.securityGroupMap = securityGroupMap; - this.placementGroupMap = placementGroupMap; - this.createUniqueKeyPair = createUniqueKeyPair; - this.createSecurityGroupIfNeeded = createSecurityGroupIfNeeded; - this.createPlacementGroupIfNeeded = createPlacementGroupIfNeeded; - } - - // this method only exists so that we can mock - String getProvider() { - return provider; - } - - public RunInstancesOptions execute(String region, String tag, Template template) { - - RunInstancesOptions instanceOptions = asType(template.getHardware().getId()); - - String keyPairName = createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, template.getOptions()); - - String placementGroupName = template.getHardware().getId().startsWith("cc") ? createNewPlacementGroupUnlessUserSpecifiedOtherwise( - region, tag, template.getOptions()) : null; - - String subnetId = EC2TemplateOptions.class.cast(template.getOptions()).getSubnetId(); - - if (subnetId != null) { - instanceOptions.withSubnetId(subnetId); - } else { - Set groups = getSecurityGroupsForTagAndOptions(region, tag, template.getOptions()); - instanceOptions.withSecurityGroups(groups); - } - - if (keyPairName != null) - instanceOptions.withKeyName(keyPairName); - - if (placementGroupName != null) - instanceOptions.inPlacementGroup(placementGroupName); - - byte[] userData = EC2TemplateOptions.class.cast(template.getOptions()).getUserData(); - - if (userData != null) - instanceOptions.withUserData(userData); - - Set blockDeviceMappings = EC2TemplateOptions.class.cast(template.getOptions()) - .getBlockDeviceMappings(); - if (blockDeviceMappings != null && blockDeviceMappings.size() > 0) { - checkState("ebs".equals(template.getImage().getUserMetadata().get("rootDeviceType")), - "BlockDeviceMapping only available on ebs boot"); - instanceOptions.withBlockDeviceMappings(blockDeviceMappings); - } - return instanceOptions; - } - - @VisibleForTesting - String createNewKeyPairUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { - String keyPairName = null; - boolean shouldAutomaticallyCreateKeyPair = true; - if (options instanceof EC2TemplateOptions) { - keyPairName = EC2TemplateOptions.class.cast(options).getKeyPair(); - if (keyPairName == null) - shouldAutomaticallyCreateKeyPair = EC2TemplateOptions.class.cast(options) - .shouldAutomaticallyCreateKeyPair(); - } - if (keyPairName == null && shouldAutomaticallyCreateKeyPair) { - RegionAndName regionAndName = new RegionAndName(region, tag); - KeyPair keyPair = createUniqueKeyPair.apply(regionAndName); - // get or create incidental resources - // TODO race condition. we were using MapMaker, but it doesn't seem to - // refresh properly - // when - // another thread - // deletes a key - credentialsMap.put(new RegionAndName(region, keyPair.getKeyName()), keyPair); - keyPairName = keyPair.getKeyName(); - } - return keyPairName; - } - - @VisibleForTesting - String createNewPlacementGroupUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { - String placementGroupName = null; - boolean shouldAutomaticallyCreatePlacementGroup = true; - if (options instanceof EC2TemplateOptions) { - placementGroupName = EC2TemplateOptions.class.cast(options).getPlacementGroup(); - if (placementGroupName == null) - shouldAutomaticallyCreatePlacementGroup = EC2TemplateOptions.class.cast(options) - .shouldAutomaticallyCreatePlacementGroup(); - } - if (placementGroupName == null && shouldAutomaticallyCreatePlacementGroup) { - placementGroupName = String.format("jclouds#%s#%s", tag, region); - RegionAndName regionAndName = new RegionAndName(region, placementGroupName); - if (!placementGroupMap.containsKey(regionAndName)) { - placementGroupMap.put(regionAndName, createPlacementGroupIfNeeded.apply(regionAndName)); - } - } - return placementGroupName; - } - - @VisibleForTesting - Set getSecurityGroupsForTagAndOptions(String region, @Nullable String tag, TemplateOptions options) { - Set groups = Sets.newLinkedHashSet(); - - if (tag != null) { - String markerGroup = String.format("jclouds#%s#%s", tag, region); - groups.add(markerGroup); - - RegionNameAndIngressRules regionNameAndIngessRulesForMarkerGroup; - - if (options instanceof EC2TemplateOptions && EC2TemplateOptions.class.cast(options).getGroupIds().size() > 0) { - regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, new int[] {}, - false); - groups.addAll(EC2TemplateOptions.class.cast(options).getGroupIds()); - - } else { - regionNameAndIngessRulesForMarkerGroup = new RegionNameAndIngressRules(region, markerGroup, - options.getInboundPorts(), true); - } - - if (!securityGroupMap.containsKey(regionNameAndIngessRulesForMarkerGroup)) { - securityGroupMap.put(regionNameAndIngessRulesForMarkerGroup, - createSecurityGroupIfNeeded.apply(regionNameAndIngessRulesForMarkerGroup)); - } - } - return groups; - } -} \ No newline at end of file diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategy.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java similarity index 65% rename from apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategy.java rename to apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java index 6d44e28fe2..f81f840693 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategy.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java @@ -38,12 +38,10 @@ import org.jclouds.compute.config.CustomizationResponse; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.util.ComputeUtils; import org.jclouds.domain.Credentials; import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; -import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RunningInstance; import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.logging.Logger; @@ -52,6 +50,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; @@ -61,7 +60,7 @@ import com.google.common.collect.Multimap; * @author Adrian Cole */ @Singleton -public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy { +public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThenAddToSet { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -70,7 +69,7 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate @VisibleForTesting final EC2Client client; @VisibleForTesting - final CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize; + final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize; @VisibleForTesting final Function runningInstanceToNodeMetadata; @VisibleForTesting @@ -80,9 +79,9 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate final Map credentialStore; @Inject - EC2RunNodesAndAddToSetStrategy( + EC2CreateNodesInGroupThenAddToSet( EC2Client client, - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, @Named("PRESENT") Predicate instancePresent, Function runningInstanceToNodeMetadata, Function instanceToCredentials, Map credentialStore, @@ -97,52 +96,65 @@ public class EC2RunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrate } @Override - public Map> execute(String tag, int count, Template template, Set goodNodes, + public Map> execute(String group, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses) { - Reservation reservation = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(tag, - count, template); - - Iterable ids = transform(reservation, instanceToId); + Iterable started = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(group, count, + template); + Iterable ids = transform(started, instanceToId); String idsString = Joiner.on(',').join(ids); if (Iterables.size(ids) > 0) { logger.debug("<< started instances(%s)", idsString); - all(reservation, instancePresent); + all(started, instancePresent); logger.debug("<< present instances(%s)", idsString); - populateCredentials(reservation); + populateCredentials(started); } - return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(reservation, + return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(template.getOptions(), transform(started, runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses); } - protected void populateCredentials(Reservation reservation) { - RunningInstance instance1 = Iterables.get(reservation, 0); - Credentials credentials = instanceToCredentials.apply(instance1); + protected void populateCredentials(Iterable started) { + Credentials credentials = null; + for (RunningInstance instance : started) { + credentials = instanceToCredentials.apply(instance); + if (credentials != null) + break; + } if (credentials != null) - for (RunningInstance instance : reservation) + for (RunningInstance instance : started) credentialStore.put("node#" + instance.getRegion() + "/" + instance.getId(), credentials); + } + // TODO write test for this @VisibleForTesting - Reservation createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String tag, int count, + Iterable createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String group, int count, Template template) { String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation()); String zone = getZoneFromLocationOrNull(template.getLocation()); RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region, - tag, template); + group, template); - if (EC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled()) - instanceOptions.enableMonitoring(); + int countStarted = 0; + int tries = 0; + Iterable started = ImmutableSet. of(); - if (logger.isDebugEnabled()) - logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count, region, zone, template - .getImage().getProviderId(), instanceOptions.buildFormParameters()); + while (countStarted < count && tries++ < count) { + if (logger.isDebugEnabled()) + logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count - countStarted, region, + zone, template.getImage().getProviderId(), instanceOptions.buildFormParameters()); - return client.getInstanceServices().runInstancesInRegion(region, zone, template.getImage().getProviderId(), 1, - count, instanceOptions); + started = Iterables.concat(started, client.getInstanceServices().runInstancesInRegion(region, zone, + template.getImage().getProviderId(), 1, count - countStarted, instanceOptions)); + + countStarted = Iterables.size(started); + if (countStarted < count) + logger.debug(">> not enough instances (%d/%d) started, attempting again", countStarted, count); + } + return started; } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java index 6c2efe2617..73d6585cee 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java @@ -81,12 +81,13 @@ public class EC2ListNodesStrategy implements ListNodesStrategy { @Override public Set listDetailsOnNodesMatching(Predicate filter) { - Iterable>> reservations = transformParallel( + Iterable>> reservations = transformParallel( regions, new Function>>>() { + @SuppressWarnings("unchecked") @Override public Future>> apply(String from) { - return client.getInstanceServices().describeInstancesInRegion(from); + return (Future>>) client.getInstanceServices().describeInstancesInRegion(from); } }, executor, null, logger, "reservations"); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java index 8f9608149c..8e79dca5eb 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java @@ -19,37 +19,19 @@ package org.jclouds.ec2.compute.suppliers; -import static com.google.common.collect.Iterables.find; -import static com.google.common.collect.Sets.newLinkedHashSet; +import static org.jclouds.compute.predicates.ImagePredicates.any; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small; import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_xlarge; -import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.t1_micro; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; -import static org.jclouds.compute.predicates.ImagePredicates.any; import java.util.Set; -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.location.Provider; -import org.jclouds.logging.Logger; -import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; @@ -59,41 +41,10 @@ import com.google.common.collect.ImmutableSet; */ @Singleton public class EC2HardwareSupplier implements Supplier> { - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - private final Supplier> locations; - private final String[] ccAmis; - private final String providerName; - - @Inject - EC2HardwareSupplier(@Memoized Supplier> locations, @Provider String providerName, - @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis) { - this.locations = locations; - this.ccAmis = ccAmis; - this.providerName = providerName; - } @Override public Set get() { - Set sizes = newLinkedHashSet(); - for (String ccAmi : ccAmis) { - final String region = ccAmi.split("/")[0]; - Location location = find(locations.get(), new Predicate() { - - @Override - public boolean apply(Location input) { - return input.getScope() == LocationScope.REGION && input.getId().equals(region); - } - - }); - sizes.add(cc1_4xlarge().location(location).supportsImageIds(ccAmi).build()); - } - // TODO move logic to dependent module - sizes.addAll(ImmutableSet. of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large() - .build(), - !"aws-ec2".equals(providerName) ? m1_small().supportsImage(any()).build() : m1_small().build(), - m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(), m2_4xlarge().build())); - return sizes; + return ImmutableSet. of(m1_small().supportsImage(any()).build(), c1_medium().build(), c1_xlarge() + .build(), m1_large().build(), m1_xlarge().build()); } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java index c1df66b9ff..423894b6a6 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java @@ -38,31 +38,27 @@ package org.jclouds.ec2.compute.suppliers; * ==================================================================== */ -import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.transform; -import static com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Maps.uniqueIndex; -import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds; import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.ownedBy; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; +import java.util.Map.Entry; import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.functions.EC2ImageParser; import org.jclouds.ec2.compute.strategy.DescribeImagesParallel; import org.jclouds.ec2.options.DescribeImagesOptions; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.location.Region; import org.jclouds.logging.Logger; @@ -84,18 +80,15 @@ public class RegionAndNameToImageSupplier implements Supplier regions; private final DescribeImagesParallel describer; - private final String[] ccAmis; private final String[] amiOwners; private final EC2ImageParser parser; private final Map images; @Inject - RegionAndNameToImageSupplier(@Region Set regions, DescribeImagesParallel describer, - @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis, @Named(PROPERTY_EC2_AMI_OWNERS) final String[] amiOwners, - final EC2ImageParser parser, final Map images) { + protected RegionAndNameToImageSupplier(@Region Set regions, DescribeImagesParallel describer, + @Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, EC2ImageParser parser, Map images) { this.regions = regions; this.describer = describer; - this.ccAmis = ccAmis; this.amiOwners = amiOwners; this.parser = parser; this.images = images; @@ -108,12 +101,11 @@ public class RegionAndNameToImageSupplier implements Supplier> providing images"); - Iterable> queries = concat( - getDescribeQueriesForOwnersInRegions(regions, amiOwners).entrySet(), ccAmisToDescribeQueries(ccAmis) - .entrySet()); + Iterable> queries = getDescribeQueriesForOwnersInRegions(regions, + amiOwners); - Iterable parsedImages = filter(transform(describer.apply(queries), parser), - Predicates.notNull()); + Iterable parsedImages = filter(transform(describer.apply(queries), parser), Predicates + .notNull()); images.putAll(uniqueIndex(parsedImages, new Function() { @@ -129,24 +121,16 @@ public class RegionAndNameToImageSupplier implements Supplier ccAmisToDescribeQueries(String[] ccAmis) { - Map queries = newLinkedHashMap(); - for (String from : ccAmis) { - queries.put(from.split("/")[0], imageIds(from.split("/")[1])); - } - return queries; - } - - private static Map getDescribeQueriesForOwnersInRegions(Set regions, - final String[] amiOwners) { - final DescribeImagesOptions options = getOptionsForOwners(amiOwners); + public Iterable> getDescribeQueriesForOwnersInRegions(Set regions, + String[] amiOwners) { + DescribeImagesOptions options = getOptionsForOwners(amiOwners); Builder builder = ImmutableMap. builder(); for (String region : regions) builder.put(region, options); - return builder.build(); + return builder.build().entrySet(); } - private static DescribeImagesOptions getOptionsForOwners(final String[] amiOwners) { + public static DescribeImagesOptions getOptionsForOwners(String[] amiOwners) { final DescribeImagesOptions options; if (amiOwners.length == 1 && amiOwners[0].equals("*")) options = new DescribeImagesOptions(); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java index 5ab839e40f..3be92a4425 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/config/EC2RestClientModule.java @@ -19,8 +19,11 @@ package org.jclouds.ec2.config; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; + import java.net.URI; import java.util.Map; +import java.util.Set; import java.util.Map.Entry; import javax.inject.Inject; @@ -42,10 +45,6 @@ import org.jclouds.ec2.services.InstanceAsyncClient; import org.jclouds.ec2.services.InstanceClient; import org.jclouds.ec2.services.KeyPairAsyncClient; import org.jclouds.ec2.services.KeyPairClient; -import org.jclouds.ec2.services.MonitoringAsyncClient; -import org.jclouds.ec2.services.MonitoringClient; -import org.jclouds.ec2.services.PlacementGroupAsyncClient; -import org.jclouds.ec2.services.PlacementGroupClient; import org.jclouds.ec2.services.SecurityGroupAsyncClient; import org.jclouds.ec2.services.SecurityGroupClient; import org.jclouds.ec2.services.WindowsAsyncClient; @@ -55,8 +54,16 @@ import org.jclouds.location.Region; import org.jclouds.location.Zone; import org.jclouds.rest.ConfiguresRestClient; +import com.google.common.base.Predicates; +import com.google.common.base.Splitter; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; import com.google.common.collect.ImmutableMap.Builder; +import com.google.inject.ConfigurationException; +import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.name.Names; /** * Configures the EC2 connection. @@ -65,23 +72,26 @@ import com.google.common.collect.ImmutableMap.Builder; */ @RequiresHttp @ConfiguresRestClient -public class EC2RestClientModule extends WithZonesFormSigningRestClientModule { +public class EC2RestClientModule extends + WithZonesFormSigningRestClientModule { public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// - .put(AMIClient.class, AMIAsyncClient.class)// - .put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)// - .put(InstanceClient.class, InstanceAsyncClient.class)// - .put(KeyPairClient.class, KeyPairAsyncClient.class)// - .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)// - .put(PlacementGroupClient.class, PlacementGroupAsyncClient.class)// - .put(MonitoringClient.class, MonitoringAsyncClient.class)// - .put(WindowsClient.class, WindowsAsyncClient.class)// - .put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)// - .put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)// - .build(); + .put(AMIClient.class, AMIAsyncClient.class)// + .put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)// + .put(InstanceClient.class, InstanceAsyncClient.class)// + .put(KeyPairClient.class, KeyPairAsyncClient.class)// + .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)// + .put(WindowsClient.class, WindowsAsyncClient.class)// + .put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)// + .put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)// + .build(); - public EC2RestClientModule() { - super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP); + public static EC2RestClientModule create() { + return new EC2RestClientModule(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP); + } + + public EC2RestClientModule(Class sync, Class async, Map, Class> delegateMap) { + super(sync, async, delegateMap); } @Override @@ -97,20 +107,32 @@ public class EC2RestClientModule extends WithZonesFormSigningRestClientModule> { private final AvailabilityZoneAndRegionClient client; + private final Injector injector; @Inject - public RegionIdsToURI(EC2Client client) { + public RegionIdsToURI(EC2Client client, Injector injector) { this.client = client.getAvailabilityZoneAndRegionServices(); + this.injector = injector; } @Singleton @Region @Override public Map get() { + try { + String regionString = injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGIONS))); + Set regions = ImmutableSet.copyOf(Splitter.on(',').split(regionString)); + if (regions.size() > 0) + return Maps.filterKeys(client.describeRegions(), Predicates.in(regions)); + } catch (ConfigurationException e) { + // this happens if regions property isn't set + // services not run by AWS may not have regions, so this is ok. + } return client.describeRegions(); - } + } } + @Singleton public static class RegionIdToZoneId implements javax.inject.Provider> { private final AvailabilityZoneAndRegionClient client; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDevice.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDevice.java index 3a98726d48..a0765ade8b 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDevice.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDevice.java @@ -37,7 +37,6 @@ public class BlockDevice { private final boolean deleteOnTermination; public BlockDevice(String volumeId, Status attachmentStatus, Date attachTime, boolean deleteOnTermination) { - super(); this.volumeId = volumeId; this.attachmentStatus = attachmentStatus; this.attachTime = attachTime; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDeviceMapping.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDeviceMapping.java index 94364d10e6..0e6c3563f8 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDeviceMapping.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/BlockDeviceMapping.java @@ -42,15 +42,15 @@ public class BlockDeviceMapping { private static final Integer VOLUME_SIZE_MIN_VALUE = 1; private static final Integer VOLUME_SIZE_MAX_VALUE = 1000; - public BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId, - @Nullable Integer sizeInGib, @Nullable Boolean noDevice, @Nullable Boolean deleteOnTermination) { + BlockDeviceMapping(String deviceName, @Nullable String virtualName, @Nullable String snapshotId, + @Nullable Integer sizeInGib, @Nullable Boolean noDevice, @Nullable Boolean deleteOnTermination) { checkNotNull(deviceName, "deviceName cannot be null"); Preconditions2.checkNotEmpty(deviceName, "the deviceName must be non-empty"); if (sizeInGib != null) { - checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE), - String.format("Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE)); + checkArgument((sizeInGib >= VOLUME_SIZE_MIN_VALUE && sizeInGib <= VOLUME_SIZE_MAX_VALUE), String.format( + "Size in Gib must be between %s and %s GB", VOLUME_SIZE_MIN_VALUE, VOLUME_SIZE_MAX_VALUE)); } this.deviceName = deviceName; this.virtualName = virtualName; @@ -88,7 +88,12 @@ public class BlockDeviceMapping { public int hashCode() { final int prime = 31; int result = 1; + result = prime * result + ((deleteOnTermination == null) ? 0 : deleteOnTermination.hashCode()); result = prime * result + ((deviceName == null) ? 0 : deviceName.hashCode()); + result = prime * result + ((noDevice == null) ? 0 : noDevice.hashCode()); + result = prime * result + ((sizeInGib == null) ? 0 : sizeInGib.hashCode()); + result = prime * result + ((snapshotId == null) ? 0 : snapshotId.hashCode()); + result = prime * result + ((virtualName == null) ? 0 : virtualName.hashCode()); return result; } @@ -101,24 +106,49 @@ public class BlockDeviceMapping { if (getClass() != obj.getClass()) return false; BlockDeviceMapping other = (BlockDeviceMapping) obj; + if (deleteOnTermination == null) { + if (other.deleteOnTermination != null) + return false; + } else if (!deleteOnTermination.equals(other.deleteOnTermination)) + return false; if (deviceName == null) { if (other.deviceName != null) return false; } else if (!deviceName.equals(other.deviceName)) return false; + if (noDevice == null) { + if (other.noDevice != null) + return false; + } else if (!noDevice.equals(other.noDevice)) + return false; + if (sizeInGib == null) { + if (other.sizeInGib != null) + return false; + } else if (!sizeInGib.equals(other.sizeInGib)) + return false; + if (snapshotId == null) { + if (other.snapshotId != null) + return false; + } else if (!snapshotId.equals(other.snapshotId)) + return false; + if (virtualName == null) { + if (other.virtualName != null) + return false; + } else if (!virtualName.equals(other.virtualName)) + return false; return true; } @Override public String toString() { - return "BlockDeviceMapping [deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId=" - + snapshotId + ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination=" - + deleteOnTermination + "]"; + return "[deviceName=" + deviceName + ", virtualName=" + virtualName + ", snapshotId=" + snapshotId + + ", sizeInGib=" + sizeInGib + ", noDevice=" + noDevice + ", deleteOnTermination=" + deleteOnTermination + + "]"; } public static class MapEBSSnapshotToDevice extends BlockDeviceMapping { public MapEBSSnapshotToDevice(String deviceName, String snapshotId, @Nullable Integer sizeInGib, - @Nullable Boolean deleteOnTermination) { + @Nullable Boolean deleteOnTermination) { super(deviceName, null, snapshotId, sizeInGib, null, deleteOnTermination); checkNotNull(snapshotId, "snapshotId cannot be null"); Preconditions2.checkNotEmpty(snapshotId, "the snapshotId must be non-empty"); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java index fa41f67da9..03f982704b 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Reservation.java @@ -42,15 +42,15 @@ public class Reservation extends LinkedHashSet imp private static final long serialVersionUID = -9051777593518861395L; private final String region; private final Set groupIds = Sets.newLinkedHashSet(); - private final @Nullable - String ownerId; - private final @Nullable - String requesterId; - private final @Nullable - String reservationId; + @Nullable + private final String ownerId; + @Nullable + private final String requesterId; + @Nullable + private final String reservationId; - public Reservation(String region, Iterable groupIds, Iterable instances, - @Nullable String ownerId, @Nullable String requesterId, @Nullable String reservationId) { + public Reservation(String region, Iterable groupIds, Iterable instances, @Nullable String ownerId, + @Nullable String requesterId, @Nullable String reservationId) { this.region = checkNotNull(region, "region"); Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds")); Iterables.addAll(this, checkNotNull(instances, "instances")); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java index 645de2b7b9..020c2e975f 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/RunningInstance.java @@ -27,8 +27,8 @@ import java.util.Set; import javax.annotation.Nullable; - -import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -40,64 +40,221 @@ import com.google.common.collect.Sets; */ public class RunningInstance implements Comparable { - private final String region; - private final Set groupIds = Sets.newLinkedHashSet(); + public static class Builder { + protected String region; + protected Set groupIds = Sets.newLinkedHashSet(); + protected String amiLaunchIndex; + protected String dnsName; + protected String imageId; + protected String instanceId; + protected InstanceState instanceState; + protected String instanceType; + protected String ipAddress; + protected String kernelId; + protected String keyName; + protected Date launchTime; + protected String availabilityZone; + protected String virtualizationType = "paravirtual"; + protected String platform; + protected String privateDnsName; + protected String privateIpAddress; + protected String ramdiskId; + protected String reason; + protected RootDeviceType rootDeviceType = RootDeviceType.INSTANCE_STORE; + protected String rootDeviceName; + protected Map ebsBlockDevices = Maps.newLinkedHashMap(); - private final String amiLaunchIndex; + public Builder region(String region) { + this.region = region; + return this; + } + + public Builder groupIds(Iterable groupIds) { + this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds")); + return this; + } + + public Builder groupId(String groupId) { + if (groupId != null) + this.groupIds.add(groupId); + return this; + } + + public Builder amiLaunchIndex(String amiLaunchIndex) { + this.amiLaunchIndex = amiLaunchIndex; + return this; + } + + public Builder dnsName(String dnsName) { + this.dnsName = dnsName; + return this; + } + + public Builder imageId(String imageId) { + this.imageId = imageId; + return this; + } + + public Builder instanceId(String instanceId) { + this.instanceId = instanceId; + return this; + } + + public Builder instanceState(InstanceState instanceState) { + this.instanceState = instanceState; + return this; + } + + public Builder instanceType(String instanceType) { + this.instanceType = instanceType; + return this; + } + + public Builder ipAddress(String ipAddress) { + this.ipAddress = ipAddress; + return this; + } + + public Builder kernelId(String kernelId) { + this.kernelId = kernelId; + return this; + } + + public Builder keyName(String keyName) { + this.keyName = keyName; + return this; + } + + public Builder launchTime(Date launchTime) { + this.launchTime = launchTime; + return this; + } + + public Builder availabilityZone(String availabilityZone) { + this.availabilityZone = availabilityZone; + return this; + } + + public Builder virtualizationType(String virtualizationType) { + this.virtualizationType = virtualizationType; + return this; + } + + public Builder platform(String platform) { + this.platform = platform; + return this; + } + + public Builder privateDnsName(String privateDnsName) { + this.privateDnsName = privateDnsName; + return this; + } + + public Builder privateIpAddress(String privateIpAddress) { + this.privateIpAddress = privateIpAddress; + return this; + } + + public Builder ramdiskId(String ramdiskId) { + this.ramdiskId = ramdiskId; + return this; + } + + public Builder reason(String reason) { + this.reason = reason; + return this; + } + + public Builder rootDeviceType(RootDeviceType rootDeviceType) { + this.rootDeviceType = rootDeviceType; + return this; + } + + public Builder rootDeviceName(String rootDeviceName) { + this.rootDeviceName = rootDeviceName; + return this; + } + + public Builder devices(Map ebsBlockDevices) { + this.ebsBlockDevices = ImmutableMap.copyOf(checkNotNull(ebsBlockDevices, "ebsBlockDevices")); + return this; + } + + public Builder device(String key, BlockDevice value) { + if (key != null && value != null) + this.ebsBlockDevices.put(key, value); + return this; + } + + public RunningInstance build() { + return new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState, + instanceType, ipAddress, kernelId, keyName, launchTime, availabilityZone, virtualizationType, + platform, privateDnsName, privateIpAddress, ramdiskId, reason, rootDeviceType, rootDeviceName, + ebsBlockDevices); + } + + public String getDnsName() { + return dnsName; + } + + public String getIpAddress() { + return ipAddress; + } + + public String getPrivateDnsName() { + return privateDnsName; + } + + public String getPrivateIpAddress() { + return privateIpAddress; + } + + } + + protected final String region; + protected final Set groupIds; + protected final String amiLaunchIndex; @Nullable - private final String dnsName; - private final String imageId; - private final String instanceId; - private final InstanceState instanceState; - private final String instanceType; + protected final String dnsName; + protected final String imageId; + protected final String instanceId; + protected final InstanceState instanceState; + protected final String instanceType; @Nullable - private final String ipAddress; + protected final String ipAddress; @Nullable - private final String kernelId; + protected final String kernelId; @Nullable - private final String keyName; - private final Date launchTime; - private final MonitoringState monitoringState; - private final String availabilityZone; + protected final String keyName; + protected final Date launchTime; + protected final String availabilityZone; + protected final String virtualizationType; @Nullable - private final String placementGroup; - private final String virtualizationType; + protected final String platform; @Nullable - private final String platform; + protected final String privateDnsName; @Nullable - private final String privateDnsName; + protected final String privateIpAddress; @Nullable - private final String privateIpAddress; - private final Set productCodes = Sets.newLinkedHashSet(); + protected final String ramdiskId; @Nullable - private final String ramdiskId; + protected final String reason; + protected final RootDeviceType rootDeviceType; @Nullable - private final String reason; - @Nullable - private final String subnetId; - @Nullable - private final String spotInstanceRequestId; - @Nullable - private final String vpcId; - private final RootDeviceType rootDeviceType; - @Nullable - private final String rootDeviceName; - private final Map ebsBlockDevices = Maps.newHashMap(); + protected final String rootDeviceName; + protected final Map ebsBlockDevices; public int compareTo(RunningInstance o) { return (this == o) ? 0 : getId().compareTo(o.getId()); } - public RunningInstance(String region, Iterable groupIds, @Nullable String amiLaunchIndex, + protected RunningInstance(String region, Iterable groupIds, @Nullable String amiLaunchIndex, @Nullable String dnsName, String imageId, String instanceId, InstanceState instanceState, String instanceType, @Nullable String ipAddress, @Nullable String kernelId, @Nullable String keyName, - Date launchTime, MonitoringState monitoringState, String availabilityZone, @Nullable String placementGroup, - String virtualizationType, @Nullable String platform, @Nullable String privateDnsName, - @Nullable String privateIpAddress, Set productCodes, @Nullable String ramdiskId, - @Nullable String reason, @Nullable String subnetId, @Nullable String spotInstanceRequestId, - @Nullable String vpcId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName, + Date launchTime, String availabilityZone, String virtualizationType, @Nullable String platform, + @Nullable String privateDnsName, @Nullable String privateIpAddress, @Nullable String ramdiskId, + @Nullable String reason, RootDeviceType rootDeviceType, @Nullable String rootDeviceName, Map ebsBlockDevices) { - Iterables.addAll(this.groupIds, checkNotNull(groupIds, "groupIds")); this.region = checkNotNull(region, "region"); this.amiLaunchIndex = amiLaunchIndex; // nullable on runinstances. this.dnsName = dnsName; // nullable on runinstances. @@ -109,22 +266,17 @@ public class RunningInstance implements Comparable { this.kernelId = kernelId; this.keyName = keyName; this.launchTime = checkNotNull(launchTime, "launchTime"); - this.monitoringState = monitoringState; - this.availabilityZone = availabilityZone; // nullable on Nova. - this.placementGroup = placementGroup; + this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone"); this.virtualizationType = virtualizationType; this.platform = platform; - this.privateDnsName = privateDnsName; // nullable on Nova. - this.privateIpAddress = privateIpAddress; - Iterables.addAll(this.productCodes, checkNotNull(productCodes, "productCodes")); + this.privateDnsName = privateDnsName;// nullable on runinstances. + this.privateIpAddress = privateIpAddress;// nullable on runinstances. this.ramdiskId = ramdiskId; this.reason = reason; - this.subnetId = subnetId; - this.spotInstanceRequestId = spotInstanceRequestId; - this.vpcId = vpcId; this.rootDeviceType = checkNotNull(rootDeviceType, "rootDeviceType"); this.rootDeviceName = rootDeviceName; - this.getEbsBlockDevices().putAll(checkNotNull(ebsBlockDevices, "ebsBlockDevices")); + this.ebsBlockDevices = ImmutableMap.copyOf(checkNotNull(ebsBlockDevices, "ebsBlockDevices")); + this.groupIds = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds")); } /** @@ -209,13 +361,6 @@ public class RunningInstance implements Comparable { return launchTime; } - /** - * State of monitoring for the instance. - */ - public MonitoringState getMonitoringState() { - return monitoringState; - } - /** * The location where the instance launched. */ @@ -223,13 +368,6 @@ public class RunningInstance implements Comparable { return availabilityZone; } - /** - * The name of the placement group the instance is in (for cluster compute instances). - */ - public String getPlacementGroup() { - return placementGroup; - } - /** * Specifies the instance's virtualization type. Valid values are paravirtual or hvm. */ @@ -259,13 +397,6 @@ public class RunningInstance implements Comparable { return privateIpAddress; } - /** - * Product codes attached to this instance. - */ - public Set getProductCodes() { - return productCodes; - } - /** * Optional. RAM disk associated with this instance. */ @@ -280,27 +411,6 @@ public class RunningInstance implements Comparable { return reason; } - /** - * The ID of the Spot Instance request - */ - public String getSpotInstanceRequestId() { - return spotInstanceRequestId; - } - - /** - * Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud). - */ - public String getSubnetId() { - return subnetId; - } - - /** - * Specifies the VPC in which the instance is running (Amazon Virtual Private Cloud). - */ - public String getVpcId() { - return vpcId; - } - public RootDeviceType getRootDeviceType() { return rootDeviceType; } @@ -339,21 +449,14 @@ public class RunningInstance implements Comparable { result = prime * result + ((kernelId == null) ? 0 : kernelId.hashCode()); result = prime * result + ((keyName == null) ? 0 : keyName.hashCode()); result = prime * result + ((launchTime == null) ? 0 : launchTime.hashCode()); - result = prime * result + ((monitoringState == null) ? 0 : monitoringState.hashCode()); - result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); result = prime * result + ((platform == null) ? 0 : platform.hashCode()); result = prime * result + ((privateDnsName == null) ? 0 : privateDnsName.hashCode()); result = prime * result + ((privateIpAddress == null) ? 0 : privateIpAddress.hashCode()); - result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode()); result = prime * result + ((ramdiskId == null) ? 0 : ramdiskId.hashCode()); - result = prime * result + ((reason == null) ? 0 : reason.hashCode()); result = prime * result + ((region == null) ? 0 : region.hashCode()); result = prime * result + ((rootDeviceName == null) ? 0 : rootDeviceName.hashCode()); result = prime * result + ((rootDeviceType == null) ? 0 : rootDeviceType.hashCode()); - result = prime * result + ((spotInstanceRequestId == null) ? 0 : spotInstanceRequestId.hashCode()); - result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); result = prime * result + ((virtualizationType == null) ? 0 : virtualizationType.hashCode()); - result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode()); return result; } @@ -426,16 +529,6 @@ public class RunningInstance implements Comparable { return false; } else if (!launchTime.equals(other.launchTime)) return false; - if (monitoringState == null) { - if (other.monitoringState != null) - return false; - } else if (!monitoringState.equals(other.monitoringState)) - return false; - if (placementGroup == null) { - if (other.placementGroup != null) - return false; - } else if (!placementGroup.equals(other.placementGroup)) - return false; if (platform == null) { if (other.platform != null) return false; @@ -451,21 +544,11 @@ public class RunningInstance implements Comparable { return false; } else if (!privateIpAddress.equals(other.privateIpAddress)) return false; - if (productCodes == null) { - if (other.productCodes != null) - return false; - } else if (!productCodes.equals(other.productCodes)) - return false; if (ramdiskId == null) { if (other.ramdiskId != null) return false; } else if (!ramdiskId.equals(other.ramdiskId)) return false; - if (reason == null) { - if (other.reason != null) - return false; - } else if (!reason.equals(other.reason)) - return false; if (region == null) { if (other.region != null) return false; @@ -481,41 +564,22 @@ public class RunningInstance implements Comparable { return false; } else if (!rootDeviceType.equals(other.rootDeviceType)) return false; - if (spotInstanceRequestId == null) { - if (other.spotInstanceRequestId != null) - return false; - } else if (!spotInstanceRequestId.equals(other.spotInstanceRequestId)) - return false; - if (subnetId == null) { - if (other.subnetId != null) - return false; - } else if (!subnetId.equals(other.subnetId)) - return false; if (virtualizationType == null) { if (other.virtualizationType != null) return false; } else if (!virtualizationType.equals(other.virtualizationType)) return false; - if (vpcId == null) { - if (other.vpcId != null) - return false; - } else if (!vpcId.equals(other.vpcId)) - return false; return true; } @Override public String toString() { - return "RunningInstance [amiLaunchIndex=" + amiLaunchIndex + ", availabilityZone=" + availabilityZone - + ", placementGroup=" + placementGroup + ", virtualizationType=" + virtualizationType + ", dnsName=" - + dnsName + ", ebsBlockDevices=" + ebsBlockDevices + ", groupIds=" + groupIds + ", imageId=" + imageId - + ", instanceId=" + instanceId + ", instanceState=" + instanceState + ", instanceType=" + instanceType - + ", ipAddress=" + ipAddress + ", kernelId=" + kernelId + ", keyName=" + keyName + ", launchTime=" - + launchTime + ", monitoringState=" + monitoringState + ", platform=" + platform + ", privateDnsName=" - + privateDnsName + ", privateIpAddress=" + privateIpAddress + ", productCodes=" + productCodes - + ", ramdiskId=" + ramdiskId + ", reason=" + reason + ", region=" + region + ", rootDeviceName=" - + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", spotInstanceRequestId=" - + spotInstanceRequestId + ", subnetId=" + subnetId + ", vpcId=" + vpcId + "]"; + return "[region=" + region + ", availabilityZone=" + availabilityZone + ", instanceId=" + instanceId + + ", instanceState=" + instanceState + ", instanceType=" + instanceType + ", virtualizationType=" + + virtualizationType + ", imageId=" + imageId + ", ipAddress=" + ipAddress + ", dnsName=" + dnsName + + ", privateIpAddress=" + privateIpAddress + ", privateDnsName=" + privateDnsName + ", keyName=" + + keyName + ", platform=" + platform + ", launchTime=" + launchTime + ", rootDeviceName=" + + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", ebsBlockDevices=" + ebsBlockDevices + "]"; } } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java b/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java index b3e743653d..30c166afdc 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/options/RunInstancesOptions.java @@ -43,8 +43,7 @@ import org.jclouds.encryption.internal.Base64; * * * @author Adrian Cole - * @see */ @@ -93,22 +92,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return getFirstFormOrNull("SecurityGroup.1"); } - /** - * Specifies the name of an existing placement group you want to launch the instance into (for - * cluster compute instances). - * - * @param placementGroup - * name of an existing placement group - */ - public RunInstancesOptions inPlacementGroup(String placementGroup) { - formParameters.put("Placement.GroupName", checkNotNull(placementGroup, "placementGroup")); - return this; - } - - String getPlacementGroup() { - return getFirstFormOrNull("Placement.GroupName"); - } - /** * Unencoded data */ @@ -163,58 +146,34 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return getFirstFormOrNull("RamdiskId"); } - /** - * Enables monitoring for the instance. - */ - public RunInstancesOptions enableMonitoring() { - formParameters.put("Monitoring.Enabled", "true"); - return this; - } - - String getMonitoringEnabled() { - return getFirstFormOrNull("Monitoring.Enabled"); - } - - /** - * Specifies the subnet ID within which to launch the instance(s) for Amazon Virtual Private - * Cloud. - */ - public RunInstancesOptions withSubnetId(String subnetId) { - formParameters.put("SubnetId", checkNotNull(subnetId, "subnetId")); - return this; - } - - String getSubnetId() { - return getFirstFormOrNull("SubnetId"); - } - /** * Specifies the Block Device Mapping for the instance - * + * */ - - public RunInstancesOptions withBlockDeviceMappings(Set mappings) { - int i = 1; - for(BlockDeviceMapping mapping: mappings) - { - checkNotNull(mapping.getDeviceName(), "deviceName"); - formParameters.put(String.format("BlockDeviceMapping.%d.DeviceName", i), mapping.getDeviceName()); - if(mapping.getVirtualName() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.VirtualName", i), mapping.getVirtualName()); - if(mapping.getEbsSnapshotId() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId()); - if(mapping.getEbsVolumeSize() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i), String.valueOf(mapping.getEbsVolumeSize())); - if(mapping.getEbsNoDevice() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i), String.valueOf(mapping.getEbsNoDevice())); - if(mapping.getEbsDeleteOnTermination() != null) - formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i), String.valueOf(mapping.getEbsDeleteOnTermination())); - - i++; - } - return this; - } + public RunInstancesOptions withBlockDeviceMappings(Set mappings) { + int i = 1; + for (BlockDeviceMapping mapping : checkNotNull(mappings, "mappings")) { + checkNotNull(mapping.getDeviceName(), "deviceName"); + formParameters.put(String.format("BlockDeviceMapping.%d.DeviceName", i), mapping.getDeviceName()); + if (mapping.getVirtualName() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.VirtualName", i), mapping.getVirtualName()); + if (mapping.getEbsSnapshotId() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.SnapshotId", i), mapping.getEbsSnapshotId()); + if (mapping.getEbsVolumeSize() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.VolumeSize", i), String.valueOf(mapping + .getEbsVolumeSize())); + if (mapping.getEbsNoDevice() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.NoDevice", i), String.valueOf(mapping + .getEbsNoDevice())); + if (mapping.getEbsDeleteOnTermination() != null) + formParameters.put(String.format("BlockDeviceMapping.%d.Ebs.DeleteOnTermination", i), String + .valueOf(mapping.getEbsDeleteOnTermination())); + + i++; + } + return this; + } public static class Builder { /** @@ -233,14 +192,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return options.withSecurityGroup(securityGroup); } - /** - * @see RunInstancesOptions#inPlacementGroup(String) - */ - public static RunInstancesOptions inPlacementGroup(String placementGroup) { - RunInstancesOptions options = new RunInstancesOptions(); - return options.inPlacementGroup(placementGroup); - } - /** * @see RunInstancesOptions#withUserData(byte []) */ @@ -265,22 +216,6 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { return options.withKernelId(kernelId); } - /** - * @see RunInstancesOptions#enableMonitoring() - */ - public static RunInstancesOptions enableMonitoring() { - RunInstancesOptions options = new RunInstancesOptions(); - return options.enableMonitoring(); - } - - /** - * @see RunInstancesOptions#withSubnetId(String) - */ - public static RunInstancesOptions withSubnetId(String subnetId) { - RunInstancesOptions options = new RunInstancesOptions(); - return options.withSubnetId(subnetId); - } - /** * @see RunInstancesOptions#withRamdisk(String) */ @@ -288,7 +223,7 @@ public class RunInstancesOptions extends BaseEC2RequestOptions { RunInstancesOptions options = new RunInstancesOptions(); return options.withRamdisk(ramdiskId); } - + /** * @see RunInstancesOptions#withBlockDeviceMappings(Set mappings) */ diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java b/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java index f54a5d63f1..f51281f681 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/reference/EC2Constants.java @@ -26,19 +26,11 @@ import org.jclouds.compute.ComputeService; * * @author Adrian Cole */ -public interface EC2Constants{ +public interface EC2Constants { /** * Listing the universe of amis is extremely expensive. set this to a comma separated value of * the ami owners you wish to use in {@link ComputeService} */ public static final String PROPERTY_EC2_AMI_OWNERS = "jclouds.ec2.ami-owners"; - public static final String PROPERTY_ELB_ENDPOINT = "jclouds.elb.endpoint"; - - /** - * amis that work on the cluster instance type - * - * @see InstanceType.CC1_4XLARGE - */ - public static final String PROPERTY_EC2_CC_AMIs = "jclouds.ec2.cc-amis"; } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java index 39253ff9ee..d86528fbbe 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIAsyncClient.java @@ -32,12 +32,11 @@ import javax.ws.rs.Path; import org.jclouds.aws.filters.FormSigner; import org.jclouds.ec2.EC2AsyncClient; -import org.jclouds.ec2.binders.BindProductCodesToIndexedFormParams; import org.jclouds.ec2.binders.BindUserGroupsToIndexedFormParams; import org.jclouds.ec2.binders.BindUserIdsToIndexedFormParams; import org.jclouds.ec2.domain.Image; -import org.jclouds.ec2.domain.Image.EbsBlockDevice; import org.jclouds.ec2.domain.Permission; +import org.jclouds.ec2.domain.Image.EbsBlockDevice; import org.jclouds.ec2.options.CreateImageOptions; import org.jclouds.ec2.options.DescribeImagesOptions; import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; @@ -46,7 +45,6 @@ import org.jclouds.ec2.xml.BlockDeviceMappingHandler; import org.jclouds.ec2.xml.DescribeImagesResponseHandler; import org.jclouds.ec2.xml.ImageIdHandler; import org.jclouds.ec2.xml.PermissionHandler; -import org.jclouds.ec2.xml.ProductCodesHandler; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.EndpointParam; @@ -79,7 +77,8 @@ public interface AMIAsyncClient { @XMLResponseParser(DescribeImagesResponseHandler.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) ListenableFuture> describeImagesInRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, DescribeImagesOptions... options); + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + DescribeImagesOptions... options); /** * @see AMIClient#createImageInRegion @@ -88,7 +87,8 @@ public interface AMIAsyncClient { @Path("/") @FormParams(keys = ACTION, values = "CreateImage") @XMLResponseParser(ImageIdHandler.class) - ListenableFuture createImageInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + ListenableFuture createImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("Name") String name, @FormParam("InstanceId") String instanceId, CreateImageOptions... options); /** @@ -97,7 +97,8 @@ public interface AMIAsyncClient { @POST @Path("/") @FormParams(keys = ACTION, values = "DeregisterImage") - ListenableFuture deregisterImageInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + ListenableFuture deregisterImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("ImageId") String imageId); /** @@ -173,17 +174,6 @@ public interface AMIAsyncClient { @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("ImageId") String imageId); - /** - * @see AMIClient#getProductCodesForImageInRegion - */ - @POST - @Path("/") - @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "productCodes" }) - @XMLResponseParser(ProductCodesHandler.class) - ListenableFuture> getProductCodesForImageInRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, - @FormParam("ImageId") String imageId); - /** * @see AMIClient#getBlockDeviceMappingsForImageInRegion */ @@ -194,27 +184,4 @@ public interface AMIAsyncClient { ListenableFuture> getBlockDeviceMappingsForImageInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @FormParam("ImageId") String imageId); - - /** - * @see AMIClient#addProductCodesToImageInRegion - */ - @POST - @Path("/") - @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "add", - "productCodes" }) - ListenableFuture addProductCodesToImageInRegion(@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, - @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, - @FormParam("ImageId") String imageId); - - /** - * @see AMIClient#removeProductCodesToImageInRegion - */ - @POST - @Path("/") - @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "remove", - "productCodes" }) - ListenableFuture removeProductCodesFromImageInRegion( - @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, - @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, - @FormParam("ImageId") String imageId); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java index 9e621fcbc2..29d1b5aadb 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/AMIClient.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; +import org.jclouds.concurrent.Timeout; import org.jclouds.ec2.domain.Image; import org.jclouds.ec2.domain.Permission; import org.jclouds.ec2.domain.Image.EbsBlockDevice; @@ -32,7 +33,6 @@ import org.jclouds.ec2.options.CreateImageOptions; import org.jclouds.ec2.options.DescribeImagesOptions; import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; import org.jclouds.ec2.options.RegisterImageOptions; -import org.jclouds.concurrent.Timeout; /** * Provides access to EC2 via their REST API. @@ -60,22 +60,6 @@ public interface AMIClient { @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) Set describeImagesInRegion(@Nullable String region, DescribeImagesOptions... options); - /** - * Returns the Product Codes of an image. - * - * @param region - * AMIs are tied to the Region where its files are located within Amazon S3. - * @param imageId - * The ID of the AMI for which an attribute will be described - * @see #describeImages - * @see #modifyImageAttribute - * @see #resetImageAttribute - * @see - * @see DescribeImagesOptions - */ - Set getProductCodesForImageInRegion(@Nullable String region, String imageId); - /** * Returns a map of device name to block device for the image. * @@ -114,8 +98,7 @@ public interface AMIClient { * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateImage.html" * /> */ - String createImageInRegion(@Nullable String region, String name, String instanceId, - CreateImageOptions... options); + String createImageInRegion(@Nullable String region, String name, String instanceId, CreateImageOptions... options); /** * @@ -201,7 +184,7 @@ public interface AMIClient { */ String registerUnixImageBackedByEbsInRegion(@Nullable String region, String name, String ebsSnapshotId, RegisterImageBackedByEbsOptions... options); - + /** * Returns the {@link Permission}s of an image. * @@ -276,40 +259,4 @@ public interface AMIClient { void removeLaunchPermissionsFromImageInRegion(@Nullable String region, Iterable userIds, Iterable userGroups, String imageId); - /** - * Adds {@code productCode}s to an AMI. - * - * @param region - * AMIs are tied to the Region where its files are located within Amazon S3. - * @param productCodes - * Product Codes - * @param imageId - * The AMI ID. - * - * @see #removeProductCodesFromImage - * @see #describeImageAttribute - * @see #resetImageAttribute - * @see - */ - void addProductCodesToImageInRegion(@Nullable String region, Iterable productCodes, String imageId); - - /** - * Removes {@code productCode}s from an AMI. - * - * @param region - * AMIs are tied to the Region where its files are located within Amazon S3. - * @param productCodes - * Product Codes - * @param imageId - * The AMI ID. - * - * @see #addProductCodesToImage - * @see #describeImageAttribute - * @see #resetImageAttribute - * @see - */ - void removeProductCodesFromImageInRegion(@Nullable String region, Iterable productCodes, - String imageId); } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java b/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java index cecacd6ecc..b30afddbf7 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/services/InstanceAsyncClient.java @@ -83,7 +83,7 @@ public interface InstanceAsyncClient { @FormParams(keys = ACTION, values = "DescribeInstances") @XMLResponseParser(DescribeInstancesResponseHandler.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) - ListenableFuture>> describeInstancesInRegion( + ListenableFuture>> describeInstancesInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); @@ -94,7 +94,7 @@ public interface InstanceAsyncClient { @Path("/") @FormParams(keys = ACTION, values = "RunInstances") @XMLResponseParser(RunInstancesResponseHandler.class) - ListenableFuture> runInstancesInRegion( + ListenableFuture> runInstancesInRegion( @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone, @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount, diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java index 6a60ae61b2..04c4af953d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/BaseReservationHandler.java @@ -20,28 +20,27 @@ package org.jclouds.ec2.xml; import java.util.Date; -import java.util.Map; import java.util.Set; import javax.annotation.Resource; import javax.inject.Inject; +import org.jclouds.aws.util.AWSUtils; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.Attachment; import org.jclouds.ec2.domain.BlockDevice; import org.jclouds.ec2.domain.InstanceState; -import org.jclouds.ec2.domain.MonitoringState; import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RootDeviceType; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.aws.util.AWSUtils; -import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.RunningInstance.Builder; import org.jclouds.http.functions.ParseSax.HandlerForGeneratedRequestWithResult; import org.jclouds.location.Region; import org.jclouds.logging.Logger; import org.xml.sax.Attributes; -import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import com.google.inject.Provider; /** * @@ -49,75 +48,49 @@ import com.google.common.collect.Sets; */ public abstract class BaseReservationHandler extends HandlerForGeneratedRequestWithResult { - protected final DateService dateService; - - protected final String defaultRegion; - - @Inject - public BaseReservationHandler(DateService dateService, @Region String defaultRegion) { - this.dateService = dateService; - this.defaultRegion = defaultRegion; - } - @Resource protected Logger logger = Logger.NULL; - private StringBuilder currentText = new StringBuilder(); - private Set groupIds = Sets.newLinkedHashSet(); - private Set instances = Sets.newLinkedHashSet(); - private String ownerId; - private String requesterId; - private String reservationId; - private String amiLaunchIndex; - private String dnsName; - private String imageId; - private String instanceId; - private InstanceState instanceState; - private String instanceType; - private String ipAddress; - private String kernelId; - private String keyName; - private Date launchTime; - private MonitoringState monitoringState; - private String availabilityZone; - private String placementGroup; - private String virtualizationType = "paravirtual"; - private String platform; - private String privateDnsName; - private String privateIpAddress; - private Set productCodes = Sets.newHashSet(); - private String ramdiskId; - private String reason; - private String spotInstanceRequestId; - private String subnetId; - private String vpcId; - protected boolean inInstances; - protected boolean inProductCodes; - protected boolean inGroups; - protected boolean inMonitoring; - private boolean inBlockDeviceMapping; - private Map ebsBlockDevices = Maps.newHashMap(); + protected final DateService dateService; + protected final String defaultRegion; + protected final Provider builderProvider; + @Inject + public BaseReservationHandler(DateService dateService, @Region String defaultRegion, + Provider builderProvider) { + this.dateService = dateService; + this.defaultRegion = defaultRegion; + this.builderProvider = builderProvider; + this.builder = builderProvider.get(); + } + + protected StringBuilder currentText = new StringBuilder(); + + protected Builder builder; + + protected int itemDepth; + boolean inInstancesSet; + // attachments private String volumeId; private Attachment.Status attachmentStatus; private Date attachTime; private boolean deleteOnTermination; - private RootDeviceType rootDeviceType = RootDeviceType.INSTANCE_STORE; private String deviceName; - private String rootDeviceName; + + // reservation stuff + private Set groupIds = Sets.newLinkedHashSet(); + private String ownerId; + private String requesterId; + private String reservationId; + + private Set instances = Sets.newLinkedHashSet(); public void startElement(String uri, String name, String qName, Attributes attrs) { - if (qName.equals("instancesSet")) { - inInstances = true; - } else if (qName.equals("productCodesSet")) { - inProductCodes = true; - } else if (qName.equals("groupSet")) { - inGroups = true; - } else if (qName.equals("blockDeviceMapping")) { - inBlockDeviceMapping = true; + if (qName.equals("item")) { + itemDepth++; + } else if (qName.equals("instancesSet")) { + inInstancesSet = true; } - if (qName.equals("monitoring")) - inMonitoring = true; } protected String currentOrNull() { @@ -126,7 +99,12 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque } public void endElement(String uri, String name, String qName) { - if (qName.equals("groupId")) { + if (qName.equals("item")) { + inItem(); + itemDepth--; + } else if (qName.equals("instancesSet")) { + inInstancesSet = false; + } else if (qName.equals("groupId")) { groupIds.add(currentOrNull()); } else if (qName.equals("ownerId")) { ownerId = currentOrNull(); @@ -135,83 +113,51 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque } else if (qName.equals("reservationId")) { reservationId = currentOrNull(); } else if (qName.equals("amiLaunchIndex")) { - amiLaunchIndex = currentOrNull(); + builder.amiLaunchIndex(currentOrNull()); } else if (qName.equals("dnsName")) { - dnsName = currentOrNull(); + String dnsName = currentOrNull(); // Eucalyptus - if ("0.0.0.0".equals(dnsName)) - dnsName = null; + if (!"0.0.0.0".equals(dnsName)) + builder.dnsName(dnsName); } else if (qName.equals("imageId")) { - imageId = currentOrNull(); + builder.imageId(currentOrNull()); } else if (qName.equals("instanceId")) { - instanceId = currentOrNull(); + builder.instanceId(currentOrNull()); } else if (qName.equals("name")) { - String state = currentOrNull(); - if (state != null) { - // Nova - if ("shutdown".equalsIgnoreCase(state)) - instanceState = InstanceState.TERMINATED; - else - instanceState = InstanceState.fromValue(state); - } + builder.instanceState(InstanceState.fromValue(currentOrNull())); } else if (qName.equals("instanceType")) { - instanceType = currentOrNull(); + builder.instanceType(currentOrNull()); } else if (qName.equals("ipAddress")) { - ipAddress = currentOrNull(); + builder.ipAddress(currentOrNull()); } else if (qName.equals("kernelId")) { - kernelId = currentOrNull(); + builder.kernelId(currentOrNull()); } else if (qName.equals("keyName")) { - keyName = currentOrNull(); + builder.keyName(currentOrNull()); } else if (qName.equals("launchTime")) { - try { - launchTime = dateService.iso8601DateParse(currentOrNull()); - } catch (RuntimeException e) { - // Eucalyptus - launchTime = dateService.iso8601SecondsDateParse(currentOrNull()); - } - } else if (qName.equals("state") && inMonitoring) { - monitoringState = MonitoringState.fromValue(currentOrNull()); + builder.launchTime(parseDate()); } else if (qName.equals("availabilityZone")) { - availabilityZone = currentOrNull(); - } else if (qName.equals("groupName")) { - placementGroup = currentOrNull(); + builder.availabilityZone(currentOrNull()); } else if (qName.equals("virtualizationType")) { - virtualizationType = currentOrNull(); + builder.virtualizationType(currentOrNull()); } else if (qName.equals("platform")) { - platform = currentOrNull(); + builder.platform(currentOrNull()); } else if (qName.equals("privateDnsName")) { - privateDnsName = currentOrNull(); + String privateDnsName = currentOrNull(); // Eucalyptus - if ("0.0.0.0".equals(privateDnsName)) - privateDnsName = null; + if (!"0.0.0.0".equals(privateDnsName)) + builder.privateDnsName(privateDnsName); } else if (qName.equals("privateIpAddress")) { - privateIpAddress = currentOrNull(); + builder.privateIpAddress(currentOrNull()); } else if (qName.equals("ramdiskId")) { - ramdiskId = currentOrNull(); + builder.ramdiskId(currentOrNull()); } else if (qName.equals("reason")) { - reason = currentOrNull(); - } else if (qName.equals("subnetId")) { - subnetId = currentOrNull(); - } else if (qName.equals("spotInstanceRequestId")) { - spotInstanceRequestId = currentOrNull(); - } else if (qName.equals("vpcId")) { - vpcId = currentOrNull(); - } else if (qName.equals("productCode")) { - productCodes.add(currentOrNull()); - } else if (qName.equals("productCodesSet")) { - inProductCodes = false; - } else if (qName.equals("instancesSet")) { - inInstances = false; - } else if (qName.equals("groupSet")) { - inGroups = false; - } else if (qName.equals("monitoring")) { - inMonitoring = false; - } else if (qName.equals("blockDeviceMapping")) { - inBlockDeviceMapping = false; + builder.reason(currentOrNull()); + } else if (qName.equals("rootDeviceType")) { + builder.rootDeviceType(RootDeviceType.fromValue(currentOrNull())); + } else if (qName.equals("rootDeviceName")) { + builder.rootDeviceName(currentOrNull()); } else if (qName.equals("deviceName")) { deviceName = currentOrNull(); - } else if (qName.equals("rootDeviceType")) { - rootDeviceType = RootDeviceType.fromValue(currentOrNull()); } else if (qName.equals("volumeId")) { volumeId = currentOrNull(); } else if (qName.equals("status")) { @@ -220,72 +166,60 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque attachTime = dateService.iso8601DateParse(currentText.toString().trim()); } else if (qName.equals("deleteOnTermination")) { deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim()); - } else if (qName.equals("rootDeviceName")) { - rootDeviceName = currentOrNull(); - } else if (qName.equals("item")) { - inItem(); - } - currentText = new StringBuilder(); - } - - protected void inItem() { - if (inBlockDeviceMapping) { - ebsBlockDevices.put(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, - deleteOnTermination)); + } else if (qName.equals("ebs")) { + builder.device(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination)); this.deviceName = null; this.volumeId = null; this.attachmentStatus = null; this.attachTime = null; this.deleteOnTermination = true; - } else if (inInstances && !inProductCodes && !inBlockDeviceMapping) { - String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null; + } + currentText = new StringBuilder(); + } + protected Date parseDate() { + try { + return dateService.iso8601DateParse(currentOrNull()); + } catch (RuntimeException e) { // Eucalyptus - if (ipAddress == null && dnsName != null && dnsName.matches(".*[0-9]$")) { - ipAddress = dnsName; - dnsName = null; - } - - if (privateIpAddress == null && privateDnsName != null && privateDnsName.matches(".*[0-9]$")) { - privateIpAddress = privateDnsName; - privateDnsName = null; - } - if (region == null) - region = defaultRegion; - instances.add(new RunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, - instanceState, instanceType, ipAddress, kernelId, keyName, launchTime, monitoringState, - availabilityZone, placementGroup, virtualizationType, platform, privateDnsName, privateIpAddress, - productCodes, ramdiskId, reason, subnetId, spotInstanceRequestId, vpcId, rootDeviceType, rootDeviceName, - ebsBlockDevices)); - this.amiLaunchIndex = null; - this.dnsName = null; - this.imageId = null; - this.instanceId = null; - this.instanceState = null; - this.instanceType = null; - this.ipAddress = null; - this.kernelId = null; - this.keyName = null; - this.launchTime = null; - this.monitoringState = null; - this.availabilityZone = null; - this.placementGroup = null; - this.virtualizationType = "paravirtual"; - this.platform = null; - this.privateDnsName = null; - this.privateIpAddress = null; - this.productCodes = Sets.newHashSet(); - this.ramdiskId = null; - this.reason = null; - this.subnetId = null; - this.spotInstanceRequestId = null; - this.vpcId = null; - this.rootDeviceType = RootDeviceType.INSTANCE_STORE; - this.rootDeviceName = null; - this.ebsBlockDevices = Maps.newHashMap(); + return dateService.iso8601SecondsDateParse(currentOrNull()); } } + protected void inItem() { + if (endOfInstanceItem()) { + refineBuilderBeforeAddingInstance(); + instances.add(builder.build()); + builder = builderProvider.get(); + } + } + + protected void refineBuilderBeforeAddingInstance() { + String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null; + + // Eucalyptus + if (builder.getIpAddress() == null && builder.getDnsName() != null && builder.getDnsName().matches(".*[0-9]$")) { + builder.ipAddress(builder.getDnsName()); + builder.dnsName(null); + } + if (builder.getPrivateIpAddress() == null && builder.getPrivateDnsName() != null + && builder.getPrivateDnsName().matches(".*[0-9]$")) { + builder.privateIpAddress(builder.getPrivateDnsName()); + builder.privateDnsName(null); + } + + builder.region((region == null) ? defaultRegion : region); + builder.groupIds(groupIds); + } + + protected Builder builder() { + return builder; + } + + protected boolean endOfInstanceItem() { + return itemDepth <= 2 && inInstancesSet; + } + public void characters(char ch[], int start, int length) { currentText.append(ch, start, length); } @@ -295,7 +229,7 @@ public abstract class BaseReservationHandler extends HandlerForGeneratedReque if (region == null) region = defaultRegion; Reservation info = new Reservation(region, groupIds, instances, - ownerId, requesterId, reservationId); + ownerId, requesterId, reservationId); this.groupIds = Sets.newLinkedHashSet(); this.instances = Sets.newLinkedHashSet(); this.ownerId = null; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java index 57fc65e789..a63eb307e4 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeInstancesResponseHandler.java @@ -23,12 +23,13 @@ import java.util.Set; import javax.inject.Inject; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.date.DateService; import org.jclouds.location.Region; import com.google.common.collect.Sets; +import com.google.inject.Provider; /** * Parses the following XML document: @@ -43,8 +44,9 @@ public class DescribeInstancesResponseHandler extends private Set> reservations = Sets.newLinkedHashSet(); @Inject - DescribeInstancesResponseHandler(DateService dateService, @Region String defaultRegion) { - super(dateService, defaultRegion); + DescribeInstancesResponseHandler(DateService dateService, @Region String defaultRegion, + Provider builderProvider) { + super(dateService, defaultRegion, builderProvider); } @Override @@ -52,9 +54,13 @@ public class DescribeInstancesResponseHandler extends return reservations; } + protected boolean endOfReservationItem() { + return itemDepth == 1; + } + @Override protected void inItem() { - if (!inInstances && !inProductCodes && !inGroups) { + if (endOfReservationItem()) { reservations.add(super.newReservation()); } else { super.inItem(); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java index 5188ae029c..ab776e81f7 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/RunInstancesResponseHandler.java @@ -21,11 +21,13 @@ package org.jclouds.ec2.xml; import javax.inject.Inject; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.Reservation; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.date.DateService; import org.jclouds.location.Region; +import com.google.inject.Provider; + /** * Parses the following XML document: *

@@ -37,8 +39,9 @@ import org.jclouds.location.Region; public class RunInstancesResponseHandler extends BaseReservationHandler> { @Inject - RunInstancesResponseHandler(DateService dateService, @Region String defaultRegion) { - super(dateService, defaultRegion); + RunInstancesResponseHandler(DateService dateService, @Region String defaultRegion, + Provider builderProvider) { + super(dateService, defaultRegion, builderProvider); } @Override diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java index 52bf7daaa8..ae90573c74 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/EC2AsyncClientTest.java @@ -49,9 +49,7 @@ public class EC2AsyncClientTest extends BaseEC2AsyncClientTest { assert syncClient.getElasticIPAddressServices() != null; assert syncClient.getInstanceServices() != null; assert syncClient.getKeyPairServices() != null; - assert syncClient.getMonitoringServices() != null; assert syncClient.getSecurityGroupServices() != null; - assert syncClient.getPlacementGroupServices() != null; assert syncClient.getWindowsServices() != null; } @@ -63,9 +61,7 @@ public class EC2AsyncClientTest extends BaseEC2AsyncClientTest { assert asyncClient.getElasticIPAddressServices() != null; assert asyncClient.getInstanceServices() != null; assert asyncClient.getKeyPairServices() != null; - assert asyncClient.getMonitoringServices() != null; assert asyncClient.getSecurityGroupServices() != null; - assert asyncClient.getPlacementGroupServices() != null; assert asyncClient.getWindowsServices() != null; } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java index 61d4ed91c5..1c7f95a671 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceLiveTest.java @@ -21,7 +21,9 @@ package org.jclouds.ec2.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import java.util.Map; import java.util.Set; import org.jclouds.compute.BaseComputeServiceLiveTest; @@ -31,18 +33,26 @@ import org.jclouds.compute.domain.Template; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationScope; import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.InstanceType; import org.jclouds.ec2.domain.IpProtocol; import org.jclouds.ec2.domain.KeyPair; import org.jclouds.ec2.domain.RunningInstance; import org.jclouds.ec2.domain.SecurityGroup; +import org.jclouds.ec2.domain.Snapshot; +import org.jclouds.ec2.domain.Volume; +import org.jclouds.ec2.services.ElasticBlockStoreClient; import org.jclouds.ec2.services.InstanceClient; import org.jclouds.ec2.services.KeyPairClient; import org.jclouds.ec2.services.SecurityGroupClient; import org.jclouds.ssh.jsch.config.JschSshClientModule; import org.testng.annotations.Test; +import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; @@ -68,7 +78,7 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { public void testImagesResolveCorrectly() { Template defaultTemplate = client.templateBuilder().build(); assertEquals(defaultTemplate.getImage().getId(), defaultTemplate.getImage().getLocation().getId() + "/" - + defaultTemplate.getImage().getProviderId()); + + defaultTemplate.getImage().getProviderId()); Template byId = client.templateBuilder().imageId(defaultTemplate.getImage().getId()).build(); assertEquals(byId.getImage(), defaultTemplate.getImage()); } @@ -89,37 +99,34 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { @Test(enabled = true, dependsOnMethods = "testCompareSizes") public void testExtendedOptionsAndLogin() throws Exception { SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getSecurityGroupServices(); + .getSecurityGroupServices(); KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getKeyPairServices(); + .getKeyPairServices(); InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getInstanceServices(); + .getInstanceServices(); - String tag = this.tag + "o"; + String group = this.group + "o"; TemplateOptions options = client.templateOptions(); -// Date before = new Date(); - - options.as(EC2TemplateOptions.class).securityGroups(tag); - options.as(EC2TemplateOptions.class).keyPair(tag); - options.as(EC2TemplateOptions.class).enableMonitoring(); + options.as(EC2TemplateOptions.class).securityGroups(group); + options.as(EC2TemplateOptions.class).keyPair(group); String startedId = null; try { - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + cleanupExtendedStuff(securityGroupClient, keyPairClient, group); // create a security group that allows ssh in so that our scripts later // will work - securityGroupClient.createSecurityGroupInRegion(null, tag, tag); - securityGroupClient.authorizeSecurityGroupIngressInRegion(null, tag, IpProtocol.TCP, 22, 22, "0.0.0.0/0"); + securityGroupClient.createSecurityGroupInRegion(null, group, group); + securityGroupClient.authorizeSecurityGroupIngressInRegion(null, group, IpProtocol.TCP, 22, 22, "0.0.0.0/0"); // create a keypair to pass in as well - KeyPair result = keyPairClient.createKeyPairInRegion(null, tag); + KeyPair result = keyPairClient.createKeyPairInRegion(null, group); - Set nodes = client.runNodesWithTag(tag, 1, options); + Set nodes = client.createNodesInGroup(group, 1, options); NodeMetadata first = Iterables.get(nodes, 0); assert first.getCredentials() != null : first; assert first.getCredentials().identity != null : first; @@ -128,181 +135,123 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest { RunningInstance instance = getInstance(instanceClient, startedId); - assertEquals(instance.getKeyName(), tag); -// checkMonitoringEnabled(before, instance); + assertEquals(instance.getKeyName(), group); // make sure we made our dummy group and also let in the user's group - assertEquals(Sets.newTreeSet(instance.getGroupIds()), - ImmutableSortedSet. of("jclouds#" + tag + "#" + instance.getRegion(), tag)); + assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet. of("jclouds#" + group + "#" + + instance.getRegion(), group)); // make sure our dummy group has no rules - SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null, - "jclouds#" + tag + "#" + instance.getRegion())); - assert group.getIpPermissions().size() == 0 : group; + SecurityGroup secgroup = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null, + "jclouds#" + group + "#" + instance.getRegion())); + assert secgroup.getIpPermissions().size() == 0 : secgroup; // try to run a script with the original keyPair - runScriptWithCreds(tag, first.getOperatingSystem(), - new Credentials(first.getCredentials().identity, result.getKeyMaterial())); + runScriptWithCreds(group, first.getOperatingSystem(), new Credentials(first.getCredentials().identity, result + .getKeyMaterial())); } finally { - client.destroyNodesMatching(NodePredicates.withTag(tag)); + client.destroyNodesMatching(NodePredicates.inGroup(group)); if (startedId != null) { // ensure we didn't delete these resources! - assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1); - assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1); + assertEquals(keyPairClient.describeKeyPairsInRegion(null, group).size(), 1); + assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, group).size(), 1); } - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + cleanupExtendedStuff(securityGroupClient, keyPairClient, group); } } -// private void checkMonitoringEnabled(Date before, RunningInstance instance) { -// assertEquals(instance.getMonitoringState(), MonitoringState.ENABLED); -// -// RestContext monitoringContext = new RestContextFactory().createContext( -// "cloudwatch", identity, credential, ImmutableSet. of(new Log4JLoggingModule())); -// -// try { -// Set datapoints = monitoringContext.getApi().getMetricStatisticsInRegion(instance.getRegion(), -// "CPUUtilization", before, new Date(), 60, "Average"); -// assert datapoints != null; -// } finally { -// monitoringContext.close(); -// } -// } - - @Test(enabled = true, dependsOnMethods = "testCompareSizes") - public void testExtendedOptionsNoKeyPair() throws Exception { - SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getSecurityGroupServices(); - - KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getKeyPairServices(); + /** + * Note we cannot use the micro size as it has no ephemeral space. + */ + @Test(enabled = true) + public void testMapEBS() throws Exception { InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getInstanceServices(); + .getInstanceServices(); - String tag = this.tag + "k"; + ElasticBlockStoreClient ebsClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getElasticBlockStoreServices(); - TemplateOptions options = client.templateOptions(); + String group = this.group + "e"; + int volumeSize = 8; - options.as(EC2TemplateOptions.class).securityGroups(tag); - options.as(EC2TemplateOptions.class).noKeyPair(); + Location zone = Iterables.find(context.getComputeService().listAssignableLocations(), new Predicate() { + + @Override + public boolean apply(Location arg0) { + return arg0.getScope() == LocationScope.ZONE; + } + + }); + + // create volume only to make a snapshot + Volume volume = ebsClient.createVolumeInAvailabilityZone(zone.getId(), 4); + Snapshot snapshot = ebsClient.createSnapshotInRegion(volume.getRegion(), volume.getId()); + ebsClient.deleteVolumeInRegion(volume.getRegion(), volume.getId()); + + Template template = context.getComputeService().templateBuilder().locationId(volume.getRegion()).hardwareId( + InstanceType.M1_SMALL).imageDescriptionMatches(".*ebs.*").build(); + + template.getOptions().as(EC2TemplateOptions.class)// + // .unmapDeviceNamed("/dev/foo) + .mapEphemeralDeviceToDeviceName("/dev/sdm", "ephemeral0")// + .mapNewVolumeToDeviceName("/dev/sdn", volumeSize, true)// + .mapEBSSnapshotToDeviceName("/dev/sdo", snapshot.getId(), volumeSize, true); - String startedId = null; try { - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + NodeMetadata node = Iterables.getOnlyElement(client.createNodesInGroup(group, 1, template)); - // create the security group - securityGroupClient.createSecurityGroupInRegion(null, tag, tag); + // TODO figure out how to validate the ephemeral drive. perhaps with df -k? - Set nodes = client.runNodesWithTag(tag, 1, options); - Credentials creds = nodes.iterator().next().getCredentials(); - assert creds == null; + Map devices = instanceClient.getBlockDeviceMappingForInstanceInRegion(node.getLocation() + .getParent().getId(), node.getProviderId()); - startedId = Iterables.getOnlyElement(nodes).getProviderId(); + BlockDevice device = devices.get("/dev/sdn"); + // check delete on termination + assertTrue(device.isDeleteOnTermination()); - RunningInstance instance = getInstance(instanceClient, startedId); + volume = Iterables.getOnlyElement(ebsClient.describeVolumesInRegion(node.getLocation().getParent().getId(), + device.getVolumeId())); + // check volume size + assertEquals(volumeSize, volume.getSize()); - assertEquals(instance.getKeyName(), null); + device = devices.get("/dev/sdo"); + // check delete on termination + assertTrue(device.isDeleteOnTermination()); - // make sure we made our dummy group and also let in the user's group - assertEquals(Sets.newTreeSet(instance.getGroupIds()), - ImmutableSortedSet. of(tag, String.format("jclouds#%s#%s", tag, instance.getRegion()))); - - // make sure our dummy group has no rules - SecurityGroup group = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null, - String.format("jclouds#%s#%s", tag, instance.getRegion()))); - assert group.getIpPermissions().size() == 0 : group; + volume = Iterables.getOnlyElement(ebsClient.describeVolumesInRegion(node.getLocation().getParent().getId(), + device.getVolumeId())); + // check volume size + assertEquals(volumeSize, volume.getSize()); + // check volume's snapshot id + assertEquals(snapshot.getId(), volume.getSnapshotId()); } finally { - client.destroyNodesMatching(NodePredicates.withTag(tag)); - if (startedId != null) { - // ensure we didn't delete these resources! - assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, tag).size(), 1); - } - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); + client.destroyNodesMatching(NodePredicates.inGroup(group)); + ebsClient.deleteSnapshotInRegion(snapshot.getRegion(), snapshot.getId()); } } - @Test(enabled = true, dependsOnMethods = "testCompareSizes") - public void testExtendedOptionsWithSubnetId() throws Exception { - - String subnetId = System.getProperty("test.subnetId"); - if (subnetId == null) { - // Skip test and return - return; - } - SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getSecurityGroupServices(); - - KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getKeyPairServices(); - - InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) - .getInstanceServices(); - - String tag = this.tag + "g"; - - TemplateOptions options = client.templateOptions(); - - // options.as(EC2TemplateOptions.class).securityGroups(tag); - options.as(EC2TemplateOptions.class).keyPair(tag); - options.as(EC2TemplateOptions.class).subnetId(subnetId); - - String startedId = null; - String nodeId = null; - try { - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); - - // create the security group - // securityGroupClient.createSecurityGroupInRegion(null, tag, tag); - - // create a keypair to pass in as well - keyPairClient.createKeyPairInRegion(null, tag); - - Set nodes = client.runNodesWithTag(tag, 1, options); - - NodeMetadata first = Iterables.get(nodes, 0); - assert first.getCredentials() != null : first; - assert first.getCredentials().identity != null : first; - - startedId = Iterables.getOnlyElement(nodes).getProviderId(); - nodeId = Iterables.getOnlyElement(nodes).getId(); - - RunningInstance instance = getInstance(instanceClient, startedId); - - assertEquals(instance.getSubnetId(), subnetId); - - } finally { - if (nodeId != null) - client.destroyNode(nodeId); - if (startedId != null) { - // ensure we didn't delete these resources! - assertEquals(keyPairClient.describeKeyPairsInRegion(null, tag).size(), 1); - } - cleanupExtendedStuff(securityGroupClient, keyPairClient, tag); - } - } - - private RunningInstance getInstance(InstanceClient instanceClient, String id) { + protected RunningInstance getInstance(InstanceClient instanceClient, String id) { RunningInstance instance = Iterables.getOnlyElement(Iterables.getOnlyElement(instanceClient - .describeInstancesInRegion(null, id))); + .describeInstancesInRegion(null, id))); return instance; } - private void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String tag) - throws InterruptedException { + protected void cleanupExtendedStuff(SecurityGroupClient securityGroupClient, KeyPairClient keyPairClient, String group) + throws InterruptedException { try { - for (SecurityGroup group : securityGroupClient.describeSecurityGroupsInRegion(null)) - if (group.getName().startsWith("jclouds#" + tag) || group.getName().equals(tag)) { - securityGroupClient.deleteSecurityGroupInRegion(null, group.getName()); + for (SecurityGroup secgroup : securityGroupClient.describeSecurityGroupsInRegion(null)) + if (secgroup.getName().startsWith("jclouds#" + group) || secgroup.getName().equals(group)) { + securityGroupClient.deleteSecurityGroupInRegion(null, secgroup.getName()); } } catch (Exception e) { } try { for (KeyPair pair : keyPairClient.describeKeyPairsInRegion(null)) - if (pair.getKeyName().startsWith("jclouds#" + tag) || pair.getKeyName().equals(tag)) { + if (pair.getKeyName().startsWith("jclouds#" + group) || pair.getKeyName().equals(group)) { keyPairClient.deleteKeyPairInRegion(null, pair.getKeyName()); } } catch (Exception e) { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceTest.java deleted file mode 100644 index 5e61476aea..0000000000 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2ComputeServiceTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.ec2.compute; - -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 java.util.Map; -import java.util.concurrent.ExecutorService; - -import javax.inject.Provider; - -import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; -import org.jclouds.compute.strategy.DestroyNodeStrategy; -import org.jclouds.compute.strategy.GetNodeMetadataStrategy; -import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; -import org.jclouds.compute.strategy.ListNodesStrategy; -import org.jclouds.compute.strategy.RebootNodeStrategy; -import org.jclouds.compute.strategy.ResumeNodeStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; -import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.services.PlacementGroupClient; -import org.testng.annotations.Test; - -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; - -/** - * @author Adrian Cole - */ -@Test(groups = "unit") -public class EC2ComputeServiceTest { - - @SuppressWarnings( { "unchecked" }) - public void testUnsupportedOperationOkForPlacementGroups() { - EC2Client client = createMock(EC2Client.class); - EC2ComputeService service = new EC2ComputeService(createMock(ComputeServiceContext.class), createMock(Map.class), - createMock(Supplier.class), createMock(Supplier.class), createMock(Supplier.class), - createMock(ListNodesStrategy.class), createMock(GetNodeMetadataStrategy.class), - createMock(RunNodesAndAddToSetStrategy.class), createMock(RebootNodeStrategy.class), - createMock(DestroyNodeStrategy.class), createMock(ResumeNodeStrategy.class), - createMock(SuspendNodeStrategy.class), createMock(Provider.class), createMock(Provider.class), - createMock(Predicate.class), createMock(Predicate.class), createMock(Predicate.class), - createMock(InitializeRunScriptOnNodeOrPlaceInBadMap.Factory.class), - createMock(Timeouts.class), createMock(ExecutorService.class), client, createMock(Map.class), - createMock(Map.class), createMock(Map.class), createMock(Predicate.class)); - - PlacementGroupClient placementClient = createMock(PlacementGroupClient.class); - - // setup expectations - expect(client.getPlacementGroupServices()).andReturn(placementClient).atLeastOnce(); - expect(placementClient.describePlacementGroupsInRegion("us-west-1", "jclouds#tag#us-west-1")).andThrow( - new UnsupportedOperationException()); - - // replay mocks - replay(client); - replay(placementClient); - // run - service.deletePlacementGroup("us-west-1", "tag"); - - // verify mocks - verify(client); - verify(placementClient); - - } -} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderTest.java index 0a379d03bd..a5b3b0e463 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/EC2TemplateBuilderTest.java @@ -51,8 +51,8 @@ import org.jclouds.compute.domain.internal.TemplateBuilderImpl; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.testng.annotations.Test; import com.google.common.base.Function; @@ -71,7 +71,8 @@ import com.google.common.collect.ImmutableSet; * @author Oleksiy Yarmula */ public class EC2TemplateBuilderTest { - private static final Location location = new LocationImpl(LocationScope.REGION, "us-east-1", "us east", null); + private static final Location location = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1") + .description("us-east-1").build(); public static final Hardware CC1_4XLARGE = cc1_4xlarge().location(location).supportsImageIds("us-east-1/cc-image") .build(); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateTagLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java similarity index 92% rename from apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateTagLiveTest.java rename to apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java index b60e820ea8..504d3654ae 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateTagLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/TestCanRecreateGroupLiveTest.java @@ -46,7 +46,7 @@ import com.google.inject.Module; * @author Adrian Cole */ @Test(groups = "live") -public class TestCanRecreateTagLiveTest { +public class TestCanRecreateGroupLiveTest { private ComputeServiceContext context; protected String provider = "ec2"; @@ -85,21 +85,21 @@ public class TestCanRecreateTagLiveTest { ImmutableSet. of(new Log4JLoggingModule(), new JschSshClientModule()), overrides); } - public void testCanRecreateTag() throws Exception { + public void testCanRecreateGroup() throws Exception { String tag = PREFIX + "recreate"; - context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); + context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); try { Template template = context.getComputeService().templateBuilder().locationId("us-west-1").build(); - context.getComputeService().runNodesWithTag(tag, 1, template); - context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); - context.getComputeService().runNodesWithTag(tag, 1, template); + context.getComputeService().createNodesInGroup(tag, 1, template); + context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); + context.getComputeService().createNodesInGroup(tag, 1, template); } catch (RunNodesException e) { System.err.println(e.getNodeErrors().keySet()); Throwables.propagate(e); } finally { - context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); + context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(tag)); } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CredentialsForInstanceTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CredentialsForInstanceTest.java deleted file mode 100644 index 4a41652874..0000000000 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/CredentialsForInstanceTest.java +++ /dev/null @@ -1,833 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.ec2.compute.functions; - -import org.jclouds.date.DateService; -import org.jclouds.date.internal.SimpleDateFormatDateService; -import org.testng.annotations.Test; - -/** - * @author Adrian Cole - */ -@Test(groups = "unit") -public class CredentialsForInstanceTest { - - DateService dateService = new SimpleDateFormatDateService(); - -// @SuppressWarnings({ "unchecked" }) -// @Test -// public void testApplyWithEBSWhenBootIsInstanceStoreAndAvailabilityZoneNotFound() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); -// Map credentialsMap = createMock(Map.class); -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m1_small().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// Image image = createMock(Image.class); -// -// expect(instance.getId()).andReturn("i-3d640055").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet.of("default")).atLeastOnce(); -// expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1d", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// expect(instance.getIpAddress()).andReturn("174.129.1.50"); -// expect(instance.getPrivateIpAddress()).andReturn("10.202.117.241"); -// -// expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("ami-1515f07c").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); -// -// expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( -// (Set) ImmutableSet. of(image)); -// -// expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); -// -// expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "jclouds#tag#us-east-1#50"))).andReturn( -// new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.M1_SMALL).atLeastOnce(); -// expect(instance.getEbsBlockDevices()).andReturn( -// ImmutableMap. of( -// "/dev/sdg", -// new EbsBlockDevice("vol-1f20d376", Attachment.Status.ATTACHED, dateService -// .iso8601DateParse("2009-12-11T16:32:46.000Z"), false), -// "/dev/sdj", -// new EbsBlockDevice("vol-c0eb78aa", Attachment.Status.ATTACHED, dateService -// .iso8601DateParse("2010-06-17T10:43:28.000Z"), false))); -// expect(instance.getRootDeviceType()).andReturn(RootDeviceType.INSTANCE_STORE); -// expect(instance.getRootDeviceName()).andReturn(null).atLeastOnce(); -// -// replay(imageMap); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// replay(jcImage); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// -// assertEquals(metadata.getTag(), "NOTAG#i-3d640055"); -// assertEquals(metadata.getLocation(), null); -// assertEquals(metadata.getImageId(), "us-east-1/ami-1515f07c"); -// assertEquals(metadata.getHardware().getId(), "m1.small"); -// assertEquals(metadata.getHardware().getName(), "m1.small"); -// assertEquals(metadata.getHardware().getProviderId(), "m1.small"); -// assertEquals(metadata.getHardware().getProcessors(), ImmutableList. of(new Processor(1.0, 1.0))); -// assertEquals(metadata.getHardware().getRam(), 1740); -// assertEquals(metadata.getHardware().getVolumes(), -// ImmutableList. of(new VolumeImpl(null, Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// -// new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false),// -// new VolumeImpl("vol-1f20d376", Volume.Type.SAN, null, "/dev/sdg", false, true),// -// new VolumeImpl("vol-c0eb78aa", Volume.Type.SAN, null, "/dev/sdj", false, true))); -// -// assertEquals(metadata.getCredentials(), new Credentials("user", "pass")); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// -// } -// -// @SuppressWarnings({ "unchecked" }) -// @Test -// public void testApplyForNovaWhereNullAvailabilityZoneIpAddressNoGroups() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); -// Map credentialsMap = createMock(Map.class); -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m1_small().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// Image image = createMock(Image.class); -// -// expect(instance.getId()).andReturn("i-3d640055").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet. of()).atLeastOnce(); -// expect(instance.getKeyName()).andReturn("nebulatanimislam").atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(region)); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// expect(instance.getIpAddress()).andReturn(null); -// expect(instance.getPrivateIpAddress()).andReturn("10.202.117.241"); -// -// expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("ami-1515f07c").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); -// -// expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( -// (Set) ImmutableSet. of(image)); -// -// expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); -// -// expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "nebulatanimislam"))).andReturn(null); -// -// expect(instance.getAvailabilityZone()).andReturn(null).atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.M1_SMALL).atLeastOnce(); -// expect(instance.getEbsBlockDevices()).andReturn(Maps. newHashMap()); -// expect(instance.getRootDeviceType()).andReturn(RootDeviceType.INSTANCE_STORE); -// -// replay(imageMap); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// replay(jcImage); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// -// assertEquals(metadata.getTag(), "NOTAG#i-3d640055"); -// assertEquals(metadata.getLocation(), region); -// assertEquals(metadata.getImageId(), "us-east-1/ami-1515f07c"); -// assertEquals(metadata.getHardware().getId(), "m1.small"); -// assertEquals(metadata.getHardware().getName(), "m1.small"); -// assertEquals(metadata.getHardware().getProviderId(), "m1.small"); -// assertEquals(metadata.getHardware().getProcessors(), ImmutableList. of(new Processor(1.0, 1.0))); -// assertEquals(metadata.getHardware().getRam(), 1740); -// assertEquals(metadata.getHardware().getVolumes(), -// ImmutableList. of(new VolumeImpl(null, Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// -// new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false))); -// -// assertEquals(metadata.getCredentials(), new Credentials("user", null)); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// -// } -// -// @SuppressWarnings({ "unchecked" }) -// @Test -// public void testApplyWhereUnknownInstanceType() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); -// Map credentialsMap = createMock(Map.class); -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m1_small().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// Image image = createMock(Image.class); -// -// expect(instance.getId()).andReturn("i-3d640055").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet. of()).atLeastOnce(); -// expect(instance.getKeyName()).andReturn("nebulatanimislam").atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(region)); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// expect(instance.getIpAddress()).andReturn(null); -// expect(instance.getPrivateIpAddress()).andReturn("10.202.117.241"); -// -// expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("ami-1515f07c").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); -// -// expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( -// (Set) ImmutableSet. of(image)); -// -// expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); -// -// expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "nebulatanimislam"))).andReturn(null); -// -// expect(instance.getAvailabilityZone()).andReturn(null).atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn("hhttpp").atLeastOnce(); -// -// replay(imageMap); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// replay(jcImage); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// -// assertEquals(metadata.getTag(), "NOTAG#i-3d640055"); -// assertEquals(metadata.getLocation(), region); -// assertEquals(metadata.getImageId(), "us-east-1/ami-1515f07c"); -// assertEquals(metadata.getHardware(), null); -// -// assertEquals(metadata.getCredentials(), new Credentials("user", null)); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// -// } -// -// @SuppressWarnings({ "unchecked" }) -// @Test -// public void testApplyForNovaWhereImageNotFound() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); -// Map credentialsMap = createMock(Map.class); -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m1_small().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// -// expect(instance.getId()).andReturn("i-3d640055").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet. of()).atLeastOnce(); -// expect(instance.getKeyName()).andReturn("nebulatanimislam").atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// Location region = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(region)); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// expect(instance.getIpAddress()).andReturn(null); -// expect(instance.getPrivateIpAddress()).andReturn("10.202.117.241"); -// -// expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("ami-1515f07c").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "ami-1515f07c"))).andReturn(jcImage); -// -// expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("ami-1515f07c"))).andReturn( -// (Set) ImmutableSet. of()); -// -// expect(credentialProvider.execute(null)).andReturn(new Credentials("root", null)); -// -// expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "nebulatanimislam"))).andReturn(null); -// -// expect(instance.getAvailabilityZone()).andReturn(null).atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.M1_SMALL).atLeastOnce(); -// expect(instance.getEbsBlockDevices()).andReturn(Maps. newHashMap()); -// expect(instance.getRootDeviceType()).andReturn(RootDeviceType.INSTANCE_STORE); -// -// replay(imageMap); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// replay(jcImage); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// -// assertEquals(metadata.getTag(), "NOTAG#i-3d640055"); -// assertEquals(metadata.getLocation(), region); -// assertEquals(metadata.getImageId(), "us-east-1/ami-1515f07c"); -// assertEquals(metadata.getHardware().getId(), "m1.small"); -// assertEquals(metadata.getHardware().getName(), "m1.small"); -// assertEquals(metadata.getHardware().getProviderId(), "m1.small"); -// assertEquals(metadata.getHardware().getProcessors(), ImmutableList. of(new Processor(1.0, 1.0))); -// assertEquals(metadata.getHardware().getRam(), 1740); -// assertEquals(metadata.getHardware().getVolumes(), -// ImmutableList. of(new VolumeImpl(null, Volume.Type.LOCAL, 10.0f, "/dev/sda1", true, false),// -// new VolumeImpl(null, Volume.Type.LOCAL, 150.0f, "/dev/sda2", false, false))); -// -// assertEquals(metadata.getCredentials(), new Credentials("root", null)); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// -// } -// -// @SuppressWarnings("unchecked") -// @Test -// public void testImageNotFoundAndLazyReturnsNull() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// -// Map credentialsMap = createMock(Map.class); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m2_4xlarge().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// -// expect(instance.getId()).andReturn("id").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet. of()).atLeastOnce(); -// expect(instance.getKeyName()).andReturn(null).atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// expect(instance.getIpAddress()).andReturn("127.0.0.1"); -// expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); -// expect(instance.getRegion()).andReturn("us-east-1").atLeastOnce(); -// -// expect(imageMap.get(new RegionAndName("us-east-1", "imageId"))).andReturn(null); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); -// -// replay(imageMap); -// replay(jcImage); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// assertEquals(metadata.getLocation(), locations.get().iterator().next()); -// assertEquals(metadata.getImageId(), "us-east-1/imageId"); -// assertEquals(metadata.getTag(), "NOTAG#id"); -// assertEquals(metadata.getCredentials(), null); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// } -// -// @SuppressWarnings("unchecked") -// @Test -// public void testImageNotFoundStillSetsImageId() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// Map credentialsMap = createMock(Map.class); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m2_4xlarge().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// -// expect(instance.getId()).andReturn("id").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet. of()).atLeastOnce(); -// expect(instance.getKeyName()).andReturn(null).atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// expect(instance.getIpAddress()).andReturn("127.0.0.1"); -// expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); -// expect(instance.getRegion()).andReturn("us-east-1").atLeastOnce(); -// -// expect(imageMap.get(new RegionAndName("us-east-1", "imageId"))).andThrow(new NullPointerException()) -// .atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); -// -// replay(imageMap); -// replay(jcImage); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// assertEquals(metadata.getLocation(), locations.get().iterator().next()); -// assertEquals(metadata.getImageId(), "us-east-1/imageId"); -// assertEquals(metadata.getTag(), "NOTAG#id"); -// assertEquals(metadata.getCredentials(), null); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// } -// -// @SuppressWarnings("unchecked") -// @Test -// public void testImageNotFoundAndLazySucceeds() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// Map credentialsMap = createMock(Map.class); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m2_4xlarge().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// -// expect(instance.getId()).andReturn("id").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet. of()).atLeastOnce(); -// expect(instance.getKeyName()).andReturn(null).atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// expect(instance.getIpAddress()).andReturn("127.0.0.1"); -// expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); -// expect(instance.getRegion()).andReturn("us-east-1").atLeastOnce(); -// -// org.jclouds.compute.domain.Image lateImage = createMock(org.jclouds.compute.domain.Image.class); -// -// expect(imageMap.get(new RegionAndName("us-east-1", "imageId"))).andReturn(lateImage).atLeastOnce(); -// expect(lateImage.getId()).andReturn("us-east-1/imageId").atLeastOnce(); -// expect(lateImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); -// -// replay(lateImage); -// replay(imageMap); -// replay(jcImage); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// assertEquals(metadata.getLocation(), locations.get().iterator().next()); -// assertEquals(metadata.getImageId(), lateImage.getId()); -// assertEquals(metadata.getTag(), "NOTAG#id"); -// assertEquals(metadata.getCredentials(), null); -// -// verify(lateImage); -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// } -// -// @SuppressWarnings("unchecked") -// @Test -// public void testApplyWithNoSecurityGroupCreatesTagOfIdPrefixedByTagAndNullCredentials() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// Map credentialsMap = createMock(Map.class); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m2_4xlarge().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// -// expect(instance.getId()).andReturn("id").atLeastOnce(); -// expect(instance.getRegion()).andReturn("us-east-1").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet. of()).atLeastOnce(); -// expect(instance.getKeyName()).andReturn(null).atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// expect(instance.getIpAddress()).andReturn("127.0.0.1"); -// expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "imageId"))).andReturn(jcImage); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); -// -// replay(imageMap); -// replay(jcImage); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// assertEquals(metadata.getLocation(), locations.get().iterator().next()); -// assertEquals(metadata.getImageId(), "us-east-1/imageId"); -// assertEquals(metadata.getTag(), "NOTAG#id"); -// assertEquals(metadata.getCredentials(), null); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// } -// -// @SuppressWarnings("unchecked") -// @Test -// public void testApplyWithNoKeyPairCreatesTagOfParsedSecurityGroupAndNullCredentials() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// Map credentialsMap = createMock(Map.class); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m2_4xlarge().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// -// expect(instance.getId()).andReturn("id").atLeastOnce(); -// expect(instance.getRegion()).andReturn("us-east-1").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds#tag#us-east-1")).atLeastOnce(); -// expect(instance.getKeyName()).andReturn(null).atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// expect(instance.getIpAddress()).andReturn("127.0.0.1"); -// expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "imageId"))).andReturn(jcImage); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); -// -// replay(imageMap); -// replay(jcImage); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// assertEquals(metadata.getLocation(), locations.get().iterator().next()); -// assertEquals(metadata.getImageId(), "us-east-1/imageId"); -// assertEquals(metadata.getTag(), "tag"); -// assertEquals(metadata.getCredentials(), null); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// } -// -// @SuppressWarnings({ "unchecked" }) -// @Test -// public void testApplyWithKeyPairCreatesTagOfParsedSecurityGroupAndCredentialsBasedOnIt() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); -// Map credentialsMap = createMock(Map.class); -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m2_4xlarge().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// Image image = createMock(Image.class); -// -// expect(instance.getId()).andReturn("id").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds#tag#us-east-1")).atLeastOnce(); -// expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// expect(instance.getIpAddress()).andReturn("127.0.0.1"); -// expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); -// -// expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "imageId"))).andReturn(jcImage); -// -// expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("imageId"))).andReturn( -// (Set) ImmutableSet. of(image)); -// -// expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); -// -// expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "jclouds#tag#us-east-1#50"))).andReturn( -// new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); -// -// replay(imageMap); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// replay(jcImage); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// NodeMetadata metadata = parser.apply(instance); -// -// assertEquals(metadata.getTag(), "tag"); -// assertEquals(metadata.getLocation(), location); -// assertEquals(metadata.getImageId(), "us-east-1/imageId"); -// -// assertEquals(metadata.getCredentials(), new Credentials("user", "pass")); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// -// } -// -// @SuppressWarnings({ "unchecked" }) -// @Test -// public void testApplyWithTwoSecurityGroups() throws UnknownHostException { -// EC2Client client = createMock(EC2Client.class); -// AMIClient amiClient = createMock(AMIClient.class); -// expect(client.getAMIServices()).andReturn(amiClient).atLeastOnce(); -// Map credentialsMap = createMock(Map.class); -// ConcurrentMap imageMap = createMock(ConcurrentMap.class); -// @Memoized Supplier> hardwares = Suppliers.> ofInstance(ImmutableSet -// . of(m2_4xlarge().build())); -// PopulateDefaultLoginCredentialsForImageStrategy credentialProvider = createMock(PopulateDefaultLoginCredentialsForImageStrategy.class); -// RunningInstance instance = createMock(RunningInstance.class); -// Image image = createMock(Image.class); -// -// expect(instance.getId()).andReturn("id").atLeastOnce(); -// expect(instance.getGroupIds()).andReturn(ImmutableSet.of("jclouds1", "jclouds2")).atLeastOnce(); -// expect(instance.getKeyName()).andReturn("jclouds#tag#us-east-1#50").atLeastOnce(); -// expect(instance.getInstanceState()).andReturn(InstanceState.RUNNING); -// -// Location location = new LocationImpl(LocationScope.ZONE, "us-east-1a", "description", null); -// @Memoized Supplier> locations = Suppliers.> ofInstance(ImmutableSet -// . of(location)); -// org.jclouds.compute.domain.Image jcImage = createMock(org.jclouds.compute.domain.Image.class); -// -// expect(instance.getIpAddress()).andReturn("127.0.0.1"); -// expect(instance.getPrivateIpAddress()).andReturn("127.0.0.1"); -// -// expect(instance.getRegion()).andReturn(Region.US_EAST_1).atLeastOnce(); -// -// expect(jcImage.getOperatingSystem()).andReturn(createMock(OperatingSystem.class)).atLeastOnce(); -// -// expect(instance.getImageId()).andReturn("imageId").atLeastOnce(); -// expect(imageMap.get(new RegionAndName(Region.US_EAST_1, "imageId"))).andReturn(jcImage); -// -// expect(amiClient.describeImagesInRegion(Region.US_EAST_1, imageIds("imageId"))).andReturn( -// (Set) ImmutableSet. of(image)); -// -// expect(credentialProvider.execute(image)).andReturn(new Credentials("user", "pass")); -// -// expect(credentialsMap.get(new RegionAndName(Region.US_EAST_1, "jclouds#tag#us-east-1#50"))).andReturn( -// new KeyPair(Region.US_EAST_1, "jclouds#tag#us-east-1#50", "keyFingerprint", "pass")); -// -// expect(instance.getAvailabilityZone()).andReturn(AvailabilityZone.US_EAST_1A).atLeastOnce(); -// -// expect(instance.getInstanceType()).andReturn(InstanceType.C1_XLARGE).atLeastOnce(); -// -// replay(imageMap); -// replay(client); -// replay(amiClient); -// replay(credentialsMap); -// replay(credentialProvider); -// replay(instance); -// replay(jcImage); -// -// Function parser = new CredentialsForInstance(client, credentialsMap, -// credentialProvider, imageMap, locations, hardwares); -// -// NodeMetadata metadata = parser.apply(instance); -// -// assertEquals(metadata.getTag(), "NOTAG#id"); -// assertEquals(metadata.getLocation(), location); -// assertEquals(metadata.getImageId(), "us-east-1/imageId"); -// -// assertEquals(metadata.getCredentials(), new Credentials("user", "pass")); -// -// verify(imageMap); -// verify(jcImage); -// verify(client); -// verify(amiClient); -// verify(credentialsMap); -// verify(credentialProvider); -// verify(instance); -// -// } -} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2ImageParserTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2ImageParserTest.java index 485fea963c..d38db5275e 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2ImageParserTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/EC2ImageParserTest.java @@ -31,8 +31,8 @@ import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.ec2.compute.strategy.EC2PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.ec2.compute.strategy.ReviseParsedImage; import org.jclouds.ec2.domain.Image; @@ -74,7 +74,8 @@ public class EC2ImageParserTest { ImmutableMap.of("owner", "137112412989", "rootDeviceType", "ebs")).build()); } - static Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", "us-east-1", null); + static Location defaultLocation = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1").description( + "us-east-1").build(); public static Set convertImages(String resource) { @@ -85,7 +86,7 @@ public class EC2ImageParserTest { Set result = DescribeImagesResponseHandlerTest.parseImages(resource); EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, Suppliers.> ofInstance(ImmutableSet. of(defaultLocation)), Suppliers - .ofInstance(defaultLocation), "ec2", new ReviseParsedImage.NoopReviseParsedImage()); + .ofInstance(defaultLocation), new ReviseParsedImage.NoopReviseParsedImage()); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java index b8246cc91c..e71aef38ac 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/functions/RunningInstanceToNodeMetadataTest.java @@ -36,8 +36,8 @@ import org.jclouds.compute.domain.OperatingSystemBuilder; import org.jclouds.compute.domain.OsFamily; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.ec2.compute.config.EC2ComputeServiceDependenciesModule; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.domain.InstanceState; @@ -67,7 +67,8 @@ public class RunningInstanceToNodeMetadataTest { } - Location provider = new LocationImpl(LocationScope.REGION, "us-east-1", "description", null); + static Location provider = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1") + .description("us-east-1").build(); @Test public void testApplyWhereTagDoesntMatchAndImageHardwareAndLocationNotFoundButCredentialsFound() @@ -76,14 +77,14 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet . of(), ImmutableSet. of(), ImmutableMap. of( - "node#us-east-1/i-9slweygo", creds)); + "node#us-east-1/i-0799056f", creds)); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).publicAddresses( - ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo") - .credentials(creds).imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-9slweygo") - .providerId("i-9slweygo").build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).publicAddresses( + ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.243.42.70")).publicAddresses( + ImmutableSet.of("174.129.81.68")).credentials(creds).imageId("us-east-1/ami-82e4b5c7").id( + "us-east-1/i-0799056f").providerId("i-0799056f").build()); } @Test @@ -91,11 +92,12 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet . of(), ImmutableSet. of(), ImmutableMap. of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).publicAddresses( - ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo") - .imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-9slweygo").providerId("i-9slweygo").build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).publicAddresses( + ImmutableSet. of()).privateAddresses(ImmutableSet.of("10.243.42.70")).publicAddresses( + ImmutableSet.of("174.129.81.68")).imageId("us-east-1/ami-82e4b5c7").id("us-east-1/i-0799056f") + .providerId("i-0799056f").build()); } @Test @@ -103,11 +105,11 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet.of(provider), ImmutableSet. of(), ImmutableMap. of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7").id( - "us-east-1/i-9slweygo").providerId("i-9slweygo").location(provider).build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).imageId( + "us-east-1/ami-82e4b5c7").id("us-east-1/i-0799056f").providerId("i-0799056f").location(provider).build()); } @Test @@ -115,14 +117,14 @@ public class RunningInstanceToNodeMetadataTest { RunningInstanceToNodeMetadata parser = createNodeParser(ImmutableSet. of(), ImmutableSet.of(provider), EC2ImageParserTest.convertImages("/amzn_images.xml"), ImmutableMap. of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7") - .operatingSystem( - new OperatingSystemBuilder().family(OsFamily.UNRECOGNIZED).version("").arch("paravirtual") - .description("137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id( - "us-east-1/i-9slweygo").providerId("i-9slweygo").location(provider).build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).imageId( + "us-east-1/ami-82e4b5c7").operatingSystem( + new OperatingSystemBuilder().family(OsFamily.UNRECOGNIZED).version("").arch("paravirtual").description( + "137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id("us-east-1/i-0799056f") + .providerId("i-0799056f").location(provider).build()); } @Test @@ -131,14 +133,14 @@ public class RunningInstanceToNodeMetadataTest { .of(provider), EC2ImageParserTest.convertImages("/amzn_images.xml"), ImmutableMap . of()); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7").hardware( - m1_small().build()).operatingSystem( + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).imageId( + "us-east-1/ami-82e4b5c7").hardware(m1_small().build()).operatingSystem( new OperatingSystemBuilder().family(OsFamily.UNRECOGNIZED).version("").arch("paravirtual").description( - "137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id("us-east-1/i-9slweygo") - .providerId("i-9slweygo").location(provider).build()); + "137112412989/amzn-ami-0.9.7-beta.i386-ebs").is64Bit(false).build()).id("us-east-1/i-0799056f") + .providerId("i-0799056f").location(provider).build()); } @Test @@ -160,11 +162,12 @@ public class RunningInstanceToNodeMetadataTest { .of(provider), ImmutableMap. of(), EC2ComputeServiceDependenciesModule.instanceToNodeState, instanceToImage); - RunningInstance server = firstInstanceFromResource("/describe_instances_nova.xml"); + RunningInstance server = firstInstanceFromResource("/describe_instances_running.xml"); - assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.TERMINATED).privateAddresses( - ImmutableSet.of("10.128.207.5")).tag("NOTAG#i-9slweygo").imageId("us-east-1/ami-82e4b5c7").id( - "us-east-1/i-9slweygo").providerId("i-9slweygo").hardware(m1_small().build()).location(provider).build()); + assertEquals(parser.apply(server), new NodeMetadataBuilder().state(NodeState.RUNNING).privateAddresses( + ImmutableSet.of("10.243.42.70")).publicAddresses(ImmutableSet.of("174.129.81.68")).imageId( + "us-east-1/ami-82e4b5c7").id("us-east-1/i-0799056f").providerId("i-0799056f").hardware( + m1_small().build()).location(provider).build()); } protected RunningInstance firstInstanceFromResource(String resource) { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImplTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImplTest.java index 4c5b906f4c..42f03fb7bc 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImplTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/internal/EC2TemplateBuilderImplTest.java @@ -32,8 +32,6 @@ import java.util.concurrent.ConcurrentMap; import javax.inject.Provider; -import org.jclouds.ec2.compute.domain.RegionAndName; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.jclouds.collect.Memoized; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; @@ -43,8 +41,10 @@ import org.jclouds.compute.domain.internal.TemplateBuilderImpl; import org.jclouds.compute.domain.internal.TemplateBuilderImplTest; import org.jclouds.compute.options.TemplateOptions; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; import org.testng.annotations.Test; import com.google.common.base.Function; @@ -89,7 +89,7 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest { @SuppressWarnings("unchecked") @Test public void testParseOnDemand() { - Location location = new LocationImpl(LocationScope.REGION, "region", "region", null); + Location location = new LocationBuilder().scope(LocationScope.REGION).id("region").description("region").build(); Supplier> locations = Suppliers.> ofInstance(ImmutableSet . of(location)); @@ -142,7 +142,7 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest { @SuppressWarnings("unchecked") @Test public void testParseOnDemandWithoutRegionEncodedIntoId() { - Location location = new LocationImpl(LocationScope.REGION, "region", "region", null); + Location location = new LocationBuilder().scope(LocationScope.REGION).id("region").description("region").build(); Supplier> locations = Suppliers.> ofInstance(ImmutableSet . of(location)); @@ -179,7 +179,7 @@ public class EC2TemplateBuilderImplTest extends TemplateBuilderImplTest { @SuppressWarnings("unchecked") @Test(expectedExceptions = NoSuchElementException.class) public void testParseOnDemandNotFound() { - Location location = new LocationImpl(LocationScope.REGION, "region", "region", null); + Location location = new LocationBuilder().scope(LocationScope.REGION).id("region").description("region").build(); Supplier> locations = Suppliers.> ofInstance(ImmutableSet . of(location)); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java index 070cf275ec..1de6ded869 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/options/EC2TemplateOptionsTest.java @@ -21,7 +21,6 @@ package org.jclouds.ec2.compute.options; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.authorizePublicKey; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.blockOnPort; -import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.enableMonitoring; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.inboundPorts; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.installPrivateKey; import static org.jclouds.ec2.compute.options.EC2TemplateOptions.Builder.keyPair; @@ -172,26 +171,6 @@ public class EC2TemplateOptionsTest { assert !options.shouldAutomaticallyCreateKeyPair(); } - @Test - public void testMonitoringEnabledDefault() { - EC2TemplateOptions options = new EC2TemplateOptions(); - assert !options.isMonitoringEnabled(); - } - - @Test - public void testMonitoringEnabled() { - EC2TemplateOptions options = new EC2TemplateOptions(); - options.enableMonitoring(); - assert options.isMonitoringEnabled(); - } - - @Test - public void testEnableMonitoringStatic() { - EC2TemplateOptions options = enableMonitoring(); - assertEquals(options.getKeyPair(), null); - assert options.isMonitoringEnabled(); - } - // superclass tests @Test(expectedExceptions = IllegalArgumentException.class) public void testinstallPrivateKeyBadFormat() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java new file mode 100644 index 0000000000..5b20782e9a --- /dev/null +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -0,0 +1,442 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.ec2.compute.strategy; + +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.lang.reflect.Method; +import java.util.Map; +import java.util.Set; + +import javax.inject.Provider; + +import org.jclouds.aws.domain.Region; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.domain.EC2HardwareBuilder; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.encryption.internal.Base64; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit") +public class CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptionsTest { + + private static final Provider OPTIONS_PROVIDER = new javax.inject.Provider() { + + @Override + public RunInstancesOptions get() { + return new RunInstancesOptions(); + } + + }; + + public void testExecuteWithDefaultOptionsEC2() throws SecurityException, NoSuchMethodException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + Hardware size = EC2HardwareBuilder.m1_small().build(); + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + String generatedGroup = "group"; + Set generatedGroups = ImmutableSet.of(generatedGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); + + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + Template template = createMock(Template.class); + + // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); + expect(template.getHardware()).andReturn(size).atLeastOnce(); + expect(template.getOptions()).andReturn(options).atLeastOnce(); + expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); + expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( + systemGeneratedKeyPairName); + expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); + expect(options.getUserData()).andReturn(null); + + // replay mocks + replay(options); + replay(template); + replay(strategy); + + // run + RunInstancesOptions customize = strategy.execute(region, tag, template); + assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName) + .entries()); + assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); + assertEquals(customize.buildStringPayload(), null); + + // verify mocks + verify(options); + verify(template); + verify(strategy); + } + + public void testExecuteWithUserData() throws SecurityException, NoSuchMethodException { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + Hardware size = EC2HardwareBuilder.m1_small().build(); + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + String generatedGroup = "group"; + Set generatedGroups = ImmutableSet.of(generatedGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); + + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + Template template = createMock(Template.class); + + // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); + expect(template.getHardware()).andReturn(size).atLeastOnce(); + expect(template.getOptions()).andReturn(options).atLeastOnce(); + expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); + expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( + systemGeneratedKeyPairName); + expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); + expect(options.getUserData()).andReturn("hello".getBytes()); + + // replay mocks + replay(options); + replay(template); + replay(strategy); + + // run + RunInstancesOptions customize = strategy.execute(region, tag, template); + assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", "group", "KeyName", systemGeneratedKeyPairName, "UserData", + Base64.encodeBytes("hello".getBytes())).entries()); + assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); + assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); + assertEquals(customize.buildStringPayload(), null); + + // verify mocks + verify(options); + verify(template); + verify(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_reusesKeyWhenToldTo() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = "myKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), userSuppliedKeyPair); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_createsNewKeyPairAndReturnsItsNameByDefault() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = null; + boolean shouldAutomaticallyCreateKeyPair = true; + String systemGeneratedKeyPairName = "systemGeneratedKeyPair"; + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); + expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, tag))).andReturn(keyPair); + expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); + expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn( + null); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), + systemGeneratedKeyPairName); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testCreateNewKeyPairUnlessUserSpecifiedOtherwise_doesntCreateAKeyPairAndReturnsNullWhenToldNotTo() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String userSuppliedKeyPair = null; + boolean shouldAutomaticallyCreateKeyPair = false; // here's the important + // part! + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + KeyPair keyPair = createMock(KeyPair.class); + + // setup expectations + expect(options.getKeyPair()).andReturn(userSuppliedKeyPair); + expect(options.shouldAutomaticallyCreateKeyPair()).andReturn(shouldAutomaticallyCreateKeyPair); + + // replay mocks + replay(options); + replay(keyPair); + replayStrategy(strategy); + + // run + assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), null); + + // verify mocks + verify(options); + verify(keyPair); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesntExist() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of(); + int[] ports = new int[] {}; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = false; + Set returnVal = ImmutableSet. of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); + expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_createsNewGroupByDefaultWhenPortsAreSpecifiedWhenDoesntExist() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of(); + int[] ports = new int[] { 22, 80 }; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = false; + Set returnVal = ImmutableSet. of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); + expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExist() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of(); + int[] ports = new int[] {}; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = true; + Set returnVal = ImmutableSet. of(generatedMarkerGroup); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + public void testGetSecurityGroupsForTagAndOptions_reusesGroupByDefaultWhenNoPortsAreSpecifiedWhenDoesExistAndAcceptsUserSuppliedGroups() { + // setup constants + String region = Region.AP_SOUTHEAST_1; + String tag = "tag"; + String generatedMarkerGroup = "jclouds#tag#" + Region.AP_SOUTHEAST_1; + Set groupIds = ImmutableSet. of("group1", "group2"); + int[] ports = new int[] {}; + boolean shouldAuthorizeSelf = true; + boolean groupExisted = true; + Set returnVal = ImmutableSet. of(generatedMarkerGroup, "group1", "group2"); + + // create mocks + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); + EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + + // setup expectations + expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); + RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, + ports, shouldAuthorizeSelf); // note + // this + // works + // since + // there's + // no equals on portsq + expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); + + // replay mocks + replay(options); + replayStrategy(strategy); + + // run + assertEquals(strategy.getSecurityGroupsForTagAndOptions(region, tag, options), returnVal); + + // verify mocks + verify(options); + verifyStrategy(strategy); + } + + private void verifyStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { + verify(strategy.credentialsMap); + verify(strategy.securityGroupMap); + verify(strategy.createUniqueKeyPair); + verify(strategy.createSecurityGroupIfNeeded); + } + + @SuppressWarnings("unchecked") + private CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() { + Map credentialsMap = createMock(Map.class); + Map securityGroupMap = createMock(Map.class); + CreateUniqueKeyPair createUniqueKeyPair = createMock(CreateUniqueKeyPair.class); + CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class); + + return new CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions(credentialsMap, securityGroupMap, + createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER); + } + + private void replayStrategy(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { + replay(strategy.credentialsMap); + replay(strategy.securityGroupMap); + replay(strategy.createUniqueKeyPair); + replay(strategy.createSecurityGroupIfNeeded); + } + +} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java index f584ed933d..605a6660fe 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/EC2RunNodesAndAddToSetStrategyTest.java @@ -39,8 +39,8 @@ import org.jclouds.compute.domain.Template; import org.jclouds.compute.util.ComputeUtils; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; import org.jclouds.ec2.compute.options.EC2TemplateOptions; @@ -99,7 +99,7 @@ public class EC2RunNodesAndAddToSetStrategyTest { String imageId = "ami1"; String instanceCreatedId = "instance1"; // setup mocks - EC2RunNodesAndAddToSetStrategy strategy = setupStrategy(); + EC2CreateNodesInGroupThenAddToSet strategy = setupStrategy(); InputParams input = new InputParams(location); InstanceClient instanceClient = createMock(InstanceClient.class); RunInstancesOptions ec2Options = createMock(RunInstancesOptions.class); @@ -127,7 +127,6 @@ public class EC2RunNodesAndAddToSetStrategyTest { expect(strategy.instancePresent.apply(instance)).andReturn(true); expect(input.template.getOptions()).andReturn(input.options).atLeastOnce(); - expect(input.options.isMonitoringEnabled()).andReturn(false); expect(strategy.runningInstanceToNodeMetadata.apply(instance)).andReturn(nodeMetadata); expect( @@ -155,10 +154,12 @@ public class EC2RunNodesAndAddToSetStrategyTest { verifyStrategy(strategy); } - private static final Location REGION_AP_SOUTHEAST_1 = new LocationImpl(LocationScope.REGION, Region.AP_SOUTHEAST_1, - Region.AP_SOUTHEAST_1, new LocationImpl(LocationScope.PROVIDER, "ec2", "ec2", null)); - private static final Location ZONE_AP_SOUTHEAST_1A = new LocationImpl(LocationScope.ZONE, - AvailabilityZone.AP_SOUTHEAST_1A, AvailabilityZone.AP_SOUTHEAST_1A, REGION_AP_SOUTHEAST_1); + private static final Location REGION_AP_SOUTHEAST_1 = new LocationBuilder().scope(LocationScope.REGION).id( + Region.AP_SOUTHEAST_1).description(Region.AP_SOUTHEAST_1).parent( + new LocationBuilder().scope(LocationScope.PROVIDER).id("ec2").description("ec2").build()).build(); + private static final Location ZONE_AP_SOUTHEAST_1A = new LocationBuilder().scope(LocationScope.ZONE).id( + AvailabilityZone.AP_SOUTHEAST_1A).description(AvailabilityZone.AP_SOUTHEAST_1A).parent( + REGION_AP_SOUTHEAST_1).build(); // ///////////////////////////////////////////////////////////////////// @SuppressWarnings("unchecked") @@ -199,7 +200,7 @@ public class EC2RunNodesAndAddToSetStrategyTest { } } - private void verifyStrategy(EC2RunNodesAndAddToSetStrategy strategy) { + private void verifyStrategy(EC2CreateNodesInGroupThenAddToSet strategy) { verify(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize); verify(strategy.client); verify(strategy.instancePresent); @@ -210,19 +211,19 @@ public class EC2RunNodesAndAddToSetStrategyTest { } @SuppressWarnings("unchecked") - private EC2RunNodesAndAddToSetStrategy setupStrategy() { + private EC2CreateNodesInGroupThenAddToSet setupStrategy() { EC2Client client = createMock(EC2Client.class); - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class); + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = createMock(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class); Predicate instanceStateRunning = createMock(Predicate.class); RunningInstanceToNodeMetadata runningInstanceToNodeMetadata = createMock(RunningInstanceToNodeMetadata.class); Function instanceToCredentials = createMock(Function.class); Map credentialStore = createMock(Map.class); ComputeUtils utils = createMock(ComputeUtils.class); - return new EC2RunNodesAndAddToSetStrategy(client, createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, + return new EC2CreateNodesInGroupThenAddToSet(client, createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, instanceStateRunning, runningInstanceToNodeMetadata, instanceToCredentials, credentialStore, utils); } - private void replayStrategy(EC2RunNodesAndAddToSetStrategy strategy) { + private void replayStrategy(EC2CreateNodesInGroupThenAddToSet strategy) { replay(strategy.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize); replay(strategy.client); replay(strategy.instancePresent); diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java index e94200e161..4f82afecd5 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/options/RunInstancesOptionsTest.java @@ -20,25 +20,23 @@ package org.jclouds.ec2.options; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.asType; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.enableMonitoring; +import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKernelId; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withKeyName; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withRamdisk; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withSecurityGroup; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withSubnetId; import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withUserData; -import static org.jclouds.ec2.options.RunInstancesOptions.Builder.withBlockDeviceMappings; import static org.testng.Assert.assertEquals; import java.util.Collections; -import java.util.HashSet; -import java.util.Set; import org.jclouds.ec2.domain.BlockDeviceMapping; import org.jclouds.ec2.domain.InstanceType; import org.jclouds.http.options.HttpRequestOptions; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * Tests possible uses of RunInstancesOptions and RunInstancesOptions.Builder.* * @@ -183,49 +181,6 @@ public class RunInstancesOptionsTest { withKernelId(null); } - @Test - public void testWithMonitoringEnabled() { - RunInstancesOptions options = new RunInstancesOptions(); - options.enableMonitoring(); - assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); - } - - @Test - public void testNullWithMonitoringEnabled() { - RunInstancesOptions options = new RunInstancesOptions(); - assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.EMPTY_LIST); - } - - @Test - public void testWithMonitoringEnabledStatic() { - RunInstancesOptions options = enableMonitoring(); - assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); - } - - @Test - public void testWithSubnetId() { - RunInstancesOptions options = new RunInstancesOptions(); - options.withSubnetId("test"); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); - } - - @Test - public void testNullWithSubnetId() { - RunInstancesOptions options = new RunInstancesOptions(); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections.EMPTY_LIST); - } - - @Test - public void testWithSubnetIdStatic() { - RunInstancesOptions options = withSubnetId("test"); - assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); - } - - @Test(expectedExceptions = NullPointerException.class) - public void testWithSubnetIdNPE() { - withSubnetId(null); - } - @Test public void testWithRamdisk() { RunInstancesOptions options = new RunInstancesOptions(); @@ -255,17 +210,18 @@ public class RunInstancesOptionsTest { RunInstancesOptions options = new RunInstancesOptions(); assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), Collections.EMPTY_LIST); } - + @Test public void testWithBlockDeviceMapping() { - RunInstancesOptions options = new RunInstancesOptions(); - BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true); - Set mappings = new HashSet(); - mappings.add(mapping); - options.withBlockDeviceMappings(mappings); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true")); + BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true); + RunInstancesOptions options = new RunInstancesOptions().withBlockDeviceMappings(ImmutableSet + . of(mapping)); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections + .singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections + .singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections + .singletonList("true")); } @Test @@ -276,18 +232,20 @@ public class RunInstancesOptionsTest { @Test public void testWithBlockDeviceMappingStatic() { - BlockDeviceMapping mapping = new BlockDeviceMapping("/dev/sda1", null, null, 120, null, true); - Set mappings = new HashSet(); - mappings.add(mapping); - RunInstancesOptions options = withBlockDeviceMappings(mappings); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections.singletonList("/dev/sda1")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections.singletonList("120")); - assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections.singletonList("true")); + BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true); + RunInstancesOptions options = withBlockDeviceMappings(ImmutableSet + . of(mapping)); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections + .singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections + .singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections + .singletonList("true")); } @Test(expectedExceptions = NullPointerException.class) public void testWithBlockDeviceMappingNPE() { - withBlockDeviceMappings(null); + withBlockDeviceMappings(null); } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java index 5d5afa3766..d63ca92ec9 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIAsyncClientTest.java @@ -33,7 +33,6 @@ import org.jclouds.ec2.xml.BlockDeviceMappingHandler; import org.jclouds.ec2.xml.DescribeImagesResponseHandler; import org.jclouds.ec2.xml.ImageIdHandler; import org.jclouds.ec2.xml.PermissionHandler; -import org.jclouds.ec2.xml.ProductCodesHandler; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReleasePayloadAndReturn; @@ -222,23 +221,6 @@ public class AMIAsyncClientTest extends BaseEC2AsyncClientTest { checkFilters(request); } - public void testGetProductCodesForImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("getProductCodesForImageInRegion", String.class, String.class); - HttpRequest request = processor.createRequest(method, null, "imageId"); - - assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); - assertPayloadEquals(request, - "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=productCodes&ImageId=imageId", - "application/x-www-form-urlencoded", false); - - assertResponseParserClassEquals(method, request, ParseSax.class); - assertSaxResponseParserClassEquals(method, ProductCodesHandler.class); - assertExceptionParserClassEquals(method, null); - - checkFilters(request); - } - public void testGetBlockDeviceMappingsForImage() throws SecurityException, NoSuchMethodException, IOException { Method method = AMIAsyncClient.class.getMethod("getBlockDeviceMappingsForImageInRegion", String.class, String.class); @@ -335,44 +317,6 @@ public class AMIAsyncClientTest extends BaseEC2AsyncClientTest { checkFilters(request); } - public void testAddProductCodesToImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("addProductCodesToImageInRegion", String.class, Iterable.class, - String.class); - HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); - - assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); - assertPayloadEquals( - request, - "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", - "application/x-www-form-urlencoded", false); - - assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(request); - } - - public void testRemoveProductCodesFromImage() throws SecurityException, NoSuchMethodException, IOException { - Method method = AMIAsyncClient.class.getMethod("removeProductCodesFromImageInRegion", String.class, - Iterable.class, String.class); - HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); - - assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); - assertPayloadEquals( - request, - "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", - "application/x-www-form-urlencoded", false); - - assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, null); - - checkFilters(request); - } - @Override protected TypeLiteral> createTypeLiteral() { return new TypeLiteral>() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java index 4703aadc0c..7e6a7208a8 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/AMIClientLiveTest.java @@ -37,8 +37,8 @@ import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.domain.Image; -import org.jclouds.ec2.domain.Image.ImageType; import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.Image.ImageType; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.rest.RestContext; import org.testng.annotations.AfterTest; @@ -101,8 +101,8 @@ public class AMIClientLiveTest { public void setupClient() { setupCredentials(); Properties overrides = setupProperties(); - context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet. of(new Log4JLoggingModule()), - overrides).getProviderSpecificContext(); + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); client = context.getApi().getAMIServices(); } @@ -223,10 +223,6 @@ public class AMIClientLiveTest { System.out.println(client.getLaunchPermissionForImageInRegion(null, imageId)); } - public void testGetProductCodesForImage() { - System.out.println(client.getProductCodesForImageInRegion(null, imageId)); - } - @Test(enabled = false) // awaiting ebs support public void testGetBlockDeviceMappingsForImage() { diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java index f9eff08931..76fce4f473 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/BaseEC2AsyncClientTest.java @@ -29,6 +29,10 @@ import java.util.Properties; import org.jclouds.aws.domain.Region; import org.jclouds.aws.filters.FormSigner; import org.jclouds.date.DateService; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.ec2.EC2Client; +import org.jclouds.ec2.EC2ContextBuilder; +import org.jclouds.ec2.EC2PropertiesBuilder; import org.jclouds.ec2.config.EC2RestClientModule; import org.jclouds.ec2.domain.AvailabilityZone; import org.jclouds.http.HttpRequest; @@ -50,7 +54,11 @@ import com.google.inject.Module; public abstract class BaseEC2AsyncClientTest extends RestClientTest { @RequiresHttp @ConfiguresRestClient - protected static class StubEC2RestClientModule extends EC2RestClientModule { + protected static class StubEC2RestClientModule extends EC2RestClientModule { + + public StubEC2RestClientModule() { + super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP); + } @Override protected String provideTimeStamp(DateService dateService, int expiration) { @@ -108,9 +116,19 @@ public abstract class BaseEC2AsyncClientTest extends RestClientTest { protected String provider = "ec2"; + @Override + protected Properties getProperties() { + Properties overrides = new Properties(); + overrides.setProperty(provider + ".endpoint", "https://ec2.us-east-1.amazonaws.com"); + overrides.setProperty(provider + ".propertiesbuilder", EC2PropertiesBuilder.class.getName()); + overrides.setProperty(provider + ".contextbuilder", EC2ContextBuilder.class.getName()); + return overrides; + } + @Override public RestContextSpec createContextSpec() { - return new RestContextFactory().createContextSpec(provider, "identity", "credential", new Properties()); + return new RestContextFactory(getProperties()).createContextSpec(provider, "identity", "credential", + new Properties()); } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java index 6fdbbf9a5f..3088a7ffd7 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/services/InstanceAsyncClientTest.java @@ -64,7 +64,7 @@ public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest mapping = Maps.newLinkedHashMap(); mapping.put("/dev/sda1", new BlockDevice("vol-test1", true)); @@ -478,14 +476,14 @@ public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), - ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), "0", - "ec2-174-129-81-68.compute-1.amazonaws.com", "ami-1fd73376", "i-0799056f", InstanceState.RUNNING, - InstanceType.M1_SMALL, "174.129.81.68", "aki-a71cf9ce", "adriancole.ec21", dateService - .iso8601DateParse("2009-11-09T03:00:34.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1C, null, "paravirtual", null, "ip-10-243-42-70.ec2.internal", - "10.243.42.70", ImmutableSet. of(), "ari-a51cf9cc", null, null, null, null, - RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of())), "993194456877", - null, "r-a3c508cb")); + Set> contents = ImmutableSet.of(new Reservation(defaultRegion, + ImmutableSet.of("adriancole.ec2ingress"), ImmutableSet.of(new RunningInstance.Builder().region( + defaultRegion).groupId("adriancole.ec2ingress").amiLaunchIndex("0").dnsName( + "ec2-174-129-81-68.compute-1.amazonaws.com").imageId("ami-82e4b5c7").instanceId("i-0799056f") + .instanceState(InstanceState.RUNNING).instanceType(InstanceType.M1_SMALL).ipAddress( + "174.129.81.68").kernelId("aki-a71cf9ce").keyName("adriancole.ec21").launchTime( + dateService.iso8601DateParse("2009-11-09T03:00:34.000Z")) + // MonitoringState.DISABLED, + .availabilityZone(AvailabilityZone.US_EAST_1C).virtualizationType("paravirtual") + .privateDnsName("ip-10-243-42-70.ec2.internal").privateIpAddress("10.243.42.70").ramdiskId( + "ari-a51cf9cc").rootDeviceType(RootDeviceType.INSTANCE_STORE).build()), + "993194456877", null, "r-a3c508cb")); Set> result = parseRunningInstances("/describe_instances_running.xml"); @@ -86,82 +85,54 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { } public void testApplyInputStream() { - - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("default"), ImmutableSet.of( - new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23", - "ec2-72-44-33-4.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64341", InstanceState.RUNNING, - InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService - .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-132.ec2.internal", null, - ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null, RootDeviceType.INSTANCE_STORE, - null, ImmutableMap. of()), - new RunningInstance(defaultRegion, ImmutableSet.of("default"), "23", - "ec2-72-44-33-6.compute-1.amazonaws.com", "ami-6ea54007", "i-28a64435", InstanceState.RUNNING, - InstanceType.M1_LARGE, (String) null, "aki-ba3adfd3", "example-key-name", dateService - .iso8601DateParse("2007-08-07T11:54:42.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1B, null, "paravirtual", null, "10-251-50-134.ec2.internal", null, - ImmutableSet.of("774F4FF8"), "ari-badbad00", null, null, null, null, RootDeviceType.INSTANCE_STORE, - null, ImmutableMap. of())), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, - "r-44a5402d")); + Set> contents = ImmutableSet.of(new Reservation(defaultRegion, + ImmutableSet.of("default"), ImmutableSet.of(new RunningInstance.Builder().region(defaultRegion).groupId( + "default").amiLaunchIndex("23").dnsName("ec2-72-44-33-4.compute-1.amazonaws.com").imageId( + "ami-6ea54007").instanceId("i-28a64341").instanceState(InstanceState.RUNNING).instanceType( + InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")) + // MonitoringState.DISABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).virtualizationType("paravirtual") + .privateDnsName("10-251-50-132.ec2.internal")// product codes + // ImmutableSet.of("774F4FF8") + .ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE).build(), + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("23") + .dnsName("ec2-72-44-33-6.compute-1.amazonaws.com").imageId("ami-6ea54007").instanceId( + "i-28a64435").instanceState(InstanceState.RUNNING).instanceType( + InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName("example-key-name") + .launchTime(dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")) + // MonitoringState.DISABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).virtualizationType("paravirtual") + .privateDnsName("10-251-50-134.ec2.internal")// product codes + // ImmutableSet.of("774F4FF8") + .ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE).build()), + "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d")); Set> result = parseRunningInstances("/describe_instances.xml"); assertEquals(result, contents); } - @Test(enabled = false) - // TODO not sure why equals fails - public void testApplyInputStreamEuc() { - - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("default"), ImmutableSet - .of(new RunningInstance(defaultRegion, ImmutableSet.of("jclouds#euc"), "1", null, "emi-9ACB1363", - "i-3FFA0762", InstanceState.SHUTTING_DOWN, InstanceType.M1_LARGE, null, "eki-6CBD12F2", - "jclouds#euc-17", dateService.iso8601DateParse("2010-06-16T03:06:19.000Z"), MonitoringState.DISABLED, - "open", null, "paravirtual", null, "10.7.0.179", null, ImmutableSet. of(), "eri-A97113E4", - null, null, null, null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap - . of())), "jclouds", null, "r-4D2A08AD")); - - Set> result = parseRunningInstances("/describe_instances_euc.xml"); - - assertEquals(result, contents); - } - - public void testApplyInputStreamNovaNoAvailabilityZone() { - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("default"), ImmutableSet - .of(new RunningInstance(defaultRegion, ImmutableSet. of(), "0", null, "ami-82e4b5c7", "i-9slweygo", - InstanceState.TERMINATED, InstanceType.M1_SMALL, null, null, "nebulatanimislam", dateService - .iso8601SecondsDateParse("2010-09-09T18:09:42Z"), null, null, null, "paravirtual", null, null, - "10.128.207.5", ImmutableSet. of("None"), null, null, null, null, null, - RootDeviceType.INSTANCE_STORE, null, ImmutableMap. of())), "tislam1", null, - "r-opqeylmj")); - - Set> result = parseRunningInstances("/describe_instances_nova.xml"); - - assertEquals(result, contents); - } - public void testEBS() throws UnknownHostException { - Set> contents = Sets.newLinkedHashSet(); - - contents.add(new Reservation(defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), - ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), "0", - "ec2-75-101-203-146.compute-1.amazonaws.com", "ami-849875ed", "i-e564438d", InstanceState.RUNNING, - InstanceType.M1_SMALL, "75.101.203.146", "aki-a71cf9ce", "adriancole.ec2ebs1", dateService - .iso8601DateParse("2009-12-30T04:06:23.000Z"), MonitoringState.DISABLED, - AvailabilityZone.US_EAST_1B, "placement", "hvm", null, "domU-12-31-39-09-CE-53.compute-1.internal", - "10.210.209.157", ImmutableSet. of(), "ari-a51cf9cc", null, null, null, null, - RootDeviceType.EBS, "/dev/sda1", ImmutableMap. of( - "/dev/sda1", - new BlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService - .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)))), "993194456877", null, - "r-596dd731")); + Set> contents = ImmutableSet.of(new Reservation(defaultRegion, + ImmutableSet.of("adriancole.ec2ebsingress"), ImmutableSet.of(new RunningInstance.Builder().region( + defaultRegion).groupId("adriancole.ec2ebsingress").amiLaunchIndex("0").dnsName( + "ec2-75-101-203-146.compute-1.amazonaws.com").imageId("ami-849875ed").instanceId("i-e564438d") + .instanceState(InstanceState.RUNNING).instanceType(InstanceType.M1_SMALL).ipAddress( + "75.101.203.146").kernelId("aki-a71cf9ce") + .keyName("adriancole.ec2ebs1") + .launchTime(dateService.iso8601DateParse("2009-12-30T04:06:23.000Z")) + // MonitoringState.DISABLED + .availabilityZone(AvailabilityZone.US_EAST_1B) + // "placement" + .virtualizationType("hvm").privateDnsName("domU-12-31-39-09-CE-53.compute-1.internal") + .privateIpAddress("10.210.209.157").ramdiskId("ari-a51cf9cc") + .rootDeviceType(RootDeviceType.EBS).rootDeviceName("/dev/sda1").device( + "/dev/sda1", + new BlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService + .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)).build()), + "993194456877", null, "r-596dd731")); Set> result = parseRunningInstances("/describe_instances_ebs.xml"); @@ -178,7 +149,8 @@ public class DescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { }); ParseSax>> parser = (ParseSax>>) injector - .getInstance(ParseSax.Factory.class).create(injector.getInstance(DescribeInstancesResponseHandler.class)); + .getInstance(ParseSax.Factory.class) + .create(injector.getInstance(DescribeInstancesResponseHandler.class)); return parser; } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java index 9988a14e38..a35063aaf5 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/xml/RunInstancesResponseHandlerTest.java @@ -26,31 +26,26 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; +import org.jclouds.date.DateService; import org.jclouds.ec2.domain.AvailabilityZone; -import org.jclouds.ec2.domain.BlockDevice; import org.jclouds.ec2.domain.InstanceState; import org.jclouds.ec2.domain.InstanceType; -import org.jclouds.ec2.domain.MonitoringState; import org.jclouds.ec2.domain.Reservation; -import org.jclouds.ec2.domain.RootDeviceType; import org.jclouds.ec2.domain.RunningInstance; -import org.jclouds.date.DateService; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; /** * Tests behavior of {@code RunInstancesResponseHandler} * * @author Adrian Cole */ -//NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "RunInstancesResponseHandlerTest") public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { @@ -69,24 +64,27 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { InputStream is = getClass().getResourceAsStream("/run_instances.xml"); Reservation expected = new Reservation(defaultRegion, ImmutableSet - .of("default"), ImmutableSet.of(new RunningInstance(defaultRegion, ImmutableSet.of("default"), "0", - null, "ami-60a54009", "i-2ba64342", InstanceState.PENDING, InstanceType.M1_SMALL, (String) null, null, - "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), MonitoringState.ENABLED, - AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, Sets - . newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, - null, ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet - .of("default"), "1", null, "ami-60a54009", "i-2bc64242", InstanceState.PENDING, InstanceType.M1_SMALL, - (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), - MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, - Sets. newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null, - ImmutableMap. of()), new RunningInstance(defaultRegion, ImmutableSet - .of("default"), "2", null, "ami-60a54009", "i-2be64332", InstanceState.PENDING, InstanceType.M1_SMALL, - (String) null, null, "example-key-name", dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"), - MonitoringState.ENABLED, AvailabilityZone.US_EAST_1B, null, "paravirtual", null, (String) null, null, - Sets. newLinkedHashSet(), null, null, null, null, null, RootDeviceType.INSTANCE_STORE, null, - ImmutableMap. of()) + .of("default"), ImmutableSet.of( - ), "AIDADH4IGTRXXKCD", null, "r-47a5402e"); + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("0") + .imageId("ami-60a54009").instanceId("i-2ba64342").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("1") + .imageId("ami-60a54009").instanceId("i-2bc64242").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new RunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("2") + .imageId("ami-60a54009").instanceId("i-2be64332").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z"))// MonitoringState.ENABLED, + .availabilityZone(AvailabilityZone.US_EAST_1B).build()) + + , "AIDADH4IGTRXXKCD", null, "r-47a5402e"); RunInstancesResponseHandler handler = injector.getInstance(RunInstancesResponseHandler.class); addDefaultRegionToHandler(handler); @@ -96,7 +94,7 @@ public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { private void addDefaultRegionToHandler(ParseSax.HandlerWithResult handler) { GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); - expect(request.getArgs()).andReturn(ImmutableList.of()).atLeastOnce(); + expect(request.getArgs()).andReturn(ImmutableList. of()).atLeastOnce(); replay(request); handler.setContext(request); } diff --git a/apis/ec2/src/test/resources/describe_instances_euc.xml b/apis/ec2/src/test/resources/describe_instances_euc.xml deleted file mode 100644 index 7ee16645a2..0000000000 --- a/apis/ec2/src/test/resources/describe_instances_euc.xml +++ /dev/null @@ -1,39 +0,0 @@ - - e323d0bd-48a2-401b-aeee-1cbf653bc6db - - - r-4D2A08AD - jclouds - - - jclouds#euc - - - - - i-3FFA0762 - emi-9ACB1363 - - 32 - shutting-down - - 10.7.0.179 - 0.0.0.0 - jclouds#euc-17 - 1 - - m1.large - 2010-06-16T03:06:19Z - - open - - eki-6CBD12F2 - eri-A97113E4 - - false - - - - - - \ No newline at end of file diff --git a/apis/ec2/src/test/resources/describe_instances_nova.xml b/apis/ec2/src/test/resources/describe_instances_nova.xml deleted file mode 100644 index f38353fc12..0000000000 --- a/apis/ec2/src/test/resources/describe_instances_nova.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - G7PDD1DNVLO7DZS6AFZH - - - - - 10.128.207.5 - 0 - m1.small - - 2010-09-09T18:09:42Z - i-9slweygo - ami-82e4b5c7 - - 1 - shutdown - - nebulatanimislam - 10.128.207.5 - - - None - - - - - r-opqeylmj - - - default - - - tislam1 - - - \ No newline at end of file diff --git a/apis/ec2/src/test/resources/describe_instances_running.xml b/apis/ec2/src/test/resources/describe_instances_running.xml index 41332fd38a..d3813d4356 100644 --- a/apis/ec2/src/test/resources/describe_instances_running.xml +++ b/apis/ec2/src/test/resources/describe_instances_running.xml @@ -12,7 +12,7 @@ i-0799056f - ami-1fd73376 + ami-82e4b5c7 16 running diff --git a/apis/elasticstack/README.txt b/apis/elasticstack/README.txt new file mode 100644 index 0000000000..32c2bfd6be --- /dev/null +++ b/apis/elasticstack/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds API for ElasticHosts' Cloud Servers API (http://www.elastichosts.com/cloud-hosting/api/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/elasticstack/pom.xml b/apis/elasticstack/pom.xml index 20da3c56cf..b083837196 100644 --- a/apis/elasticstack/pom.xml +++ b/apis/elasticstack/pom.xml @@ -69,6 +69,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + org.jclouds jclouds-core @@ -86,7 +92,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java index 1bce212142..572994a71c 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java @@ -6,7 +6,6 @@ import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; import static org.jclouds.elasticstack.util.Servers.small; -import java.net.URI; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -29,8 +28,6 @@ import org.jclouds.compute.domain.internal.VolumeImpl; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.elasticstack.ElasticStackAsyncClient; import org.jclouds.elasticstack.ElasticStackClient; import org.jclouds.elasticstack.domain.Device; @@ -42,7 +39,7 @@ import org.jclouds.elasticstack.domain.ServerInfo; import org.jclouds.elasticstack.domain.ServerStatus; import org.jclouds.elasticstack.domain.WellKnownImage; import org.jclouds.elasticstack.reference.ElasticStackConstants; -import org.jclouds.location.Provider; +import org.jclouds.location.suppliers.JustProvider; import org.jclouds.logging.Logger; import com.google.common.base.Function; @@ -64,8 +61,7 @@ public class ElasticStackComputeServiceAdapter implements private final Predicate driveNotClaimed; private final Map preinstalledImages; private final Map cache; - private final String providerName; - private final URI providerURI; + private final JustProvider locationSupplier; private final String defaultVncPassword; private final ExecutorService executor; @@ -75,15 +71,14 @@ public class ElasticStackComputeServiceAdapter implements @Inject public ElasticStackComputeServiceAdapter(ElasticStackClient client, ElasticStackAsyncClient aclient, - Predicate driveNotClaimed, @Provider String providerName, @Provider URI providerURI, + Predicate driveNotClaimed, JustProvider locationSupplier, Map preinstalledImages, Map cache, @Named(ElasticStackConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { this.client = checkNotNull(client, "client"); this.aclient = checkNotNull(aclient, "aclient"); this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed"); - this.providerName = checkNotNull(providerName, "providerName"); - this.providerURI = checkNotNull(providerURI, "providerURI"); + this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier"); this.preinstalledImages = checkNotNull(preinstalledImages, "preinstalledImages"); this.cache = checkNotNull(cache, "cache"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); @@ -91,7 +86,7 @@ public class ElasticStackComputeServiceAdapter implements } @Override - public ServerInfo runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, + public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, Map credentialStore) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l); logger.debug(">> creating boot drive bytes(%d)", bootSize); @@ -168,11 +163,11 @@ public class ElasticStackComputeServiceAdapter implements public Iterable listNodes() { return (Iterable) client.listServerInfo(); } - + + @SuppressWarnings("unchecked") @Override public Iterable listLocations() { - return ImmutableSet. of(new LocationImpl(LocationScope.PROVIDER, providerName, providerURI - .toASCIIString(), null)); + return (Iterable) locationSupplier.get(); } @Override diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/config/ElasticStackComputeServiceContextModule.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/config/ElasticStackComputeServiceContextModule.java index 910e1f7244..5b50c45706 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/config/ElasticStackComputeServiceContextModule.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/config/ElasticStackComputeServiceContextModule.java @@ -52,12 +52,14 @@ import org.jclouds.elasticstack.predicates.DriveClaimed; import org.jclouds.functions.IdentityFunction; import org.jclouds.json.Json; import org.jclouds.location.Provider; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.util.Strings2; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.base.Supplier; import com.google.common.collect.MapMaker; import com.google.common.collect.Maps; import com.google.inject.Provides; @@ -97,6 +99,8 @@ public class ElasticStackComputeServiceContextModule }).to(FindImageForId.class); bind(new TypeLiteral>() { }).to(WellKnownImageToImage.class); + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZone.class); } @Provides diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/functions/ServerInfoToNodeMetadata.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/functions/ServerInfoToNodeMetadata.java index eed46bb5f6..ed4b82f86a 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/functions/ServerInfoToNodeMetadata.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/functions/ServerInfoToNodeMetadata.java @@ -20,7 +20,7 @@ package org.jclouds.elasticstack.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import java.util.List; import java.util.Map; @@ -92,7 +92,7 @@ public class ServerInfoToNodeMetadata implements Function>>() { }).to(ServerToMap.class); - bind(new TypeLiteral>>() { - }).to(ServerToMap.class); } }).getInstance(BindServerToPlainTextString.class); diff --git a/apis/elasticstack/src/test/java/org/jclouds/elasticstack/compute/ElasticStackTemplateBuilderLiveTest.java b/apis/elasticstack/src/test/java/org/jclouds/elasticstack/compute/ElasticStackTemplateBuilderLiveTest.java deleted file mode 100644 index 1808c71a83..0000000000 --- a/apis/elasticstack/src/test/java/org/jclouds/elasticstack/compute/ElasticStackTemplateBuilderLiveTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.elasticstack.compute; - -import org.jclouds.compute.BaseTemplateBuilderLiveTest; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; -import org.testng.annotations.Test; - -import com.google.common.base.Predicate; - -/** - * - * @author Adrian Cole - */ -@Test(groups = "live") -public class ElasticStackTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { - - public ElasticStackTemplateBuilderLiveTest() { - provider = "elasticstack"; - } - - @Override - protected Predicate defineUnsupportedOperatingSystems() { - return new Predicate() { - - @Override - public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || // - (input.family == OsFamily.UBUNTU && !(input.version.equals("10.04") && input.is64Bit)) || // - (input.family == OsFamily.WINDOWS && !((input.version.equals("2008") || input.version.equals("2008 R2")) && input.is64Bit)) // - ); - } - - }; - } - -} \ No newline at end of file diff --git a/apis/eucalyptus/README.txt b/apis/eucalyptus/README.txt new file mode 100644 index 0000000000..9646bcdad5 --- /dev/null +++ b/apis/eucalyptus/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds API for Eucalyptus Systems' EC2 flavour (http://www.eucalyptus.com/). +# +# Expects the jclouds EC2 API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/eucalyptus/pom.xml b/apis/eucalyptus/pom.xml index 123e6fc2dd..41cf5d7112 100644 --- a/apis/eucalyptus/pom.xml +++ b/apis/eucalyptus/pom.xml @@ -74,6 +74,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + org.jclouds.driver jclouds-log4j diff --git a/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java b/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java index d8048aa959..794eaa9d27 100644 --- a/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java +++ b/apis/eucalyptus/src/main/java/org/jclouds/eucalyptus/EucalyptusPropertiesBuilder.java @@ -22,7 +22,6 @@ package org.jclouds.eucalyptus; import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_PORT_OPEN; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.util.Properties; @@ -38,14 +37,10 @@ public class EucalyptusPropertiesBuilder extends EC2PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_ENDPOINT, - "http://173.205.188.130:8773/services/Eucalyptus"); + properties.setProperty(PROPERTY_ENDPOINT, "http://173.205.188.130:8773/services/Eucalyptus"); properties.setProperty(PROPERTY_REGIONS, "Eucalyptus"); properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "admin"); - // amis that work with the cluster instances - properties.setProperty(PROPERTY_EC2_CC_AMIs, ""); properties.setProperty(PROPERTY_TIMEOUT_PORT_OPEN, 5 * 60 * 1000 + ""); - return properties; } diff --git a/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java b/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java index 91ea635f07..1cc6166b2c 100644 --- a/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java +++ b/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusComputeServiceLiveTest.java @@ -25,6 +25,7 @@ import static org.testng.Assert.assertEquals; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest; +import org.jclouds.http.HttpResponseException; import org.testng.annotations.Test; /** @@ -37,19 +38,7 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest public EucalyptusComputeServiceLiveTest() { provider = "eucalyptus"; // security groups must be <30 characters - tag = "eu"; - } - - @Override - @Test(enabled = false) - public void testExtendedOptionsAndLogin() throws Exception { - // euc does not support monitoring - } - - @Override - @Test(enabled = false) - public void testExtendedOptionsNoKeyPair() throws Exception { - // euc does not support multiple security groups + group = "eu"; } @Override @@ -60,4 +49,33 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + @Test(enabled = true, dependsOnMethods = "testReboot") + public void testSuspendResume() throws Exception { + try { + super.testSuspendResume(); + assert false; + } catch (HttpResponseException e) { + // ebs backed not yet available + } + } + + @Override + @Test(enabled = true, dependsOnMethods = "testSuspendResume") + public void testListNodes() throws Exception { + super.testListNodes(); + } + + @Override + @Test(enabled = true, dependsOnMethods = "testSuspendResume") + public void testGetNodesWithDetails() throws Exception { + super.testGetNodesWithDetails(); + } + + @Override + @Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" }) + public void testDestroyNodes() { + super.testDestroyNodes(); + } + } diff --git a/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusTemplateBuilderLiveTest.java b/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusTemplateBuilderLiveTest.java deleted file mode 100644 index 2c98b25e91..0000000000 --- a/apis/eucalyptus/src/test/java/org/jclouds/eucalyptus/compute/EucalyptusTemplateBuilderLiveTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.eucalyptus.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.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; -import org.testng.annotations.Test; - -import com.google.common.base.Predicate; - -/** - * - * @author Adrian Cole - */ -@Test(groups = "live") -public class EucalyptusTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { - - public EucalyptusTemplateBuilderLiveTest() { - provider = "eucalyptus"; - } - - @Override - protected Predicate defineUnsupportedOperatingSystems() { - return new Predicate() { - - @Override - public boolean apply(OsFamilyVersion64Bit input) { - return input.family == OsFamily.RHEL || // - (input.family == OsFamily.CENTOS && !input.version.equals("5.3") || !input.is64Bit) || // - input.family == OsFamily.WINDOWS || // - input.family == OsFamily.UBUNTU; - - } - - }; - } - - @Test - public void testDefaultTemplateBuilder() throws IOException { - - Template defaultTemplate = context.getComputeService().templateBuilder().build(); - assert (defaultTemplate.getImage().getProviderId().startsWith("emi-")) : defaultTemplate; - assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "5.3"); - assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); - assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); - assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "instance-store"); - assertEquals(defaultTemplate.getLocation().getId(), "Eucalyptus"); - assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); - - } - -} diff --git a/apis/filesystem/README.txt b/apis/filesystem/README.txt new file mode 100644 index 0000000000..b97c1545fd --- /dev/null +++ b/apis/filesystem/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds API for accessing a local filesystem as a blobstore. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemAsyncBlobStore.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemAsyncBlobStore.java index 4b34b760b3..0603b8211c 100644 --- a/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemAsyncBlobStore.java +++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/FilesystemAsyncBlobStore.java @@ -129,10 +129,10 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { @Inject protected FilesystemAsyncBlobStore(BlobStoreContext context, DateService dateService, Crypto crypto, - HttpGetOptionsListToGetOptions httpGetOptionsConverter, - IfDirectoryReturnNameStrategy ifDirectoryReturnName, Blob.Factory blobFactory, BlobUtils blobUtils, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, - @Memoized Supplier> locations, FilesystemStorageStrategy storageStrategy) { + HttpGetOptionsListToGetOptions httpGetOptionsConverter, IfDirectoryReturnNameStrategy ifDirectoryReturnName, + Factory blobFactory, BlobUtils blobUtils, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, + Supplier defaultLocation, @Memoized Supplier> locations, + FilesystemStorageStrategy storageStrategy) { super(context, blobUtils, service, defaultLocation, locations); // super(context, blobUtils, service, null, null); this.blobFactory = blobFactory; @@ -164,22 +164,22 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { } SortedSet contents = newTreeSet(transform(blobBelongingToContainer, - new Function() { - public StorageMetadata apply(String key) { - Blob oldBlob = loadFileBlob(container, key); + new Function() { + public StorageMetadata apply(String key) { + Blob oldBlob = loadFileBlob(container, key); - checkState(oldBlob != null, "blob " + key + " is not present although it was in the list of " - + container); - checkState(oldBlob.getMetadata() != null, "blob " + container + "/" + key + " has no metadata"); - MutableBlobMetadata md = copy(oldBlob.getMetadata()); - String directoryName = ifDirectoryReturnName.execute(md); - if (directoryName != null) { - md.setName(directoryName); - md.setType(StorageType.RELATIVE_PATH); - } - return md; + checkState(oldBlob != null, "blob " + key + " is not present although it was in the list of " + + container); + checkState(oldBlob.getMetadata() != null, "blob " + container + "/" + key + " has no metadata"); + MutableBlobMetadata md = copy(oldBlob.getMetadata()); + String directoryName = ifDirectoryReturnName.execute(md); + if (directoryName != null) { + md.setName(directoryName); + md.setType(StorageType.RELATIVE_PATH); } - })); + return md; + } + })); String marker = null; if (options != null) { @@ -219,21 +219,21 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { if (delimiter != null) { SortedSet commonPrefixes = null; Iterable iterable = transform(contents, new CommonPrefixes(prefix != null ? prefix : null, - delimiter)); + delimiter)); commonPrefixes = iterable != null ? newTreeSet(iterable) : new TreeSet(); commonPrefixes.remove(CommonPrefixes.NO_PREFIX); contents = newTreeSet(filter(contents, new DelimiterFilter(prefix != null ? prefix : null, delimiter))); - Iterables. addAll(contents, transform(commonPrefixes, - new Function() { - public StorageMetadata apply(String o) { - MutableStorageMetadata md = new MutableStorageMetadataImpl(); - md.setType(StorageType.RELATIVE_PATH); - md.setName(o); - return md; - } - })); + Iterables. addAll(contents, + transform(commonPrefixes, new Function() { + public StorageMetadata apply(String o) { + MutableStorageMetadata md = new MutableStorageMetadataImpl(); + md.setType(StorageType.RELATIVE_PATH); + md.setName(o); + return md; + } + })); } // trim metadata, if the response isn't supposed to be detailed. @@ -245,7 +245,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { } return Futures.> immediateFuture(new PageSetImpl(contents, - marker)); + marker)); } @@ -310,14 +310,14 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { Iterable containers = storageStrategy.getAllContainerNames(); return Futures.> immediateFuture(new PageSetImpl(transform( - containers, new Function() { - public StorageMetadata apply(String name) { - MutableStorageMetadata cmd = create(); - cmd.setName(name); - cmd.setType(StorageType.CONTAINER); - return cmd; - } - }), null)); + containers, new Function() { + public StorageMetadata apply(String name) { + MutableStorageMetadata cmd = create(); + cmd.setName(name); + cmd.setType(StorageType.CONTAINER); + return cmd; + } + }), null)); } protected MutableStorageMetadata create() { @@ -330,7 +330,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { @Path("{container}") @Override public ListenableFuture createContainerInLocation(final Location location, - @PathParam("container") @ParamValidators( { FilesystemContainerNameValidator.class }) String name) { + @PathParam("container") @ParamValidators({ FilesystemContainerNameValidator.class }) String name) { boolean result = storageStrategy.createContainer(name); return immediateFuture(result); } @@ -478,7 +478,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { @Override public void setCurrentRequest(HttpRequest request) { - + } }, response); @@ -500,7 +500,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { storageStrategy.writePayloadOnFile(containerName, blobKey, object.getPayload()); } catch (IOException e) { logger.error(e, "An error occurred storing the new object with name [%s] to container [%s].", blobKey, - containerName); + containerName); Throwables.propagate(e); } return immediateFuture(eTag); @@ -547,7 +547,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { if (blob.getMetadata().getLastModified().before(modifiedSince)) { HttpResponse response = new HttpResponse(304, null, null); return immediateFailedFuture(new HttpResponseException(String.format("%1$s is before %2$s", blob - .getMetadata().getLastModified(), modifiedSince), null, response)); + .getMetadata().getLastModified(), modifiedSince), null, response)); } } @@ -556,7 +556,7 @@ public class FilesystemAsyncBlobStore extends BaseAsyncBlobStore { if (blob.getMetadata().getLastModified().after(unmodifiedSince)) { HttpResponse response = new HttpResponse(412, null, null); return immediateFailedFuture(new HttpResponseException(String.format("%1$s is after %2$s", blob - .getMetadata().getLastModified(), unmodifiedSince), null, response)); + .getMetadata().getLastModified(), unmodifiedSince), null, response)); } } diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/config/FilesystemBlobStoreContextModule.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/config/FilesystemBlobStoreContextModule.java index 548c216374..5493fdab26 100644 --- a/apis/filesystem/src/main/java/org/jclouds/filesystem/config/FilesystemBlobStoreContextModule.java +++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/config/FilesystemBlobStoreContextModule.java @@ -19,8 +19,6 @@ package org.jclouds.filesystem.config; -import java.util.Set; - import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStoreContext; @@ -29,10 +27,6 @@ import org.jclouds.blobstore.config.BlobStoreMapModule; import org.jclouds.blobstore.config.BlobStoreObjectModule; import org.jclouds.blobstore.internal.BlobStoreContextImpl; import org.jclouds.blobstore.util.BlobUtils; -import org.jclouds.collect.Memoized; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.filesystem.FilesystemBlobStore; import org.jclouds.filesystem.predicates.validators.FilesystemBlobKeyValidator; import org.jclouds.filesystem.predicates.validators.FilesystemContainerNameValidator; @@ -41,10 +35,8 @@ import org.jclouds.filesystem.predicates.validators.internal.FilesystemContainer import org.jclouds.filesystem.strategy.FilesystemStorageStrategy; import org.jclouds.filesystem.strategy.internal.FilesystemStorageStrategyImpl; import org.jclouds.filesystem.util.internal.FileSystemBlobUtilsImpl; +import org.jclouds.location.config.JustProviderLocationModule; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -69,6 +61,7 @@ public class FilesystemBlobStoreContextModule extends AbstractModule { bind(BlobUtils.class).to(FileSystemBlobUtilsImpl.class); bind(FilesystemBlobKeyValidator.class).to(FilesystemBlobKeyValidatorImpl.class); bind(FilesystemContainerNameValidator.class).to(FilesystemContainerNameValidatorImpl.class); + install(new JustProviderLocationModule()); } @Provides @@ -77,18 +70,4 @@ public class FilesystemBlobStoreContextModule extends AbstractModule { return in; } - @Provides - @Singleton - @Memoized - Supplier> provideLocations(Supplier defaultLocation) { - return Suppliers.> ofInstance(ImmutableSet.of(defaultLocation.get())); - } - - @Provides - @Singleton - Supplier provideDefaultLocation() { - return Suppliers - . ofInstance(new LocationImpl(LocationScope.PROVIDER, "filesystem", "filesystem", null)); - } - } diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java index 3955dc86f6..b5bc6ebc26 100644 --- a/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java +++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java @@ -19,506 +19,507 @@ package org.jclouds.filesystem.strategy.internal; -import org.jclouds.rest.annotations.ParamValidators; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Provider; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.DirectoryFileFilter; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; +import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.filesystem.predicates.validators.FilesystemBlobKeyValidator; import org.jclouds.filesystem.predicates.validators.FilesystemContainerNameValidator; -import java.io.OutputStream; -import java.util.Set; -import java.util.HashSet; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.options.ListContainerOptions; +import org.jclouds.filesystem.reference.FilesystemConstants; +import org.jclouds.filesystem.strategy.FilesystemStorageStrategy; import org.jclouds.io.Payload; -import java.io.InputStream; -import java.io.FileOutputStream; -import java.io.FileFilter; -import org.apache.commons.io.filefilter.DirectoryFileFilter; -import java.util.Iterator; +import org.jclouds.logging.Logger; +import org.jclouds.rest.annotations.ParamValidators; + import com.google.common.base.Throwables; -import java.io.IOException; -import org.apache.commons.io.FileUtils; -import java.io.File; -import javax.annotation.Resource; import com.google.inject.Inject; import com.google.inject.name.Named; -import org.jclouds.filesystem.reference.FilesystemConstants; -import org.jclouds.filesystem.strategy.FilesystemStorageStrategy; -import org.jclouds.logging.Logger; - -import static com.google.common.base.Preconditions.checkNotNull; - /** - * + * * @author Alfredo "Rainbowbreeze" Morresi */ public class FilesystemStorageStrategyImpl implements FilesystemStorageStrategy { - private static final String BACK_SLASH = "\\"; - /** The buffer size used to copy an InputStream to an OutputStream */ - private static final int COPY_BUFFER_SIZE = 1024; + private static final String BACK_SLASH = "\\"; + /** The buffer size used to copy an InputStream to an OutputStream */ + private static final int COPY_BUFFER_SIZE = 1024; - @Resource - protected Logger logger = Logger.NULL; + @Resource + protected Logger logger = Logger.NULL; - protected final Blob.Factory blobFactory; - protected final String baseDirectory; - protected final FilesystemContainerNameValidator filesystemContainerNameValidator; - protected final FilesystemBlobKeyValidator filesystemBlobKeyValidator; + protected final Provider blobBuilders; + protected final String baseDirectory; + protected final FilesystemContainerNameValidator filesystemContainerNameValidator; + protected final FilesystemBlobKeyValidator filesystemBlobKeyValidator; + @Inject + protected FilesystemStorageStrategyImpl(Provider blobBuilders, + @Named(FilesystemConstants.PROPERTY_BASEDIR) String baseDir, + FilesystemContainerNameValidator filesystemContainerNameValidator, + FilesystemBlobKeyValidator filesystemBlobKeyValidator) { + this.blobBuilders = checkNotNull(blobBuilders, "filesystem storage strategy blobBuilders"); + this.baseDirectory = checkNotNull(baseDir, "filesystem storage strategy base directory"); + this.filesystemContainerNameValidator = checkNotNull(filesystemContainerNameValidator, + "filesystem container name validator"); + this.filesystemBlobKeyValidator = checkNotNull(filesystemBlobKeyValidator, "filesystem blob key validator"); + } - @Inject - protected FilesystemStorageStrategyImpl( - Blob.Factory blobFactory, - @Named(FilesystemConstants.PROPERTY_BASEDIR) String baseDir, - FilesystemContainerNameValidator filesystemContainerNameValidator, - FilesystemBlobKeyValidator filesystemBlobKeyValidator) { - this.blobFactory = checkNotNull(blobFactory, "filesystem storage strategy blobfactory"); - this.baseDirectory = checkNotNull(baseDir, "filesystem storage strategy base directory"); - this.filesystemContainerNameValidator = checkNotNull(filesystemContainerNameValidator, "filesystem container name validator"); - this.filesystemBlobKeyValidator = checkNotNull(filesystemBlobKeyValidator, "filesystem blob key validator"); - } + @Override + public boolean containerExists(String container) { + filesystemContainerNameValidator.validate(container); + return directoryExists(container, null); + } - @Override - public boolean containerExists(String container) { - filesystemContainerNameValidator.validate(container); - return directoryExists(container, null); - } + @Override + public boolean blobExists(String container, String key) { + filesystemContainerNameValidator.validate(container); + filesystemBlobKeyValidator.validate(key); + return buildPathAndChecksIfFileExists(container, key); + } - @Override - public boolean blobExists(String container, String key) { - filesystemContainerNameValidator.validate(container); - filesystemBlobKeyValidator.validate(key); - return buildPathAndChecksIfFileExists(container, key); - } + @Override + public boolean createContainer(String container) { + logger.debug("Creating container %s", container); + filesystemContainerNameValidator.validate(container); + return createDirectoryWithResult(container, null); + } - @Override - public boolean createContainer(String container) { - logger.debug("Creating container %s", container); - filesystemContainerNameValidator.validate(container); - return createDirectoryWithResult(container, null); - } + @Override + public void deleteContainer(String container) { + filesystemContainerNameValidator.validate(container); + deleteDirectory(container, null); + } - - @Override - public void deleteContainer(String container) { - filesystemContainerNameValidator.validate(container); - deleteDirectory(container, null); - } - - - /** - * Empty the directory of its content (files and subdirectories) - * @param container - */ - @Override - public void clearContainer(final String container) { - filesystemContainerNameValidator.validate(container); - clearContainer(container, ListContainerOptions.Builder.recursive()); - } - - @Override - public void clearContainer(String container, ListContainerOptions options) { - filesystemContainerNameValidator.validate(container); - //TODO - //now all is deleted, check it based on options - try { - File containerFile = openFolder(container); - File[] children = containerFile.listFiles(); - if (null != children) { - for(File child:children) { - FileUtils.forceDelete(child); - } - } - } catch(IOException e) { - logger.error(e,"An error occurred while clearing container %s", container); - Throwables.propagate(e); - } - } - - - @Override - public Blob newBlob(@ParamValidators( { FilesystemBlobKeyValidator.class }) String name) { - filesystemBlobKeyValidator.validate(name); - Blob blob = blobFactory.create(null); - blob.getMetadata().setName(name); - return blob; - } - - @Override - public void removeBlob(final String container, final String blobKey) { - filesystemContainerNameValidator.validate(container); - filesystemBlobKeyValidator.validate(blobKey); - String fileName = buildPathStartingFromBaseDir(container, blobKey); - logger.debug("Deleting blob %s", fileName); - File fileToBeDeleted = new File(fileName); - fileToBeDeleted.delete(); - - //now examins if the key of the blob is a complex key (with a directory structure) - //and eventually remove empty directory - removeDirectoriesTreeOfBlobKey(container, blobKey); - } - - - /** - * Return an iterator that reports all the containers under base path - * @return - */ - @Override - public Iterable getAllContainerNames() { - Iterable containers = new Iterable() { - @Override - public Iterator iterator() { - return new FileIterator( - buildPathStartingFromBaseDir(), DirectoryFileFilter.INSTANCE); - } - }; - - return containers; - } - - /** - * Returns a {@link File} object that links to the blob - * @param container - * @param blobKey - * @return - */ - @Override - public File getFileForBlobKey(String container, String blobKey) { - filesystemContainerNameValidator.validate(container); - filesystemBlobKeyValidator.validate(blobKey); - String fileName = buildPathStartingFromBaseDir(container, blobKey); - File blobFile = new File(fileName); - return blobFile; - } - - - /** - * Write a {@link Blob} {@link Payload} into a file - * @param container - * @param blobKey - * @param payload - * @throws IOException - */ - @Override - public void writePayloadOnFile(String container, String blobKey, Payload payload) throws IOException { - filesystemContainerNameValidator.validate(container); - filesystemBlobKeyValidator.validate(blobKey); - File outputFile = null; - OutputStream output = null; - InputStream input = null; - try { - outputFile = getFileForBlobKey(container, blobKey); - File parentDirectory = outputFile.getParentFile(); - if (!parentDirectory.exists()) { - if (!parentDirectory.mkdirs()) { - throw new IOException("An error occurred creating directory [" + parentDirectory.getName() + "]."); - } - } - output = new FileOutputStream(outputFile); - input = payload.getInput(); - copy(input, output); - - } catch (IOException ex) { - if (outputFile != null) { - outputFile.delete(); - } - throw ex; - } finally { - if (input != null) { - try { - input.close(); - } catch (IOException ex) { - // Does nothing - } - } - if (output != null) { - try { - output.close(); - } catch (IOException ex) { - // Does nothing - } - } - } - } - - - /** - * Returns all the blobs key inside a container - * @param container - * @return - * @throws IOException - */ - @Override - public Iterable getBlobKeysInsideContainer(String container) throws IOException { - filesystemContainerNameValidator.validate(container); - //check if container exists - //TODO maybe an error is more appropriate - if (!containerExists(container)) { - return new HashSet(); - } - - File containerFile = openFolder(container); - final int containerPathLenght = containerFile.getAbsolutePath().length() + 1; - Set blobNames = new HashSet() { - - private static final long serialVersionUID = 3152191346558570795L; - - @Override - public boolean add(String e) { - return super.add(e.substring(containerPathLenght)); - } - }; - populateBlobKeysInContainer(containerFile, blobNames); - return blobNames; - } - - @Override - public boolean directoryExists(String container, String directory) { - return buildPathAndChecksIfDirectoryExists(container, directory); - } - - @Override - public void createDirectory(String container, String directory) { - createDirectoryWithResult(container, directory); - } - - @Override - public void deleteDirectory(String container, String directory) { - //create complete dir path - String fullDirPath = buildPathStartingFromBaseDir(container, directory); - try { - FileUtils.forceDelete(new File(fullDirPath)); - } catch (IOException ex) { - logger.error("An error occurred removing directory %s.", fullDirPath); - Throwables.propagate(ex); - } - } - - - @Override - public long countBlobs(String container, ListContainerOptions options) { - //TODO - throw new UnsupportedOperationException("Not supported yet."); - } - - - - - //---------------------------------------------------------- Private methods - - private boolean buildPathAndChecksIfFileExists(String...tokens) { - String path = buildPathStartingFromBaseDir(tokens); - File file = new File(path); - boolean exists = file.exists() || file.isFile(); - return exists; - } - - /** - * Check if the file system resource whose name is obtained applying buildPath - * on the input path tokens is a directory, otherwise a RuntimeException is thrown - * - * @param tokens the tokens that make up the name of the resource on the - * file system + /** + * Empty the directory of its content (files and subdirectories) + * + * @param container */ - private boolean buildPathAndChecksIfDirectoryExists(String...tokens) { - String path = buildPathStartingFromBaseDir(tokens); - File file = new File(path); - boolean exists = file.exists() || file.isDirectory(); - return exists; - } + @Override + public void clearContainer(final String container) { + filesystemContainerNameValidator.validate(container); + clearContainer(container, ListContainerOptions.Builder.recursive()); + } - - /** - * Facility method used to concatenate path tokens normalizing separators - * @param pathTokens all the string in the proper order that must be concatenated - * in order to obtain the filename - * @return the resulting string - */ - protected String buildPathStartingFromBaseDir(String...pathTokens) { - String normalizedToken = removeFileSeparatorFromBorders(normalize(baseDirectory), true); - StringBuilder completePath = new StringBuilder(normalizedToken); - if(pathTokens!=null && pathTokens.length>0) { - for(int i=0; i getAllContainerNames() { + Iterable containers = new Iterable() { + @Override + public Iterator iterator() { + return new FileIterator(buildPathStartingFromBaseDir(), DirectoryFileFilter.INSTANCE); + } + }; + + return containers; + } + + /** + * Returns a {@link File} object that links to the blob + * + * @param container + * @param blobKey + * @return + */ + @Override + public File getFileForBlobKey(String container, String blobKey) { + filesystemContainerNameValidator.validate(container); + filesystemBlobKeyValidator.validate(blobKey); + String fileName = buildPathStartingFromBaseDir(container, blobKey); + File blobFile = new File(fileName); + return blobFile; + } + + /** + * Write a {@link Blob} {@link Payload} into a file + * + * @param container + * @param blobKey + * @param payload + * @throws IOException + */ + @Override + public void writePayloadOnFile(String container, String blobKey, Payload payload) throws IOException { + filesystemContainerNameValidator.validate(container); + filesystemBlobKeyValidator.validate(blobKey); + File outputFile = null; + OutputStream output = null; + InputStream input = null; + try { + outputFile = getFileForBlobKey(container, blobKey); + File parentDirectory = outputFile.getParentFile(); + if (!parentDirectory.exists()) { + if (!parentDirectory.mkdirs()) { + throw new IOException("An error occurred creating directory [" + parentDirectory.getName() + "]."); } - } - return pathToBeNormalized; - } + } + output = new FileOutputStream(outputFile); + input = payload.getInput(); + copy(input, output); - /** - * Remove leading and trailing {@link File.separator} character from the - * string. - * @param pathToBeCleaned - * @param remove only trailing separator char from path - * @return - */ - private String removeFileSeparatorFromBorders(String pathToBeCleaned, boolean onlyTrailing) { - if (null == pathToBeCleaned || pathToBeCleaned.equals("")) return pathToBeCleaned; - - int beginIndex = 0; - int endIndex = pathToBeCleaned.length(); - - //search for separator chars - if (!onlyTrailing) { - if (pathToBeCleaned.substring(0, 1).equals(File.separator)) beginIndex = 1; - } - if (pathToBeCleaned.substring(pathToBeCleaned.length() - 1).equals(File.separator)) endIndex--; - - return pathToBeCleaned.substring(beginIndex, endIndex); - } - - /** - * Removes recursively the directory structure of a complex blob key, only - * if the directory is empty - * @param container - * @param normalizedKey - */ - private void removeDirectoriesTreeOfBlobKey(String container, String blobKey) { - String normalizedBlobKey = normalize(blobKey); - //exists is no path is present in the blobkey - if (!normalizedBlobKey.contains(File.separator)) return; - - File file = new File(normalizedBlobKey); - //TODO - //"/media/data/works/java/amazon/jclouds/master/filesystem/aa/bb/cc/dd/eef6f0c8-0206-460b-8870-352e6019893c.txt" - String parentPath = file.getParent(); - //no need to manage "/" parentPath, because "/" cannot be used as start - //char of blobkey - if (null != parentPath || "".equals(parentPath)) { - //remove parent directory only it's empty - File directory = new File(buildPathStartingFromBaseDir(container, parentPath)); - String[] children = directory.list(); - if (null == children || children.length == 0) { - directory.delete(); - //recursively call for removing other path - removeDirectoriesTreeOfBlobKey(container, parentPath); + } catch (IOException ex) { + if (outputFile != null) { + outputFile.delete(); + } + throw ex; + } finally { + if (input != null) { + try { + input.close(); + } catch (IOException ex) { + // Does nothing } - } - } - - - private File openFolder(String folderName) throws IOException { - String baseFolderName = buildPathStartingFromBaseDir(folderName); - File folder = new File(baseFolderName); - if(folder.exists()) { - if(!folder.isDirectory()) { - throw new IOException("Resource " + baseFolderName + " isn't a folder."); + } + if (output != null) { + try { + output.close(); + } catch (IOException ex) { + // Does nothing } - } - return folder; - } + } + } + } + /** + * Returns all the blobs key inside a container + * + * @param container + * @return + * @throws IOException + */ + @Override + public Iterable getBlobKeysInsideContainer(String container) throws IOException { + filesystemContainerNameValidator.validate(container); + // check if container exists + // TODO maybe an error is more appropriate + if (!containerExists(container)) { + return new HashSet(); + } - private class FileIterator implements Iterator{ - int currentFileIndex = 0; - File[] children = new File[0]; - File currentFile = null; + File containerFile = openFolder(container); + final int containerPathLenght = containerFile.getAbsolutePath().length() + 1; + Set blobNames = new HashSet() { - public FileIterator(String fileName, FileFilter filter) { - File file = new File(fileName); - if(file.exists() && file.isDirectory()) { - children = file.listFiles(filter); + private static final long serialVersionUID = 3152191346558570795L; + + @Override + public boolean add(String e) { + return super.add(e.substring(containerPathLenght)); + } + }; + populateBlobKeysInContainer(containerFile, blobNames); + return blobNames; + } + + @Override + public boolean directoryExists(String container, String directory) { + return buildPathAndChecksIfDirectoryExists(container, directory); + } + + @Override + public void createDirectory(String container, String directory) { + createDirectoryWithResult(container, directory); + } + + @Override + public void deleteDirectory(String container, String directory) { + // create complete dir path + String fullDirPath = buildPathStartingFromBaseDir(container, directory); + try { + FileUtils.forceDelete(new File(fullDirPath)); + } catch (IOException ex) { + logger.error("An error occurred removing directory %s.", fullDirPath); + Throwables.propagate(ex); + } + } + + @Override + public long countBlobs(String container, ListContainerOptions options) { + // TODO + throw new UnsupportedOperationException("Not supported yet."); + } + + // ---------------------------------------------------------- Private methods + + private boolean buildPathAndChecksIfFileExists(String... tokens) { + String path = buildPathStartingFromBaseDir(tokens); + File file = new File(path); + boolean exists = file.exists() || file.isFile(); + return exists; + } + + /** + * Check if the file system resource whose name is obtained applying buildPath on the input path + * tokens is a directory, otherwise a RuntimeException is thrown + * + * @param tokens + * the tokens that make up the name of the resource on the file system + */ + private boolean buildPathAndChecksIfDirectoryExists(String... tokens) { + String path = buildPathStartingFromBaseDir(tokens); + File file = new File(path); + boolean exists = file.exists() || file.isDirectory(); + return exists; + } + + /** + * Facility method used to concatenate path tokens normalizing separators + * + * @param pathTokens + * all the string in the proper order that must be concatenated in order to obtain the + * filename + * @return the resulting string + */ + protected String buildPathStartingFromBaseDir(String... pathTokens) { + String normalizedToken = removeFileSeparatorFromBorders(normalize(baseDirectory), true); + StringBuilder completePath = new StringBuilder(normalizedToken); + if (pathTokens != null && pathTokens.length > 0) { + for (int i = 0; i < pathTokens.length; i++) { + if (pathTokens[i] != null) { + normalizedToken = removeFileSeparatorFromBorders(normalize(pathTokens[i]), false); + completePath.append(File.separator).append(normalizedToken); } - } + } + } + return completePath.toString(); + } - @Override - public boolean hasNext() { - return currentFileIndex { + int currentFileIndex = 0; + File[] children = new File[0]; + File currentFile = null; + + public FileIterator(String fileName, FileFilter filter) { + File file = new File(fileName); + if (file.exists() && file.isDirectory()) { + children = file.listFiles(filter); + } + } + + @Override + public boolean hasNext() { + return currentFileIndex < children.length; + } + + @Override + public String next() { + currentFile = children[currentFileIndex++]; + return currentFile.getName(); + } + + @Override + public void remove() { + if (currentFile != null && currentFile.exists()) { + if (!currentFile.delete()) { + throw new RuntimeException("An error occurred deleting " + currentFile.getName()); } - } - } + } + } + } + private void populateBlobKeysInContainer(File directory, Set blobNames) { + File[] children = directory.listFiles(); + for (File child : children) { + if (child.isFile()) { + blobNames.add(child.getAbsolutePath()); + } else if (child.isDirectory()) { + populateBlobKeysInContainer(child, blobNames); + } + } + } - private void populateBlobKeysInContainer(File directory, Set blobNames) { - File[] children = directory.listFiles(); - for(File child:children) { - if(child.isFile()) { - blobNames.add(child.getAbsolutePath()); - } else if(child.isDirectory()) { - populateBlobKeysInContainer(child, blobNames); - } - } - } + /** + * Creates a directory and returns the result + * + * @param container + * @param directory + * @return true if the directory was created, otherwise false + */ + protected boolean createDirectoryWithResult(String container, String directory) { + String directoryFullName = buildPathStartingFromBaseDir(container, directory); + logger.debug("Creating directory %s", directoryFullName); + // cannot use directoryFullName, because the following method rebuild + // another time the path starting from base directory + if (buildPathAndChecksIfDirectoryExists(container, directory)) { + logger.debug("Directory %s already exists", directoryFullName); + return false; + } - /** - * Creates a directory and returns the result - * @param container - * @param directory - * @return true if the directory was created, otherwise false - */ - protected boolean createDirectoryWithResult(String container, String directory) { - String directoryFullName = buildPathStartingFromBaseDir(container, directory); - logger.debug("Creating directory %s", directoryFullName); + File directoryToCreate = new File(directoryFullName); + boolean result = directoryToCreate.mkdirs(); + return result; + } - //cannot use directoryFullName, because the following method rebuild - //another time the path starting from base directory - if (buildPathAndChecksIfDirectoryExists(container, directory)) { - logger.debug("Directory %s already exists", directoryFullName); - return false; - } - - File directoryToCreate = new File(directoryFullName); - boolean result = directoryToCreate.mkdirs(); - return result; - } - - /** - * Copy from an InputStream to an OutputStream. - * - * @param input The InputStream - * @param output The OutputStream - * @return the number of bytes copied - * @throws IOException if an error occurs - */ - private long copy(InputStream input, OutputStream output) - throws IOException { - byte[] buffer = new byte[COPY_BUFFER_SIZE]; - long count = 0; - while (true) { - int read = input.read(buffer); - if (read < 0) { - break; - } - count += read; - - output.write(buffer, 0, read); - } - output.flush(); - return count; - } + /** + * Copy from an InputStream to an OutputStream. + * + * @param input + * The InputStream + * @param output + * The OutputStream + * @return the number of bytes copied + * @throws IOException + * if an error occurs + */ + private long copy(InputStream input, OutputStream output) throws IOException { + byte[] buffer = new byte[COPY_BUFFER_SIZE]; + long count = 0; + while (true) { + int read = input.read(buffer); + if (read < 0) { + break; + } + count += read; + output.write(buffer, 0, read); + } + output.flush(); + return count; + } } diff --git a/apis/filesystem/src/main/java/org/jclouds/filesystem/util/internal/FileSystemBlobUtilsImpl.java b/apis/filesystem/src/main/java/org/jclouds/filesystem/util/internal/FileSystemBlobUtilsImpl.java index ffffafdc8a..243b5b70be 100644 --- a/apis/filesystem/src/main/java/org/jclouds/filesystem/util/internal/FileSystemBlobUtilsImpl.java +++ b/apis/filesystem/src/main/java/org/jclouds/filesystem/util/internal/FileSystemBlobUtilsImpl.java @@ -19,14 +19,18 @@ package org.jclouds.filesystem.util.internal; -import com.google.inject.Inject; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Provider; + import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.util.BlobUtils; import org.jclouds.filesystem.strategy.FilesystemStorageStrategy; -import static com.google.common.base.Preconditions.checkNotNull; +import com.google.inject.Inject; /** * Implements the {@link BlobUtils} interfaced and act as a bridge to @@ -36,44 +40,48 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class FileSystemBlobUtilsImpl implements BlobUtils { - protected final FilesystemStorageStrategy storageStrategy; + protected final FilesystemStorageStrategy storageStrategy; + protected final Provider blobBuilders; - @Inject - public FileSystemBlobUtilsImpl( - FilesystemStorageStrategy storageStrategy) { - this.storageStrategy = checkNotNull(storageStrategy, "Filesystem Storage Strategy"); - } + @Inject + public FileSystemBlobUtilsImpl(FilesystemStorageStrategy storageStrategy, Provider blobBuilders) { + this.storageStrategy = checkNotNull(storageStrategy, "Filesystem Storage Strategy"); + this.blobBuilders = checkNotNull(blobBuilders, "Filesystem blobBuilders"); + } + @Override + public Blob newBlob(String name) { + return blobBuilder().name(name).build(); + } + @Override + public BlobBuilder blobBuilder() { + return blobBuilders.get(); + } - @Override - public Blob newBlob(String name) { - return storageStrategy.newBlob(name); - } + @Override + public boolean directoryExists(String containerName, String directory) { + return storageStrategy.directoryExists(containerName, directory); + } - @Override - public boolean directoryExists(String containerName, String directory) { - return storageStrategy.directoryExists(containerName, directory); - } + @Override + public void createDirectory(String containerName, String directory) { + storageStrategy.createDirectory(containerName, directory); + } - @Override - public void createDirectory(String containerName, String directory) { - storageStrategy.createDirectory(containerName, directory); - } + @Override + public long countBlobs(String container, ListContainerOptions options) { + return storageStrategy.countBlobs(container, options); + } - @Override - public long countBlobs(String container, ListContainerOptions options) { - return storageStrategy.countBlobs(container, options); - } + @Override + public void clearContainer(String container, ListContainerOptions options) { + storageStrategy.clearContainer(container, options); + } - @Override - public void clearContainer(String container, ListContainerOptions options) { - storageStrategy.clearContainer(container, options); - } - - @Override - public void deleteDirectory(String container, String directory) { - storageStrategy.deleteDirectory(container, directory); - } + @Override + public void deleteDirectory(String container, String directory) { + storageStrategy.deleteDirectory(container, directory); + } } diff --git a/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java b/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java index cfbd31cb4f..56be2b170e 100644 --- a/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java +++ b/apis/filesystem/src/test/java/org/jclouds/filesystem/FilesystemAsyncBlobStoreTest.java @@ -57,819 +57,736 @@ import org.testng.annotations.Test; import com.google.inject.CreationException; - /** * Test class for {@link FilesystemAsyncBlobStore} class - * + * * @author Alfredo "Rainbowbreeze" Morresi */ @Test(groups = "unit", testName = "filesystem.FilesystemAsyncBlobStoreTest", sequential = true) public class FilesystemAsyncBlobStoreTest { - private static final String CONTAINER_NAME = "fun-blobstore-test"; - private static final String TARGET_CONTAINER_NAME = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME; - private static final String LOGGING_CONFIG_KEY - = "java.util.logging.config.file"; - private static final String LOGGING_CONFIG_VALUE - = "src/main/resources/logging.properties"; - - private static final String PROVIDER = "filesystem"; - - - static { - System.setProperty(LOGGING_CONFIG_KEY, - LOGGING_CONFIG_VALUE); - - } - - private BlobStoreContext context = null; - private BlobStore blobStore = null; - private Set resourcesToBeDeleted = new HashSet(); - - @BeforeMethod - protected void setUp() throws Exception { - //create context for filesystem container - Properties prop = new Properties(); - prop.setProperty(FilesystemConstants.PROPERTY_BASEDIR, TestUtils.TARGET_BASE_DIR); - context = (BlobStoreContext) new BlobStoreContextFactory().createContext( - PROVIDER, prop); - //create a container in the default location - blobStore = context.getBlobStore(); - - resourcesToBeDeleted.add(new File(TestUtils.TARGET_BASE_DIR)); - } - - - @AfterMethod - protected void tearDown() { - context.close(); - context = null; - // freeing filesystem resources used for tests - Iterator resourceToDelete = resourcesToBeDeleted.iterator(); - while(resourceToDelete.hasNext()) { - File fileToDelete = resourceToDelete.next(); - try { - FileUtils.forceDelete(fileToDelete); - } catch (IOException ex) { - System.err.println("Error deleting folder ["+fileToDelete.getName()+"]."); - } - resourceToDelete.remove(); - } - } - - - /** - * Checks if context parameters are managed in the correct way - * - */ - public void testParameters() { - //no base directory declared in properties - try { - Properties props = new Properties(); - new BlobStoreContextFactory().createContext( - PROVIDER, props); - fail("No error if base directory is not specified"); - } catch (CreationException e) { - } - - //no base directory declared in properties - try { - Properties props = new Properties(); - props.setProperty(FilesystemConstants.PROPERTY_BASEDIR, null); - new BlobStoreContextFactory().createContext( - PROVIDER, props); - fail("No error if base directory is null in the option"); - } catch (NullPointerException e) { - } - } - - /** - * Test of list method of the root context - */ - public void testList_Root() throws IOException { - PageSet containersRetrieved; - Set containersCreated = new HashSet(); - - // Testing list with no containers - containersRetrieved = blobStore.list(); - assertTrue(containersRetrieved.isEmpty(), "List operation returns a not empty set of container"); - - // Testing list with some containers - String[] containerNames = new String[]{"34343", "aaaa", "bbbbb"}; - containersCreated = new HashSet(); - for(String containerName:containerNames) { - blobStore.createContainerInLocation(null, containerName); - containersCreated.add(containerName); - } - - containersRetrieved = blobStore.list(); - assertEquals(containersCreated.size(), containersRetrieved.size(), "Different numbers of container"); - - for(StorageMetadata data:containersRetrieved) { - String containerName = data.getName(); - if(!containersCreated.remove(containerName)) { - fail("Container list contains unexpected value ["+containerName+"]"); - } - } - assertTrue(containersCreated.isEmpty(), "List operation doesn't return all values."); - - for(String containerName:containerNames) { - //delete all creaded containers - blobStore.deleteContainer(containerName); - } - containersRetrieved = blobStore.list(); - assertTrue(containersRetrieved.isEmpty(), "List operation returns a not empty set of container"); - } - - - /** - * Test of list method, of class FilesystemAsyncBlobStore. - */ - public void testList_NoOptionSingleContainer() - throws IOException { - blobStore.createContainerInLocation(null, CONTAINER_NAME); - // Testing list for an empty container - checkForContainerContent(CONTAINER_NAME, null); - - //creates blobs in first container - Set 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", - "xdc" + File.separator + "wert.kpg" } - ); - - checkForContainerContent(CONTAINER_NAME, blobsExpected); - } - - - public void testList_NotExistingContainer() { - // Testing list for a not existing container - try { - blobStore.list(CONTAINER_NAME); - fail("Found a not existing container"); - } catch(ContainerNotFoundException e) { - //ok if arriver here - } - } - - /** - * Test of list method, of class FilesystemAsyncBlobStore. - */ - public void testList_NoOptionDoubleContainer() throws IOException { - final String CONTAINER_NAME2 = "container2"; - - //create first container - blobStore.createContainerInLocation(null, CONTAINER_NAME); - //checks for empty container - checkForContainerContent(CONTAINER_NAME, null); - - //create second container - blobStore.createContainerInLocation(null, CONTAINER_NAME2); - //checks for empty - checkForContainerContent(CONTAINER_NAME2, null); - - //creates blobs in first container - - Set blobNamesCreatedInContainer1 = TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[] { - "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg", - TestUtils.createRandomBlobKey(), - "rrr" + File.separator + "sss" + File.separator + "788.jpg", - "xdc" + File.separator + "wert.kpg"} - ); - - //creates blobs in second container - blobStore.createContainerInLocation(null, CONTAINER_NAME2); - Set blobNamesCreatedInContainer2 = TestUtils.createBlobsInContainer( - CONTAINER_NAME2, - new String[] { - "asd" + File.separator + "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg", - TestUtils.createRandomBlobKey(), - "rrr" + File.separator + "sss" + File.separator + "788.jpg", - "xdc" + File.separator + "wert.kpg" } - ); - - //test blobs in first container - checkForContainerContent(CONTAINER_NAME, blobNamesCreatedInContainer1); - //test blobs in second container - checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2); - } - - - 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 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 - * Should throws an exception? - */ - public void testClearContainer_NotExistingContainer(){ - blobStore.clearContainer(CONTAINER_NAME); - } - - - /** - * Integration test, because clearContainer is not redefined in - * {@link FilesystemAsyncBlobStore} class - */ - public void testClearContainer_NoOptions() throws IOException { - final String CONTAINER_NAME2 = "containerToClear"; - - //create containers - blobStore.createContainerInLocation(null, CONTAINER_NAME); - blobStore.createContainerInLocation(null, CONTAINER_NAME2); - - //creates blobs in first container - Set blobNamesCreatedInContainer1 = TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[] { - "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg", - TestUtils.createRandomBlobKey(), - "rrr" + File.separator + "sss" + File.separator + "788.jpg", - "xdc" + File.separator + "wert.kpg"} - ); - - //creates blobs in second container - blobStore.createContainerInLocation(null, CONTAINER_NAME2); - Set blobNamesCreatedInContainer2 = TestUtils.createBlobsInContainer( - CONTAINER_NAME2, - new String[] { - "asd" + File.separator + "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg", - TestUtils.createRandomBlobKey(), - "rrr" + File.separator + "sss" + File.separator + "788.jpg", - "xdc" + File.separator + "wert.kpg" } - ); - - //test blobs in containers - checkForContainerContent(CONTAINER_NAME, blobNamesCreatedInContainer1); - checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2); - - //delete blobs in first container - blobStore.clearContainer(CONTAINER_NAME); - checkForContainerContent(CONTAINER_NAME, null); - checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2); - //delete blobs in second container - blobStore.clearContainer(CONTAINER_NAME2); - checkForContainerContent(CONTAINER_NAME2, null); - } - - - /** - * Integration test, because countBlobs is not redefined in - * {@link FilesystemAsyncBlobStore} class - */ - public void testCountBlobs_NotExistingContainer() { - try { - blobStore.countBlobs(PROVIDER); - fail("Magically the method was implemented... Wow!"); - } catch (UnsupportedOperationException e) { - } - } - - /** - * Integration test, because countBlobs is not redefined in - * {@link FilesystemAsyncBlobStore} class - */ - public void testCountBlobs_NoOptionsEmptyContainer() { - blobStore.createContainerInLocation(null, CONTAINER_NAME); - try { - blobStore.countBlobs(PROVIDER); - fail("Magically the method was implemented... Wow!"); - } catch (UnsupportedOperationException e) { - } - } - - /** - * Integration test, because countBlobs is not redefined in - * {@link FilesystemAsyncBlobStore} class - */ - public void testCountBlobs_NoOptions() { - blobStore.createContainerInLocation(null, CONTAINER_NAME); - try { - blobStore.countBlobs(PROVIDER); - fail("Magically the method was implemented... Wow!"); - } catch (UnsupportedOperationException e) { - } - } - - - public void testRemoveBlob_SimpleBlobKey() throws IOException { - final String BLOB_KEY = TestUtils.createRandomBlobKey(null, ".txt"); - boolean result; - - blobStore.createContainerInLocation(null, CONTAINER_NAME); - - //checks that blob doesn't exists - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); - assertFalse(result, "Blob exists"); - - //create the blob - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[] { BLOB_KEY } - ); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); - assertTrue(result, "Blob exists"); - - //remove it - blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); - assertFalse(result, "Blob still exists"); - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false); - } - - - public void testRemoveBlob_TwoSimpleBlobKeys() throws IOException { - final String BLOB_KEY1 = TestUtils.createRandomBlobKey(null, null); - final String BLOB_KEY2 = TestUtils.createRandomBlobKey(null, null); - boolean result; - - //create the container and checks that blob doesn't exists - blobStore.createContainerInLocation(null, CONTAINER_NAME); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); - assertFalse(result, "Blob1 exists"); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); - assertFalse(result, "Blob2 exists"); - - //create the blob - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[] { BLOB_KEY1, BLOB_KEY2 } - ); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); - assertTrue(result, "Blob " + BLOB_KEY1 + " doesn't exist"); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); - assertTrue(result, "Blob " + BLOB_KEY2 + " doesn't exist"); - - //remove first blob - blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY1); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); - assertFalse(result, "Blob1 still exists"); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); - assertTrue(result, "Blob2 doesn't exist"); - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY1, false); - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, true); - //remove second blob - blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY2); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); - assertFalse(result, "Blob2 still exists"); - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, false); - } - - - /** - * Test of removeBlob method, with only one blob with a complex path as key - */ - public void testRemoveBlob_ComplexBlobKey() throws IOException { - final String BLOB_KEY = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null); - boolean result; - - //checks that blob doesn't exists - blobStore.createContainerInLocation(null, CONTAINER_NAME); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); - assertFalse(result, "Blob exists"); - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false); - - //create the blob - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[] { BLOB_KEY } - ); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); - assertTrue(result, "Blob doesn't exist"); - - //remove it - blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); - assertFalse(result, "Blob still exists"); - //file removed - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false); - //also the entire directory structure was removed - TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa", false); - } - - - /** - * Test of removeBlob method, with two blobs with a complex path as key and - * when first blob is removed, not all of its key's path is removed, because - * it is shared with the second blob's key - */ - public void testRemoveBlob_TwoComplexBlobKeys() throws IOException { - final String BLOB_KEY1 = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null); - final String BLOB_KEY2 = TestUtils.createRandomBlobKey("aa/bb/ee/ff/", null); - boolean result; - - blobStore.createContainerInLocation(null, CONTAINER_NAME); - - //checks that blob doesn't exist - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); - assertFalse(result, "Blob1 exists"); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); - assertFalse(result, "Blob2 exists"); - - //create the blobs - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[] { BLOB_KEY1, BLOB_KEY2 } - ); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); - assertTrue(result, "Blob " + BLOB_KEY1 + " doesn't exist"); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); - assertTrue(result, "Blob " + BLOB_KEY2 + " doesn't exist"); - - //remove first blob - blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY1); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); - assertFalse(result, "Blob still exists"); - //first file deleted, not the second - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY1, false); - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, true); - //only partial directory structure was removed, because it shares a path - //with the second blob created - TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa/bb/cc/dd", false); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa/bb", true); - //remove second blob - blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY2); - result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); - assertFalse(result, "Blob still exists"); - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, false); - //now all the directory structure is empty - TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa", false); - } - - - /** - * Test of containerExists method, of class FilesystemAsyncBlobStore. - */ - public void testContainerExists() throws IOException { - boolean result; - - result = blobStore.containerExists(CONTAINER_NAME); - assertFalse(result, "Container exists"); - - //create container - TestUtils.createContainerAsDirectory(CONTAINER_NAME); - - result = blobStore.containerExists(CONTAINER_NAME); - assertTrue(result, "Container doesn't exist"); - } - - - /** - * Test of createContainerInLocation method, of class FilesystemAsyncBlobStore. - */ - public void testCreateContainerInLocation() throws IOException { - final String CONTAINER_NAME2 = "funambol-test-2"; - final String TARGET_CONTAINER_NAME2 = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME2; - - boolean result; - - result = blobStore.containerExists(CONTAINER_NAME); - assertFalse(result, "Container exists"); - result = blobStore.createContainerInLocation(null, CONTAINER_NAME); - assertTrue(result, "Container not created"); - result = blobStore.containerExists(CONTAINER_NAME); - assertTrue(result, "Container doesn't exist"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - - result = blobStore.containerExists(CONTAINER_NAME2); - assertFalse(result, "Container exists"); - result = blobStore.createContainerInLocation(null, CONTAINER_NAME2); - assertTrue(result, "Container not created"); - result = blobStore.containerExists(CONTAINER_NAME2); - assertTrue(result, "Container doesn't exist"); - TestUtils.directoryExists(TestUtils.TARGET_BASE_DIR + CONTAINER_NAME2, true); - - //clean the environment - FileUtils.forceDelete(new File(TARGET_CONTAINER_NAME2)); - } - - - /** - * Test of putBlob method, of class FilesystemAsyncBlobStore. - * with a simple filename - no path in the filename, eg - * filename.jpg - */ - public void testPutBlobSimpleName() { - blobStore.createContainerInLocation(null, CONTAINER_NAME); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); - } - - /** - * Test of putBlob method with a complex key, with path in the filename, eg - * picture/filename.jpg - */ - public void testPutBlobComplexName1() { - blobStore.createContainerInLocation(null, CONTAINER_NAME); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("picture/putBlob-", ".jpg")); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("video/putBlob-", ".jpg")); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("video/putBlob-", ".jpg")); - } - - /** - * Test of putBlob method with a complex key, with path in the filename, eg - * picture/filename.jpg - */ - public void testPutBlobComplexName2() { - blobStore.createContainerInLocation(null, CONTAINER_NAME); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("aa/bb/cc/dd/ee/putBlob-", ".jpg")); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("aa/bb/cc/dd/ee/putBlob-", ".jpg")); - putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); - } - - - /** - * Test of blobExists method, of class FilesystemAsyncBlobStore. - */ - public void testBlobExists() throws IOException { - boolean result; - String blobKey; - - //when location doesn't exists - blobKey = TestUtils.createRandomBlobKey(); - result = blobStore.blobExists(CONTAINER_NAME, blobKey); - assertFalse(result, "Blob exists"); - - //when location exists - blobStore.createContainerInLocation(null, CONTAINER_NAME); - result = blobStore.blobExists(CONTAINER_NAME, blobKey); - assertFalse(result, "Blob exists"); - - //create blob - TestUtils.createBlobAsFile(CONTAINER_NAME, blobKey, TestUtils.getImageForBlobPayload()); - result = blobStore.blobExists(CONTAINER_NAME, blobKey); - assertTrue(result, "Blob doesn't exist"); - - //complex path test - blobKey = TestUtils.createRandomBlobKey("ss/asdas/", ""); - result = blobStore.blobExists(CONTAINER_NAME, blobKey); - assertFalse(result, "Blob exists"); - TestUtils.createBlobAsFile(CONTAINER_NAME, blobKey, TestUtils.getImageForBlobPayload()); - result = blobStore.blobExists(CONTAINER_NAME, blobKey); - assertTrue(result, "Blob doesn't exist"); - } - - - public void testGetBlob_NotExistingContainer() { - try { - blobStore.getBlob(CONTAINER_NAME, TestUtils.createRandomBlobKey(), null); - fail("Retrieve must fail, container does not exist."); - } catch(ContainerNotFoundException e) { - //correct if arrive here - } - } - - /** - * Test of getBlob method, of class FilesystemAsyncBlobStore. - */ - public void testGetBlob() throws IOException { - String blobKey = TestUtils.createRandomBlobKey(); - GetOptions options = null; - Blob resultBlob; - - blobStore.createContainerInLocation(null, CONTAINER_NAME); - - resultBlob = blobStore.getBlob(CONTAINER_NAME, blobKey, options); - assertNull(resultBlob, "Blob exists"); - - //create blob - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{blobKey}); - - resultBlob = blobStore.getBlob(CONTAINER_NAME, blobKey, options); - - assertNotNull(resultBlob, "Blob exists"); - //checks file content - InputStream expectedFile = new FileInputStream(TARGET_CONTAINER_NAME + File.separator + blobKey); - InputStream currentFile = resultBlob.getPayload().getInput(); - assertTrue(TestUtils.isSame(expectedFile, currentFile), "Blob payload differs from file content"); - //metadata are verified in the test for blobMetadata, so no need to - //perform a complete test here - assertNotNull(resultBlob.getMetadata(), "Metadata null"); - MutableBlobMetadata metadata = resultBlob.getMetadata(); - assertEquals(blobKey, metadata.getName(), "Wrong blob metadata"); - } - - - public void testBlobMetadata_withDefaultMetadata() throws IOException { - String BLOB_KEY = TestUtils.createRandomBlobKey(null, null); - //create the blob - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ BLOB_KEY } - ); - - BlobMetadata metadata = blobStore.blobMetadata(CONTAINER_NAME, BLOB_KEY); - assertNotNull(metadata, "Metadata null"); - - assertEquals(metadata.getName(), BLOB_KEY, "Wrong blob name"); - assertEquals(metadata.getType(), StorageType.BLOB, "Wrong blob type"); - assertEquals(metadata.getContentMetadata().getContentType(), "application/unknown", "Wrong blob content-type"); - assertEquals(metadata.getContentMetadata().getContentMD5(), null, "Wrong blob MD5"); - assertEquals(metadata.getLocation(), null, "Wrong blob location"); - assertEquals(metadata.getProviderId(), null, "Wrong blob provider id"); - assertEquals(metadata.getUri(), null, "Wrong blob URI"); - assertNotNull(metadata.getUserMetadata(), "No blob UserMetadata"); - assertEquals(metadata.getUserMetadata().size(), 0, "Wrong blob UserMetadata"); - //metadata.getLastModified() - File file = new File(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY); - assertEquals(metadata.getContentMetadata().getContentLength(), new Long(file.length()), "Wrong blob size"); - //don't know how to calculate ETAG - //assertEquals(metadata.getETag(), "105cf4e6c052d65352dabd20028ff102", "Wrong blob ETag"); - } - - - public void testDeleteContainer_NotExistingContainer(){ - try { - blobStore.deleteContainer(CONTAINER_NAME); - fail("No error when container doesn't exist"); - } catch (Exception e) { - } - } - - public void testDeleteContainer_EmptyContanier(){ - boolean result; - blobStore.createContainerInLocation(null, CONTAINER_NAME); - - result = blobStore.containerExists(CONTAINER_NAME); - assertTrue(result, "Container doesn't exists"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - - //delete container - blobStore.deleteContainer(CONTAINER_NAME); - result = blobStore.containerExists(CONTAINER_NAME); - assertFalse(result, "Container still exists"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - } - - - public void testDeleteContainer() throws IOException{ - boolean result; - String CONTAINER_NAME2 = "container-to-delete"; - String TARGET_CONTAINER_NAME2 = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME2; - blobStore.createContainerInLocation(null, CONTAINER_NAME); - blobStore.createContainerInLocation(null, CONTAINER_NAME2); - - result = blobStore.containerExists(CONTAINER_NAME); - assertTrue(result, "Container [" + CONTAINER_NAME + "] doesn't exists"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - result = blobStore.containerExists(CONTAINER_NAME2); - assertTrue(result, "Container [" + CONTAINER_NAME2 + "] doesn't exists"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME2, true); - - //create blobs inside container - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("testutils-", null), - TestUtils.createRandomBlobKey("testutils-", null), - TestUtils.createRandomBlobKey("ab123s" + File.separator + "testutils-", null), - }); - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("testutils-", null), - TestUtils.createRandomBlobKey("testutils-", null), - TestUtils.createRandomBlobKey("asda123s" + File.separator + "testutils-", null), - TestUtils.createRandomBlobKey("123-_3s" + File.separator + "testutils-", null), - }); - - //delete first container - blobStore.deleteContainer(CONTAINER_NAME); - result = blobStore.containerExists(CONTAINER_NAME); - assertFalse(result, "Container [" + CONTAINER_NAME + "] still exists"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - result = blobStore.containerExists(CONTAINER_NAME2); - assertTrue(result, "Container [" + CONTAINER_NAME2 + "] still exists"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME2, true); - //delete second container - blobStore.deleteContainer(CONTAINER_NAME2); - result = blobStore.containerExists(CONTAINER_NAME2); - assertFalse(result, "Container [" + CONTAINER_NAME2 + "] still exists"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME2, false); - } - - - public void testInvalidContainerName() { - try { - blobStore.createContainerInLocation(null, "file/system"); - fail("Wrong container name not recognized"); - } catch (IllegalArgumentException e) {} - try { - blobStore.containerExists("file/system"); - fail("Wrong container name not recognized"); - } catch (IllegalArgumentException e) {} - } - -// public void testInvalidBlobKey() { -// try { -// blobStore.newBlob(File.separator + "testwrongblobkey"); -// fail("Wrong blob key not recognized"); -// } catch (IllegalArgumentException e) {} -// -// try { -// blobStore.newBlob("testwrongblobkey" + File.separator); -// fail("Wrong blob key not recognized"); -// } catch (IllegalArgumentException e) {} -// } - - - - //---------------------------------------------------------- Private Methods - - /** - * Creates a {@link Blob} object filled with data from a file - * @param keyName - * @param fileContent - * @return - */ - private Blob createBlob(String keyName, File filePayload) { - Blob blob = blobStore.newBlob(keyName); - blob.setPayload(filePayload); - return blob; - } - - - - /** - * Tests if container contains only the expected blobs - * @param containerName - * @param expectedBlobKeys - */ - private void checkForContainerContent(final String containerName, Set expectedBlobKeys) { - checkForContainerContent(containerName, null, expectedBlobKeys); - } - - private void checkForContainerContent(final String containerName, String inDirectory, Set expectedBlobKeys) { - ListContainerOptions options = ListContainerOptions.Builder.recursive(); - if (null != inDirectory && !"".equals(inDirectory)) options.inDirectory(inDirectory); - - PageSet blobsRetrieved = blobStore.list(containerName, options); - - //nothing expected - if (null == expectedBlobKeys || 0 == expectedBlobKeys.size()) { - assertTrue(blobsRetrieved.isEmpty(), "Wrong blob number retrieved in the containter [" + containerName + "]"); - return; - } - - //copies values - Set expectedBlobKeysCopy = new HashSet(); - for (String value:expectedBlobKeys){ - expectedBlobKeysCopy.add(value); - } - assertEquals(blobsRetrieved.size(), expectedBlobKeysCopy.size(), "Wrong blob number retrieved in the containter [" + containerName + "]"); - for (StorageMetadata data : blobsRetrieved) { - String blobName = data.getName(); - if (!expectedBlobKeysCopy.remove(blobName)) { - fail("List for container [" + containerName + "] contains unexpected value [" + blobName + "]"); - } - } - assertTrue(expectedBlobKeysCopy.isEmpty(), "List operation for container [" + containerName + "] doesn't return all values."); - } - - /** - * Create a blob with putBlob method - */ - private void putBlobAndCheckIt(String blobKey) { - Blob blob; - - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + blobKey, false); - - //create the blob - blob = createBlob(blobKey, TestUtils.getImageForBlobPayload()); - String eTag = blobStore.putBlob(CONTAINER_NAME, blob); - assertNotNull(eTag, "putBlob result null"); - assertNotSame(eTag, "", "putBlob result empty"); - - //checks if the blob exists - TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + blobKey, true); - } + private static final String CONTAINER_NAME = "fun-blobstore-test"; + private static final String TARGET_CONTAINER_NAME = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME; + private static final String LOGGING_CONFIG_KEY = "java.util.logging.config.file"; + private static final String LOGGING_CONFIG_VALUE = "src/main/resources/logging.properties"; + + private static final String PROVIDER = "filesystem"; + + static { + System.setProperty(LOGGING_CONFIG_KEY, LOGGING_CONFIG_VALUE); + + } + + private BlobStoreContext context = null; + private BlobStore blobStore = null; + private Set resourcesToBeDeleted = new HashSet(); + + @BeforeMethod + protected void setUp() throws Exception { + // create context for filesystem container + Properties prop = new Properties(); + prop.setProperty(FilesystemConstants.PROPERTY_BASEDIR, TestUtils.TARGET_BASE_DIR); + context = (BlobStoreContext) new BlobStoreContextFactory().createContext(PROVIDER, prop); + // create a container in the default location + blobStore = context.getBlobStore(); + + resourcesToBeDeleted.add(new File(TestUtils.TARGET_BASE_DIR)); + } + + @AfterMethod + protected void tearDown() { + context.close(); + context = null; + // freeing filesystem resources used for tests + Iterator resourceToDelete = resourcesToBeDeleted.iterator(); + while (resourceToDelete.hasNext()) { + File fileToDelete = resourceToDelete.next(); + try { + FileUtils.forceDelete(fileToDelete); + } catch (IOException ex) { + System.err.println("Error deleting folder [" + fileToDelete.getName() + "]."); + } + resourceToDelete.remove(); + } + } + + /** + * Checks if context parameters are managed in the correct way + * + */ + public void testParameters() { + // no base directory declared in properties + try { + Properties props = new Properties(); + new BlobStoreContextFactory().createContext(PROVIDER, props); + fail("No error if base directory is not specified"); + } catch (CreationException e) { + } + + // no base directory declared in properties + try { + Properties props = new Properties(); + props.setProperty(FilesystemConstants.PROPERTY_BASEDIR, null); + new BlobStoreContextFactory().createContext(PROVIDER, props); + fail("No error if base directory is null in the option"); + } catch (NullPointerException e) { + } + } + + /** + * Test of list method of the root context + */ + public void testList_Root() throws IOException { + PageSet containersRetrieved; + Set containersCreated = new HashSet(); + + // Testing list with no containers + containersRetrieved = blobStore.list(); + assertTrue(containersRetrieved.isEmpty(), "List operation returns a not empty set of container"); + + // Testing list with some containers + String[] containerNames = new String[] { "34343", "aaaa", "bbbbb" }; + containersCreated = new HashSet(); + for (String containerName : containerNames) { + blobStore.createContainerInLocation(null, containerName); + containersCreated.add(containerName); + } + + containersRetrieved = blobStore.list(); + assertEquals(containersCreated.size(), containersRetrieved.size(), "Different numbers of container"); + + for (StorageMetadata data : containersRetrieved) { + String containerName = data.getName(); + if (!containersCreated.remove(containerName)) { + fail("Container list contains unexpected value [" + containerName + "]"); + } + } + assertTrue(containersCreated.isEmpty(), "List operation doesn't return all values."); + + for (String containerName : containerNames) { + // delete all creaded containers + blobStore.deleteContainer(containerName); + } + containersRetrieved = blobStore.list(); + assertTrue(containersRetrieved.isEmpty(), "List operation returns a not empty set of container"); + } + + /** + * Test of list method, of class FilesystemAsyncBlobStore. + */ + public void testList_NoOptionSingleContainer() throws IOException { + blobStore.createContainerInLocation(null, CONTAINER_NAME); + // Testing list for an empty container + checkForContainerContent(CONTAINER_NAME, null); + + // creates blobs in first container + Set 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", "xdc" + File.separator + "wert.kpg" }); + + checkForContainerContent(CONTAINER_NAME, blobsExpected); + } + + public void testList_NotExistingContainer() { + // Testing list for a not existing container + try { + blobStore.list(CONTAINER_NAME); + fail("Found a not existing container"); + } catch (ContainerNotFoundException e) { + // ok if arriver here + } + } + + /** + * Test of list method, of class FilesystemAsyncBlobStore. + */ + public void testList_NoOptionDoubleContainer() throws IOException { + final String CONTAINER_NAME2 = "container2"; + + // create first container + blobStore.createContainerInLocation(null, CONTAINER_NAME); + // checks for empty container + checkForContainerContent(CONTAINER_NAME, null); + + // create second container + blobStore.createContainerInLocation(null, CONTAINER_NAME2); + // checks for empty + checkForContainerContent(CONTAINER_NAME2, null); + + // creates blobs in first container + + Set blobNamesCreatedInContainer1 = TestUtils.createBlobsInContainer(CONTAINER_NAME, + new String[] { "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg", + TestUtils.createRandomBlobKey(), "rrr" + File.separator + "sss" + File.separator + "788.jpg", + "xdc" + File.separator + "wert.kpg" }); + + // creates blobs in second container + blobStore.createContainerInLocation(null, CONTAINER_NAME2); + Set blobNamesCreatedInContainer2 = TestUtils.createBlobsInContainer(CONTAINER_NAME2, new String[] { + "asd" + File.separator + "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + + "1234.jpg", TestUtils.createRandomBlobKey(), + "rrr" + File.separator + "sss" + File.separator + "788.jpg", "xdc" + File.separator + "wert.kpg" }); + + // test blobs in first container + checkForContainerContent(CONTAINER_NAME, blobNamesCreatedInContainer1); + // test blobs in second container + checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2); + } + + 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 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 Should throws an exception? + */ + public void testClearContainer_NotExistingContainer() { + blobStore.clearContainer(CONTAINER_NAME); + } + + /** + * Integration test, because clearContainer is not redefined in {@link FilesystemAsyncBlobStore} + * class + */ + public void testClearContainer_NoOptions() throws IOException { + final String CONTAINER_NAME2 = "containerToClear"; + + // create containers + blobStore.createContainerInLocation(null, CONTAINER_NAME); + blobStore.createContainerInLocation(null, CONTAINER_NAME2); + + // creates blobs in first container + Set blobNamesCreatedInContainer1 = TestUtils.createBlobsInContainer(CONTAINER_NAME, + new String[] { "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + "1234.jpg", + TestUtils.createRandomBlobKey(), "rrr" + File.separator + "sss" + File.separator + "788.jpg", + "xdc" + File.separator + "wert.kpg" }); + + // creates blobs in second container + blobStore.createContainerInLocation(null, CONTAINER_NAME2); + Set blobNamesCreatedInContainer2 = TestUtils.createBlobsInContainer(CONTAINER_NAME2, new String[] { + "asd" + File.separator + "bbb" + File.separator + "ccc" + File.separator + "ddd" + File.separator + + "1234.jpg", TestUtils.createRandomBlobKey(), + "rrr" + File.separator + "sss" + File.separator + "788.jpg", "xdc" + File.separator + "wert.kpg" }); + + // test blobs in containers + checkForContainerContent(CONTAINER_NAME, blobNamesCreatedInContainer1); + checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2); + + // delete blobs in first container + blobStore.clearContainer(CONTAINER_NAME); + checkForContainerContent(CONTAINER_NAME, null); + checkForContainerContent(CONTAINER_NAME2, blobNamesCreatedInContainer2); + // delete blobs in second container + blobStore.clearContainer(CONTAINER_NAME2); + checkForContainerContent(CONTAINER_NAME2, null); + } + + /** + * Integration test, because countBlobs is not redefined in {@link FilesystemAsyncBlobStore} + * class + */ + public void testCountBlobs_NotExistingContainer() { + try { + blobStore.countBlobs(PROVIDER); + fail("Magically the method was implemented... Wow!"); + } catch (UnsupportedOperationException e) { + } + } + + /** + * Integration test, because countBlobs is not redefined in {@link FilesystemAsyncBlobStore} + * class + */ + public void testCountBlobs_NoOptionsEmptyContainer() { + blobStore.createContainerInLocation(null, CONTAINER_NAME); + try { + blobStore.countBlobs(PROVIDER); + fail("Magically the method was implemented... Wow!"); + } catch (UnsupportedOperationException e) { + } + } + + /** + * Integration test, because countBlobs is not redefined in {@link FilesystemAsyncBlobStore} + * class + */ + public void testCountBlobs_NoOptions() { + blobStore.createContainerInLocation(null, CONTAINER_NAME); + try { + blobStore.countBlobs(PROVIDER); + fail("Magically the method was implemented... Wow!"); + } catch (UnsupportedOperationException e) { + } + } + + public void testRemoveBlob_SimpleBlobKey() throws IOException { + final String BLOB_KEY = TestUtils.createRandomBlobKey(null, ".txt"); + boolean result; + + blobStore.createContainerInLocation(null, CONTAINER_NAME); + + // checks that blob doesn't exists + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); + assertFalse(result, "Blob exists"); + + // create the blob + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { BLOB_KEY }); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); + assertTrue(result, "Blob exists"); + + // remove it + blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); + assertFalse(result, "Blob still exists"); + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false); + } + + public void testRemoveBlob_TwoSimpleBlobKeys() throws IOException { + final String BLOB_KEY1 = TestUtils.createRandomBlobKey(null, null); + final String BLOB_KEY2 = TestUtils.createRandomBlobKey(null, null); + boolean result; + + // create the container and checks that blob doesn't exists + blobStore.createContainerInLocation(null, CONTAINER_NAME); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); + assertFalse(result, "Blob1 exists"); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); + assertFalse(result, "Blob2 exists"); + + // create the blob + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { BLOB_KEY1, BLOB_KEY2 }); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); + assertTrue(result, "Blob " + BLOB_KEY1 + " doesn't exist"); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); + assertTrue(result, "Blob " + BLOB_KEY2 + " doesn't exist"); + + // remove first blob + blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY1); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); + assertFalse(result, "Blob1 still exists"); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); + assertTrue(result, "Blob2 doesn't exist"); + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY1, false); + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, true); + // remove second blob + blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY2); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); + assertFalse(result, "Blob2 still exists"); + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, false); + } + + /** + * Test of removeBlob method, with only one blob with a complex path as key + */ + public void testRemoveBlob_ComplexBlobKey() throws IOException { + final String BLOB_KEY = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null); + boolean result; + + // checks that blob doesn't exists + blobStore.createContainerInLocation(null, CONTAINER_NAME); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); + assertFalse(result, "Blob exists"); + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false); + + // create the blob + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { BLOB_KEY }); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); + assertTrue(result, "Blob doesn't exist"); + + // remove it + blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY); + assertFalse(result, "Blob still exists"); + // file removed + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY, false); + // also the entire directory structure was removed + TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa", false); + } + + /** + * Test of removeBlob method, with two blobs with a complex path as key and when first blob is + * removed, not all of its key's path is removed, because it is shared with the second blob's key + */ + public void testRemoveBlob_TwoComplexBlobKeys() throws IOException { + final String BLOB_KEY1 = TestUtils.createRandomBlobKey("aa/bb/cc/dd/", null); + final String BLOB_KEY2 = TestUtils.createRandomBlobKey("aa/bb/ee/ff/", null); + boolean result; + + blobStore.createContainerInLocation(null, CONTAINER_NAME); + + // checks that blob doesn't exist + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); + assertFalse(result, "Blob1 exists"); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); + assertFalse(result, "Blob2 exists"); + + // create the blobs + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { BLOB_KEY1, BLOB_KEY2 }); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); + assertTrue(result, "Blob " + BLOB_KEY1 + " doesn't exist"); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); + assertTrue(result, "Blob " + BLOB_KEY2 + " doesn't exist"); + + // remove first blob + blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY1); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY1); + assertFalse(result, "Blob still exists"); + // first file deleted, not the second + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY1, false); + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, true); + // only partial directory structure was removed, because it shares a path + // with the second blob created + TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa/bb/cc/dd", false); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa/bb", true); + // remove second blob + blobStore.removeBlob(CONTAINER_NAME, BLOB_KEY2); + result = blobStore.blobExists(CONTAINER_NAME, BLOB_KEY2); + assertFalse(result, "Blob still exists"); + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY2, false); + // now all the directory structure is empty + TestUtils.directoryExists(TARGET_CONTAINER_NAME + "/aa", false); + } + + /** + * Test of containerExists method, of class FilesystemAsyncBlobStore. + */ + public void testContainerExists() throws IOException { + boolean result; + + result = blobStore.containerExists(CONTAINER_NAME); + assertFalse(result, "Container exists"); + + // create container + TestUtils.createContainerAsDirectory(CONTAINER_NAME); + + result = blobStore.containerExists(CONTAINER_NAME); + assertTrue(result, "Container doesn't exist"); + } + + /** + * Test of createContainerInLocation method, of class FilesystemAsyncBlobStore. + */ + public void testCreateContainerInLocation() throws IOException { + final String CONTAINER_NAME2 = "funambol-test-2"; + final String TARGET_CONTAINER_NAME2 = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME2; + + boolean result; + + result = blobStore.containerExists(CONTAINER_NAME); + assertFalse(result, "Container exists"); + result = blobStore.createContainerInLocation(null, CONTAINER_NAME); + assertTrue(result, "Container not created"); + result = blobStore.containerExists(CONTAINER_NAME); + assertTrue(result, "Container doesn't exist"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + + result = blobStore.containerExists(CONTAINER_NAME2); + assertFalse(result, "Container exists"); + result = blobStore.createContainerInLocation(null, CONTAINER_NAME2); + assertTrue(result, "Container not created"); + result = blobStore.containerExists(CONTAINER_NAME2); + assertTrue(result, "Container doesn't exist"); + TestUtils.directoryExists(TestUtils.TARGET_BASE_DIR + CONTAINER_NAME2, true); + + // clean the environment + FileUtils.forceDelete(new File(TARGET_CONTAINER_NAME2)); + } + + /** + * Test of putBlob method, of class FilesystemAsyncBlobStore. with a simple filename - no path in + * the filename, eg filename.jpg + */ + public void testPutBlobSimpleName() { + blobStore.createContainerInLocation(null, CONTAINER_NAME); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); + } + + /** + * Test of putBlob method with a complex key, with path in the filename, eg picture/filename.jpg + */ + public void testPutBlobComplexName1() { + blobStore.createContainerInLocation(null, CONTAINER_NAME); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("picture/putBlob-", ".jpg")); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("video/putBlob-", ".jpg")); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("video/putBlob-", ".jpg")); + } + + /** + * Test of putBlob method with a complex key, with path in the filename, eg picture/filename.jpg + */ + public void testPutBlobComplexName2() { + blobStore.createContainerInLocation(null, CONTAINER_NAME); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("aa/bb/cc/dd/ee/putBlob-", ".jpg")); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("aa/bb/cc/dd/ee/putBlob-", ".jpg")); + putBlobAndCheckIt(TestUtils.createRandomBlobKey("putBlob-", ".jpg")); + } + + /** + * Test of blobExists method, of class FilesystemAsyncBlobStore. + */ + public void testBlobExists() throws IOException { + boolean result; + String blobKey; + + // when location doesn't exists + blobKey = TestUtils.createRandomBlobKey(); + result = blobStore.blobExists(CONTAINER_NAME, blobKey); + assertFalse(result, "Blob exists"); + + // when location exists + blobStore.createContainerInLocation(null, CONTAINER_NAME); + result = blobStore.blobExists(CONTAINER_NAME, blobKey); + assertFalse(result, "Blob exists"); + + // create blob + TestUtils.createBlobAsFile(CONTAINER_NAME, blobKey, TestUtils.getImageForBlobPayload()); + result = blobStore.blobExists(CONTAINER_NAME, blobKey); + assertTrue(result, "Blob doesn't exist"); + + // complex path test + blobKey = TestUtils.createRandomBlobKey("ss/asdas/", ""); + result = blobStore.blobExists(CONTAINER_NAME, blobKey); + assertFalse(result, "Blob exists"); + TestUtils.createBlobAsFile(CONTAINER_NAME, blobKey, TestUtils.getImageForBlobPayload()); + result = blobStore.blobExists(CONTAINER_NAME, blobKey); + assertTrue(result, "Blob doesn't exist"); + } + + public void testGetBlob_NotExistingContainer() { + try { + blobStore.getBlob(CONTAINER_NAME, TestUtils.createRandomBlobKey(), null); + fail("Retrieve must fail, container does not exist."); + } catch (ContainerNotFoundException e) { + // correct if arrive here + } + } + + /** + * Test of getBlob method, of class FilesystemAsyncBlobStore. + */ + public void testGetBlob() throws IOException { + String blobKey = TestUtils.createRandomBlobKey(); + GetOptions options = null; + Blob resultBlob; + + blobStore.createContainerInLocation(null, CONTAINER_NAME); + + resultBlob = blobStore.getBlob(CONTAINER_NAME, blobKey, options); + assertNull(resultBlob, "Blob exists"); + + // create blob + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { blobKey }); + + resultBlob = blobStore.getBlob(CONTAINER_NAME, blobKey, options); + + assertNotNull(resultBlob, "Blob exists"); + // checks file content + InputStream expectedFile = new FileInputStream(TARGET_CONTAINER_NAME + File.separator + blobKey); + InputStream currentFile = resultBlob.getPayload().getInput(); + assertTrue(TestUtils.isSame(expectedFile, currentFile), "Blob payload differs from file content"); + // metadata are verified in the test for blobMetadata, so no need to + // perform a complete test here + assertNotNull(resultBlob.getMetadata(), "Metadata null"); + MutableBlobMetadata metadata = resultBlob.getMetadata(); + assertEquals(blobKey, metadata.getName(), "Wrong blob metadata"); + } + + public void testBlobMetadata_withDefaultMetadata() throws IOException { + String BLOB_KEY = TestUtils.createRandomBlobKey(null, null); + // create the blob + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { BLOB_KEY }); + + BlobMetadata metadata = blobStore.blobMetadata(CONTAINER_NAME, BLOB_KEY); + assertNotNull(metadata, "Metadata null"); + + assertEquals(metadata.getName(), BLOB_KEY, "Wrong blob name"); + assertEquals(metadata.getType(), StorageType.BLOB, "Wrong blob type"); + assertEquals(metadata.getContentMetadata().getContentType(), "application/unknown", "Wrong blob content-type"); + assertEquals(metadata.getContentMetadata().getContentMD5(), null, "Wrong blob MD5"); + assertEquals(metadata.getLocation(), null, "Wrong blob location"); + assertEquals(metadata.getProviderId(), null, "Wrong blob provider id"); + assertEquals(metadata.getUri(), null, "Wrong blob URI"); + assertNotNull(metadata.getUserMetadata(), "No blob UserMetadata"); + assertEquals(metadata.getUserMetadata().size(), 0, "Wrong blob UserMetadata"); + // metadata.getLastModified() + File file = new File(TARGET_CONTAINER_NAME + File.separator + BLOB_KEY); + assertEquals(metadata.getContentMetadata().getContentLength(), new Long(file.length()), "Wrong blob size"); + // don't know how to calculate ETAG + // assertEquals(metadata.getETag(), "105cf4e6c052d65352dabd20028ff102", "Wrong blob ETag"); + } + + public void testDeleteContainer_NotExistingContainer() { + try { + blobStore.deleteContainer(CONTAINER_NAME); + fail("No error when container doesn't exist"); + } catch (Exception e) { + } + } + + public void testDeleteContainer_EmptyContanier() { + boolean result; + blobStore.createContainerInLocation(null, CONTAINER_NAME); + + result = blobStore.containerExists(CONTAINER_NAME); + assertTrue(result, "Container doesn't exists"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + + // delete container + blobStore.deleteContainer(CONTAINER_NAME); + result = blobStore.containerExists(CONTAINER_NAME); + assertFalse(result, "Container still exists"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + } + + public void testDeleteContainer() throws IOException { + boolean result; + String CONTAINER_NAME2 = "container-to-delete"; + String TARGET_CONTAINER_NAME2 = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME2; + blobStore.createContainerInLocation(null, CONTAINER_NAME); + blobStore.createContainerInLocation(null, CONTAINER_NAME2); + + result = blobStore.containerExists(CONTAINER_NAME); + assertTrue(result, "Container [" + CONTAINER_NAME + "] doesn't exists"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + result = blobStore.containerExists(CONTAINER_NAME2); + assertTrue(result, "Container [" + CONTAINER_NAME2 + "] doesn't exists"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME2, true); + + // create blobs inside container + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { + TestUtils.createRandomBlobKey("testutils-", null), TestUtils.createRandomBlobKey("testutils-", null), + TestUtils.createRandomBlobKey("ab123s" + File.separator + "testutils-", null), }); + TestUtils.createBlobsInContainer( + CONTAINER_NAME, + new String[] { TestUtils.createRandomBlobKey("testutils-", null), + TestUtils.createRandomBlobKey("testutils-", null), + TestUtils.createRandomBlobKey("asda123s" + File.separator + "testutils-", null), + TestUtils.createRandomBlobKey("123-_3s" + File.separator + "testutils-", null), }); + + // delete first container + blobStore.deleteContainer(CONTAINER_NAME); + result = blobStore.containerExists(CONTAINER_NAME); + assertFalse(result, "Container [" + CONTAINER_NAME + "] still exists"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + result = blobStore.containerExists(CONTAINER_NAME2); + assertTrue(result, "Container [" + CONTAINER_NAME2 + "] still exists"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME2, true); + // delete second container + blobStore.deleteContainer(CONTAINER_NAME2); + result = blobStore.containerExists(CONTAINER_NAME2); + assertFalse(result, "Container [" + CONTAINER_NAME2 + "] still exists"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME2, false); + } + + public void testInvalidContainerName() { + try { + blobStore.createContainerInLocation(null, "file/system"); + fail("Wrong container name not recognized"); + } catch (IllegalArgumentException e) { + } + try { + blobStore.containerExists("file/system"); + fail("Wrong container name not recognized"); + } catch (IllegalArgumentException e) { + } + } + + // public void testInvalidBlobKey() { + // try { + // blobStore.newBlob(File.separator + "testwrongblobkey"); + // fail("Wrong blob key not recognized"); + // } catch (IllegalArgumentException e) {} + // + // try { + // blobStore.newBlob("testwrongblobkey" + File.separator); + // fail("Wrong blob key not recognized"); + // } catch (IllegalArgumentException e) {} + // } + + // ---------------------------------------------------------- Private Methods + + /** + * Creates a {@link Blob} object filled with data from a file + * + * @param keyName + * @param fileContent + * @return + */ + private Blob createBlob(String keyName, File filePayload) { + return blobStore.blobBuilder(keyName).payload(filePayload).build(); + } + + /** + * Tests if container contains only the expected blobs + * + * @param containerName + * @param expectedBlobKeys + */ + private void checkForContainerContent(final String containerName, Set expectedBlobKeys) { + checkForContainerContent(containerName, null, expectedBlobKeys); + } + + private void checkForContainerContent(final String containerName, String inDirectory, Set expectedBlobKeys) { + ListContainerOptions options = ListContainerOptions.Builder.recursive(); + if (null != inDirectory && !"".equals(inDirectory)) + options.inDirectory(inDirectory); + + PageSet blobsRetrieved = blobStore.list(containerName, options); + + // nothing expected + if (null == expectedBlobKeys || 0 == expectedBlobKeys.size()) { + assertTrue(blobsRetrieved.isEmpty(), "Wrong blob number retrieved in the containter [" + containerName + "]"); + return; + } + + // copies values + Set expectedBlobKeysCopy = new HashSet(); + for (String value : expectedBlobKeys) { + expectedBlobKeysCopy.add(value); + } + assertEquals(blobsRetrieved.size(), expectedBlobKeysCopy.size(), + "Wrong blob number retrieved in the containter [" + containerName + "]"); + for (StorageMetadata data : blobsRetrieved) { + String blobName = data.getName(); + if (!expectedBlobKeysCopy.remove(blobName)) { + fail("List for container [" + containerName + "] contains unexpected value [" + blobName + "]"); + } + } + assertTrue(expectedBlobKeysCopy.isEmpty(), "List operation for container [" + containerName + + "] doesn't return all values."); + } + + /** + * Create a blob with putBlob method + */ + private void putBlobAndCheckIt(String blobKey) { + Blob blob; + + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + blobKey, false); + + // create the blob + blob = createBlob(blobKey, TestUtils.getImageForBlobPayload()); + String eTag = blobStore.putBlob(CONTAINER_NAME, blob); + assertNotNull(eTag, "putBlob result null"); + assertNotSame(eTag, "", "putBlob result empty"); + + // checks if the blob exists + TestUtils.fileExists(TARGET_CONTAINER_NAME + File.separator + blobKey, true); + } } diff --git a/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTest.java b/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTest.java index 8281ef9681..f8339ecaa2 100644 --- a/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTest.java +++ b/apis/filesystem/src/test/java/org/jclouds/filesystem/integration/FilesystemContainerIntegrationTest.java @@ -31,6 +31,7 @@ import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; /** @@ -45,19 +46,16 @@ public class FilesystemContainerIntegrationTest extends BaseContainerIntegration String key = "hello"; - Blob object = context.getBlobStore().newBlob(key); - object.setPayload(TEST_STRING); - object.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN); // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // providers. - object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); + Blob object = context.getBlobStore().blobBuilder(key).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).build(); String containerName = getContainerName(); try { addBlobToContainer(containerName, object); validateContent(containerName, key); - PageSet container = context.getBlobStore().list(containerName, - maxResults(1)); + PageSet container = context.getBlobStore().list(containerName, maxResults(1)); BlobMetadata metadata = (BlobMetadata) Iterables.getOnlyElement(container); // transient container should be lenient and not return metadata on undetailed listing. diff --git a/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java b/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java index 803bb85997..a240f60c26 100644 --- a/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java +++ b/apis/filesystem/src/test/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImplTest.java @@ -19,12 +19,12 @@ package org.jclouds.filesystem.strategy.internal; -import java.util.List; -import java.util.Set; -import org.jclouds.blobstore.domain.internal.MutableBlobMetadataImpl; -import org.jclouds.blobstore.domain.internal.BlobImpl; -import org.jclouds.blobstore.domain.MutableBlobMetadata; -import org.jclouds.blobstore.domain.Blob; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -32,15 +32,23 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.inject.Provider; + +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; +import org.jclouds.blobstore.domain.internal.BlobBuilderImpl; import org.jclouds.blobstore.options.ListContainerOptions; -import org.jclouds.filesystem.predicates.validators.internal.FilesystemContainerNameValidatorImpl; import org.jclouds.filesystem.predicates.validators.internal.FilesystemBlobKeyValidatorImpl; +import org.jclouds.filesystem.predicates.validators.internal.FilesystemContainerNameValidatorImpl; import org.jclouds.filesystem.strategy.FilesystemStorageStrategy; import org.jclouds.filesystem.utils.TestUtils; import org.jclouds.io.payloads.FilePayload; -import org.testng.annotations.*; - -import static org.testng.Assert.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; /** * Test class for {@link FilesystemStorageStrategyImpl } class @@ -49,529 +57,483 @@ import static org.testng.Assert.*; */ @Test(groups = "unit", testName = "filesystem.FilesystemBlobUtilsTest", sequential = true) public class FilesystemStorageStrategyImplTest { - private static final String CONTAINER_NAME = "funambol-test"; - private static final String TARGET_CONTAINER_NAME = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME; - - private static final String LOGGING_CONFIG_KEY = "java.util.logging.config.file"; - private static final String LOGGING_CONFIG_VALUE = "src/main/resources/logging.properties"; - - private static final String FS = File.separator; - - static { - System.setProperty(LOGGING_CONFIG_KEY, - LOGGING_CONFIG_VALUE); - } - - private FilesystemStorageStrategy storageStrategy; - - @BeforeMethod - protected void setUp() throws Exception { - storageStrategy = new FilesystemStorageStrategyImpl( - new Blob.Factory() { - @Override - public Blob create(MutableBlobMetadata metadata) { - return new BlobImpl(metadata != null ? metadata : new MutableBlobMetadataImpl()); - } - }, - TestUtils.TARGET_BASE_DIR, - new FilesystemContainerNameValidatorImpl(), - new FilesystemBlobKeyValidatorImpl()); - TestUtils.cleanDirectoryContent(TestUtils.TARGET_BASE_DIR); - } - - - @AfterMethod - protected void tearDown() throws IOException { - TestUtils.cleanDirectoryContent(TestUtils.TARGET_BASE_DIR); - } - - - public void testCreateDirectory() { - storageStrategy.createDirectory(CONTAINER_NAME, null); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - - storageStrategy.createDirectory(CONTAINER_NAME, "subdir"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir", true); - - storageStrategy.createDirectory(CONTAINER_NAME, "subdir1" + FS); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir1", true); - - storageStrategy.createDirectory(CONTAINER_NAME, FS + "subdir2"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir2", true); - - storageStrategy.createDirectory(CONTAINER_NAME, "subdir3" + FS + "subdir4"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir2", true); - } - - public void testCreateDirectory_DirectoryAlreadyExists() { - storageStrategy.createDirectory(CONTAINER_NAME, null); - storageStrategy.createDirectory(CONTAINER_NAME, null); - } - - public void testCreateDirectory_WrongDirectoryName() { - try { - storageStrategy.createDirectory(CONTAINER_NAME, "$%&!'`\\/"); - fail("No exception throwed"); - } catch(Exception e) { - } - } - - - public void testCreateContainer() { - boolean result; - - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - result = storageStrategy.createContainer(CONTAINER_NAME); - assertTrue(result, "Container not created"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - } - - public void testCreateContainer_ContainerAlreadyExists() { - boolean result; - - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - result = storageStrategy.createContainer(CONTAINER_NAME); - assertTrue(result, "Container not created"); - result = storageStrategy.createContainer(CONTAINER_NAME); - assertFalse(result, "Container not created"); - } - - - public void testDeleteDirectory() throws IOException { - TestUtils.createContainerAsDirectory(CONTAINER_NAME); - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev3" + FS, ".txt"), - TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev4" + FS, ".jpg") - } - ); - - //delete directory in different ways - storageStrategy.deleteDirectory(CONTAINER_NAME, "lev1" + FS + "lev2" + FS + "lev4"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2" + FS + "lev4", false); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2", true); - - storageStrategy.deleteDirectory(CONTAINER_NAME, "lev1" + FS + "lev2" + FS + "lev3" + FS); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2" + FS + "lev3", false); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2", true); - - storageStrategy.deleteDirectory(CONTAINER_NAME, FS + "lev1"); - TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1", false); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - - //delete the directory and all the files inside - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev3" + FS, ".txt"), - TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev4" + FS, ".jpg") - } - ); - storageStrategy.deleteDirectory(CONTAINER_NAME, null); - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - } - - public void testDeleteDirectory_ErrorWhenNotExists(){ - try { - storageStrategy.deleteDirectory(CONTAINER_NAME, null); - fail("No exception throwed"); - } catch(Exception e) { - } - } - - - public void testDirectoryExists() throws IOException { - final String SUBDIRECTORY_NAME = "ad" + FS + "sda" + FS + "asd"; - boolean result; - - result = storageStrategy.directoryExists(CONTAINER_NAME, null); - assertFalse(result, "Directory exist"); - - //create the container - TestUtils.createContainerAsDirectory(CONTAINER_NAME); - //check if exists - result = storageStrategy.directoryExists(CONTAINER_NAME, null); - assertTrue(result, "Directory doesn't exist"); - result = storageStrategy.directoryExists(CONTAINER_NAME + FS, null); - assertTrue(result, "Directory doesn't exist"); - - - result = storageStrategy.directoryExists(CONTAINER_NAME, SUBDIRECTORY_NAME); - assertFalse(result, "Directory exist"); - - //create subdirs inside the container - TestUtils.createContainerAsDirectory(CONTAINER_NAME + FS + SUBDIRECTORY_NAME); - //check if exists - result = storageStrategy.directoryExists(CONTAINER_NAME, SUBDIRECTORY_NAME); - assertTrue(result, "Directory doesn't exist"); - result = storageStrategy.directoryExists(CONTAINER_NAME, FS + SUBDIRECTORY_NAME); - assertTrue(result, "Directory doesn't exist"); - result = storageStrategy.directoryExists(CONTAINER_NAME, SUBDIRECTORY_NAME + FS); - assertTrue(result, "Directory doesn't exist"); - result = storageStrategy.directoryExists(CONTAINER_NAME + FS, FS + SUBDIRECTORY_NAME); - assertTrue(result, "Directory doesn't exist"); - - } - - - public void testClearContainer() throws IOException{ - storageStrategy.createContainer(CONTAINER_NAME); - Set blobs = TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("clean_container-", ".jpg"), - TestUtils.createRandomBlobKey("bf" + FS + "sd" + FS + "as" + FS + "clean_container-", ".jpg")} - ); - //test if file exits - for(String blob:blobs) { - TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, true); - } - - //clear the container - storageStrategy.clearContainer(CONTAINER_NAME); - //test if container still exits - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - //test if file was cleared - for(String blob:blobs) { - TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, false); - } - } - - - public void testClearContainer_NotExistingContainer() throws IOException{ - //test if container still exits - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - //clear the container - storageStrategy.clearContainer(CONTAINER_NAME); - //test if container still exits - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - } - - - public void testClearContainerAndThenDeleteContainer() throws IOException{ - storageStrategy.createContainer(CONTAINER_NAME); - Set blobs = TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("clean_container-", ".jpg"), - TestUtils.createRandomBlobKey("bf" + FS + "sd" + FS + "as" + FS + "clean_container-", ".jpg")} - ); - //test if file exits - for(String blob:blobs) { - TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, true); - } - - //clear the container - storageStrategy.clearContainer(CONTAINER_NAME); - //test if container still exits - TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); - //test if file was cleared - for(String blob:blobs) { - TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, false); - } - - //delete the container - storageStrategy.deleteContainer(CONTAINER_NAME); - //test if container still exits - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - assertFalse(storageStrategy.containerExists(CONTAINER_NAME), "Container still exists"); - } - - - public void testDeleteContainer() throws IOException { - final String BLOB_KEY1 = "blobName.jpg"; - final String BLOB_KEY2 = "aa" + FS + "bb" + FS + "cc" + FS + "dd" + FS + "ee" + FS + "ff" + FS + "23" + FS + "blobName.jpg"; - boolean result; - - result = storageStrategy.createContainer(CONTAINER_NAME); - - //put data inside the container - TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[] {BLOB_KEY1, BLOB_KEY2} - ); - - storageStrategy.deleteContainer(CONTAINER_NAME); - assertTrue(result, "Cannot delete container"); - TestUtils.directoryExists(CONTAINER_NAME, false); - } - - public void testDeleteContainer_EmptyContainer() { - boolean result; - - result = storageStrategy.createContainer(CONTAINER_NAME); - assertTrue(result, "Cannot create container"); - - storageStrategy.deleteContainer(CONTAINER_NAME); - TestUtils.directoryExists(CONTAINER_NAME, false); - } - - public void testDeleteContainer_ErrorWhenNotExists() { - try { - storageStrategy.deleteContainer(CONTAINER_NAME); - fail("Exception not throwed"); - } catch (Exception e) { - } - } - - - public void testGetAllContainerNames() { - Iterable resultList; - - //no container - resultList = storageStrategy.getAllContainerNames(); - assertNotNull(resultList, "Result is null"); - assertFalse(resultList.iterator().hasNext(), "Containers detected"); - - //create containers - storageStrategy.createContainer(CONTAINER_NAME + "1"); - storageStrategy.createContainer(CONTAINER_NAME + "2"); - storageStrategy.createContainer(CONTAINER_NAME + "3"); - - List containers = new ArrayList(); - resultList = storageStrategy.getAllContainerNames(); - Iterator containersIterator = resultList.iterator(); - while(containersIterator.hasNext()){ - containers.add(containersIterator.next()); - } - assertEquals(containers.size(), 3, "Different containers number"); - assertTrue(containers.contains(CONTAINER_NAME + "1"), "Containers doesn't exist"); - assertTrue(containers.contains(CONTAINER_NAME + "2"), "Containers doesn't exist"); - assertTrue(containers.contains(CONTAINER_NAME + "3"), "Containers doesn't exist"); - } - - - public void testContainerExists(){ - boolean result; - - TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); - result = storageStrategy.containerExists(CONTAINER_NAME); - assertFalse(result, "Container exists"); - storageStrategy.createContainer(CONTAINER_NAME); - result = storageStrategy.containerExists(CONTAINER_NAME); - assertTrue(result, "Container exists"); - } - - - public void testNewBlob() { - String blobKey; - Blob newBlob; - - blobKey = TestUtils.createRandomBlobKey("blobtest-", ".txt"); - newBlob = storageStrategy.newBlob(blobKey); - assertNotNull(newBlob, "Created blob was null"); - assertNotNull(newBlob.getMetadata(), "Created blob metadata were null"); - assertEquals(newBlob.getMetadata().getName(), blobKey, "Created blob name is different"); - - blobKey = TestUtils.createRandomBlobKey("blobtest-", ""); - newBlob = storageStrategy.newBlob(blobKey); - assertEquals(newBlob.getMetadata().getName(), blobKey, "Created blob name is different"); - - blobKey = TestUtils.createRandomBlobKey("asd" + FS + "asd" + FS + "asdasd" + FS + "afadsf-", ""); - newBlob = storageStrategy.newBlob(blobKey); - assertEquals(newBlob.getMetadata().getName(), blobKey, "Created blob name is different"); - } - - - public void testWritePayloadOnFile() throws IOException { - String blobKey; - File sourceFile; - FilePayload filePayload; - - blobKey = TestUtils.createRandomBlobKey("writePayload-", ".img"); - sourceFile = TestUtils.getImageForBlobPayload(); - filePayload = new FilePayload(sourceFile); - //write files - storageStrategy.writePayloadOnFile(CONTAINER_NAME, blobKey, filePayload); - //verify that the files is equal - String blobFullPath = TARGET_CONTAINER_NAME + FS + blobKey; - InputStream expectedInput = new FileInputStream(sourceFile); - InputStream currentInput = new FileInputStream(blobFullPath); - assertTrue(TestUtils.isSame(expectedInput, currentInput), "Files aren't equals"); - } - - public void testWritePayloadOnFile_SourceFileDoesntExist() { - File sourceFile = new File("asdfkjsadkfjasdlfasdflk.asdfasdfas"); - try { - new FilePayload(sourceFile); - fail("Exception not throwed"); - } catch (Exception ex) { - } - } - - - public void testGetFileForBlobKey() { - String blobKey; - File fileForPayload; - String fullPath = (new File(TARGET_CONTAINER_NAME).getAbsolutePath()) + FS; - - blobKey = TestUtils.createRandomBlobKey("getFileForBlobKey-", ".img"); - fileForPayload = storageStrategy.getFileForBlobKey(CONTAINER_NAME, blobKey); - assertNotNull(fileForPayload, "Result File object is null"); - assertEquals(fileForPayload.getAbsolutePath(), fullPath + blobKey, "Wrong file path"); - - blobKey = TestUtils.createRandomBlobKey("asd" + FS + "vmad" + FS + "andsnf" + FS + "getFileForBlobKey-", ".img"); - fileForPayload = storageStrategy.getFileForBlobKey(CONTAINER_NAME, blobKey); - assertEquals(fileForPayload.getAbsolutePath(), fullPath + blobKey, "Wrong file path"); - } - - - 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 { - String[] sourceBlobKeys = new String[]{ + private static final String CONTAINER_NAME = "funambol-test"; + private static final String TARGET_CONTAINER_NAME = TestUtils.TARGET_BASE_DIR + CONTAINER_NAME; + + private static final String LOGGING_CONFIG_KEY = "java.util.logging.config.file"; + private static final String LOGGING_CONFIG_VALUE = "src/main/resources/logging.properties"; + + private static final String FS = File.separator; + + static { + System.setProperty(LOGGING_CONFIG_KEY, LOGGING_CONFIG_VALUE); + } + + private FilesystemStorageStrategy storageStrategy; + + @BeforeMethod + protected void setUp() throws Exception { + storageStrategy = new FilesystemStorageStrategyImpl(new Provider() { + @Override + public BlobBuilder get() { + return new BlobBuilderImpl(); + } + + }, TestUtils.TARGET_BASE_DIR, new FilesystemContainerNameValidatorImpl(), new FilesystemBlobKeyValidatorImpl()); + TestUtils.cleanDirectoryContent(TestUtils.TARGET_BASE_DIR); + } + + @AfterMethod + protected void tearDown() throws IOException { + TestUtils.cleanDirectoryContent(TestUtils.TARGET_BASE_DIR); + } + + public void testCreateDirectory() { + storageStrategy.createDirectory(CONTAINER_NAME, null); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + + storageStrategy.createDirectory(CONTAINER_NAME, "subdir"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir", true); + + storageStrategy.createDirectory(CONTAINER_NAME, "subdir1" + FS); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir1", true); + + storageStrategy.createDirectory(CONTAINER_NAME, FS + "subdir2"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir2", true); + + storageStrategy.createDirectory(CONTAINER_NAME, "subdir3" + FS + "subdir4"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "subdir2", true); + } + + public void testCreateDirectory_DirectoryAlreadyExists() { + storageStrategy.createDirectory(CONTAINER_NAME, null); + storageStrategy.createDirectory(CONTAINER_NAME, null); + } + + public void testCreateDirectory_WrongDirectoryName() { + try { + storageStrategy.createDirectory(CONTAINER_NAME, "$%&!'`\\/"); + fail("No exception throwed"); + } catch (Exception e) { + } + } + + public void testCreateContainer() { + boolean result; + + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + result = storageStrategy.createContainer(CONTAINER_NAME); + assertTrue(result, "Container not created"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + } + + public void testCreateContainer_ContainerAlreadyExists() { + boolean result; + + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + result = storageStrategy.createContainer(CONTAINER_NAME); + assertTrue(result, "Container not created"); + result = storageStrategy.createContainer(CONTAINER_NAME); + assertFalse(result, "Container not created"); + } + + public void testDeleteDirectory() throws IOException { + TestUtils.createContainerAsDirectory(CONTAINER_NAME); + TestUtils.createBlobsInContainer( + CONTAINER_NAME, + new String[] { TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev3" + FS, ".txt"), + TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev4" + FS, ".jpg") }); + + // delete directory in different ways + storageStrategy.deleteDirectory(CONTAINER_NAME, "lev1" + FS + "lev2" + FS + "lev4"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2" + FS + "lev4", false); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2", true); + + storageStrategy.deleteDirectory(CONTAINER_NAME, "lev1" + FS + "lev2" + FS + "lev3" + FS); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2" + FS + "lev3", false); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1" + FS + "lev2", true); + + storageStrategy.deleteDirectory(CONTAINER_NAME, FS + "lev1"); + TestUtils.directoryExists(TARGET_CONTAINER_NAME + FS + "lev1", false); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + + // delete the directory and all the files inside + TestUtils.createBlobsInContainer( + CONTAINER_NAME, + new String[] { TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev3" + FS, ".txt"), + TestUtils.createRandomBlobKey("lev1" + FS + "lev2" + FS + "lev4" + FS, ".jpg") }); + storageStrategy.deleteDirectory(CONTAINER_NAME, null); + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + } + + public void testDeleteDirectory_ErrorWhenNotExists() { + try { + storageStrategy.deleteDirectory(CONTAINER_NAME, null); + fail("No exception throwed"); + } catch (Exception e) { + } + } + + public void testDirectoryExists() throws IOException { + final String SUBDIRECTORY_NAME = "ad" + FS + "sda" + FS + "asd"; + boolean result; + + result = storageStrategy.directoryExists(CONTAINER_NAME, null); + assertFalse(result, "Directory exist"); + + // create the container + TestUtils.createContainerAsDirectory(CONTAINER_NAME); + // check if exists + result = storageStrategy.directoryExists(CONTAINER_NAME, null); + assertTrue(result, "Directory doesn't exist"); + result = storageStrategy.directoryExists(CONTAINER_NAME + FS, null); + assertTrue(result, "Directory doesn't exist"); + + result = storageStrategy.directoryExists(CONTAINER_NAME, SUBDIRECTORY_NAME); + assertFalse(result, "Directory exist"); + + // create subdirs inside the container + TestUtils.createContainerAsDirectory(CONTAINER_NAME + FS + SUBDIRECTORY_NAME); + // check if exists + result = storageStrategy.directoryExists(CONTAINER_NAME, SUBDIRECTORY_NAME); + assertTrue(result, "Directory doesn't exist"); + result = storageStrategy.directoryExists(CONTAINER_NAME, FS + SUBDIRECTORY_NAME); + assertTrue(result, "Directory doesn't exist"); + result = storageStrategy.directoryExists(CONTAINER_NAME, SUBDIRECTORY_NAME + FS); + assertTrue(result, "Directory doesn't exist"); + result = storageStrategy.directoryExists(CONTAINER_NAME + FS, FS + SUBDIRECTORY_NAME); + assertTrue(result, "Directory doesn't exist"); + + } + + public void testClearContainer() throws IOException { + storageStrategy.createContainer(CONTAINER_NAME); + Set blobs = TestUtils.createBlobsInContainer( + CONTAINER_NAME, + new String[] { TestUtils.createRandomBlobKey("clean_container-", ".jpg"), + TestUtils.createRandomBlobKey("bf" + FS + "sd" + FS + "as" + FS + "clean_container-", ".jpg") }); + // test if file exits + for (String blob : blobs) { + TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, true); + } + + // clear the container + storageStrategy.clearContainer(CONTAINER_NAME); + // test if container still exits + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + // test if file was cleared + for (String blob : blobs) { + TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, false); + } + } + + public void testClearContainer_NotExistingContainer() throws IOException { + // test if container still exits + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + // clear the container + storageStrategy.clearContainer(CONTAINER_NAME); + // test if container still exits + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + } + + public void testClearContainerAndThenDeleteContainer() throws IOException { + storageStrategy.createContainer(CONTAINER_NAME); + Set blobs = TestUtils.createBlobsInContainer( + CONTAINER_NAME, + new String[] { TestUtils.createRandomBlobKey("clean_container-", ".jpg"), + TestUtils.createRandomBlobKey("bf" + FS + "sd" + FS + "as" + FS + "clean_container-", ".jpg") }); + // test if file exits + for (String blob : blobs) { + TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, true); + } + + // clear the container + storageStrategy.clearContainer(CONTAINER_NAME); + // test if container still exits + TestUtils.directoryExists(TARGET_CONTAINER_NAME, true); + // test if file was cleared + for (String blob : blobs) { + TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + blob, false); + } + + // delete the container + storageStrategy.deleteContainer(CONTAINER_NAME); + // test if container still exits + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + assertFalse(storageStrategy.containerExists(CONTAINER_NAME), "Container still exists"); + } + + public void testDeleteContainer() throws IOException { + final String BLOB_KEY1 = "blobName.jpg"; + final String BLOB_KEY2 = "aa" + FS + "bb" + FS + "cc" + FS + "dd" + FS + "ee" + FS + "ff" + FS + "23" + FS + + "blobName.jpg"; + boolean result; + + result = storageStrategy.createContainer(CONTAINER_NAME); + + // put data inside the container + TestUtils.createBlobsInContainer(CONTAINER_NAME, new String[] { BLOB_KEY1, BLOB_KEY2 }); + + storageStrategy.deleteContainer(CONTAINER_NAME); + assertTrue(result, "Cannot delete container"); + TestUtils.directoryExists(CONTAINER_NAME, false); + } + + public void testDeleteContainer_EmptyContainer() { + boolean result; + + result = storageStrategy.createContainer(CONTAINER_NAME); + assertTrue(result, "Cannot create container"); + + storageStrategy.deleteContainer(CONTAINER_NAME); + TestUtils.directoryExists(CONTAINER_NAME, false); + } + + public void testDeleteContainer_ErrorWhenNotExists() { + try { + storageStrategy.deleteContainer(CONTAINER_NAME); + fail("Exception not throwed"); + } catch (Exception e) { + } + } + + public void testGetAllContainerNames() { + Iterable resultList; + + // no container + resultList = storageStrategy.getAllContainerNames(); + assertNotNull(resultList, "Result is null"); + assertFalse(resultList.iterator().hasNext(), "Containers detected"); + + // create containers + storageStrategy.createContainer(CONTAINER_NAME + "1"); + storageStrategy.createContainer(CONTAINER_NAME + "2"); + storageStrategy.createContainer(CONTAINER_NAME + "3"); + + List containers = new ArrayList(); + resultList = storageStrategy.getAllContainerNames(); + Iterator containersIterator = resultList.iterator(); + while (containersIterator.hasNext()) { + containers.add(containersIterator.next()); + } + assertEquals(containers.size(), 3, "Different containers number"); + assertTrue(containers.contains(CONTAINER_NAME + "1"), "Containers doesn't exist"); + assertTrue(containers.contains(CONTAINER_NAME + "2"), "Containers doesn't exist"); + assertTrue(containers.contains(CONTAINER_NAME + "3"), "Containers doesn't exist"); + } + + public void testContainerExists() { + boolean result; + + TestUtils.directoryExists(TARGET_CONTAINER_NAME, false); + result = storageStrategy.containerExists(CONTAINER_NAME); + assertFalse(result, "Container exists"); + storageStrategy.createContainer(CONTAINER_NAME); + result = storageStrategy.containerExists(CONTAINER_NAME); + assertTrue(result, "Container exists"); + } + + public void testNewBlob() { + String blobKey; + Blob newBlob; + + blobKey = TestUtils.createRandomBlobKey("blobtest-", ".txt"); + newBlob = storageStrategy.newBlob(blobKey); + assertNotNull(newBlob, "Created blob was null"); + assertNotNull(newBlob.getMetadata(), "Created blob metadata were null"); + assertEquals(newBlob.getMetadata().getName(), blobKey, "Created blob name is different"); + + blobKey = TestUtils.createRandomBlobKey("blobtest-", ""); + newBlob = storageStrategy.newBlob(blobKey); + assertEquals(newBlob.getMetadata().getName(), blobKey, "Created blob name is different"); + + blobKey = TestUtils.createRandomBlobKey("asd" + FS + "asd" + FS + "asdasd" + FS + "afadsf-", ""); + newBlob = storageStrategy.newBlob(blobKey); + assertEquals(newBlob.getMetadata().getName(), blobKey, "Created blob name is different"); + } + + public void testWritePayloadOnFile() throws IOException { + String blobKey; + File sourceFile; + FilePayload filePayload; + + blobKey = TestUtils.createRandomBlobKey("writePayload-", ".img"); + sourceFile = TestUtils.getImageForBlobPayload(); + filePayload = new FilePayload(sourceFile); + // write files + storageStrategy.writePayloadOnFile(CONTAINER_NAME, blobKey, filePayload); + // verify that the files is equal + String blobFullPath = TARGET_CONTAINER_NAME + FS + blobKey; + InputStream expectedInput = new FileInputStream(sourceFile); + InputStream currentInput = new FileInputStream(blobFullPath); + assertTrue(TestUtils.isSame(expectedInput, currentInput), "Files aren't equals"); + } + + public void testWritePayloadOnFile_SourceFileDoesntExist() { + File sourceFile = new File("asdfkjsadkfjasdlfasdflk.asdfasdfas"); + try { + new FilePayload(sourceFile); + fail("Exception not throwed"); + } catch (Exception ex) { + } + } + + public void testGetFileForBlobKey() { + String blobKey; + File fileForPayload; + String fullPath = (new File(TARGET_CONTAINER_NAME).getAbsolutePath()) + FS; + + blobKey = TestUtils.createRandomBlobKey("getFileForBlobKey-", ".img"); + fileForPayload = storageStrategy.getFileForBlobKey(CONTAINER_NAME, blobKey); + assertNotNull(fileForPayload, "Result File object is null"); + assertEquals(fileForPayload.getAbsolutePath(), fullPath + blobKey, "Wrong file path"); + + blobKey = TestUtils.createRandomBlobKey("asd" + FS + "vmad" + FS + "andsnf" + FS + "getFileForBlobKey-", ".img"); + fileForPayload = storageStrategy.getFileForBlobKey(CONTAINER_NAME, blobKey); + assertEquals(fileForPayload.getAbsolutePath(), fullPath + blobKey, "Wrong file path"); + } + + 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 Provider() { + @Override + public BlobBuilder get() { + return new BlobBuilderImpl(); + } + }, 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 { + String[] sourceBlobKeys = new String[] { TestUtils.createRandomBlobKey("blobExists-", ".jpg"), TestUtils.createRandomBlobKey("blobExists-", ".jpg"), - TestUtils.createRandomBlobKey("blobExists-", ".jpg"), - TestUtils.createRandomBlobKey("afasd" + FS + "asdma" + FS + "blobExists-", ".jpg") - }; + TestUtils.createRandomBlobKey("afasd" + FS + "asdma" + FS + "blobExists-", ".jpg") }; - for(String blobKey:sourceBlobKeys) { - assertFalse(storageStrategy.blobExists(CONTAINER_NAME, blobKey), "Blob " + blobKey + " exists"); - } - TestUtils.createBlobsInContainer(CONTAINER_NAME, sourceBlobKeys); - for(String blobKey:sourceBlobKeys) { - assertTrue(storageStrategy.blobExists(CONTAINER_NAME, blobKey), "Blob " + blobKey + " doesn't exist"); - } - } + for (String blobKey : sourceBlobKeys) { + assertFalse(storageStrategy.blobExists(CONTAINER_NAME, blobKey), "Blob " + blobKey + " exists"); + } + TestUtils.createBlobsInContainer(CONTAINER_NAME, sourceBlobKeys); + for (String blobKey : sourceBlobKeys) { + assertTrue(storageStrategy.blobExists(CONTAINER_NAME, blobKey), "Blob " + blobKey + " doesn't exist"); + } + } + public void testRemoveBlob() throws IOException { + storageStrategy.createContainer(CONTAINER_NAME); + Set blobKeys = TestUtils.createBlobsInContainer( + CONTAINER_NAME, + new String[] { TestUtils.createRandomBlobKey("removeBlob-", ".jpg"), + TestUtils.createRandomBlobKey("removeBlob-", ".jpg"), + TestUtils.createRandomBlobKey("346" + FS + "g3sx2" + FS + "removeBlob-", ".jpg"), + TestUtils.createRandomBlobKey("346" + FS + "g3sx2" + FS + "removeBlob-", ".jpg") }); - public void testRemoveBlob() throws IOException { - storageStrategy.createContainer(CONTAINER_NAME); - Set blobKeys = TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("removeBlob-", ".jpg"), - TestUtils.createRandomBlobKey("removeBlob-", ".jpg"), - TestUtils.createRandomBlobKey("346" + FS + "g3sx2" + FS + "removeBlob-", ".jpg"), - TestUtils.createRandomBlobKey("346" + FS + "g3sx2" + FS + "removeBlob-", ".jpg") - }); + Set remainingBlobKeys = new HashSet(); + for (String key : blobKeys) { + remainingBlobKeys.add(key); + } + for (String blobKeyToRemove : blobKeys) { + storageStrategy.removeBlob(CONTAINER_NAME, blobKeyToRemove); + // checks if the blob was removed + TestUtils.fileExists(blobKeyToRemove, false); + remainingBlobKeys.remove(blobKeyToRemove); + // checks if all other blobs still exists + for (String remainingBlobKey : remainingBlobKeys) { + TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + remainingBlobKey, true); + } + } + } - Set remainingBlobKeys = new HashSet(); - for(String key:blobKeys) { - remainingBlobKeys.add(key); - } - for (String blobKeyToRemove:blobKeys) { - storageStrategy.removeBlob(CONTAINER_NAME, blobKeyToRemove); - //checks if the blob was removed - TestUtils.fileExists(blobKeyToRemove, false); - remainingBlobKeys.remove(blobKeyToRemove); - //checks if all other blobs still exists - for(String remainingBlobKey:remainingBlobKeys) { - TestUtils.fileExists(TARGET_CONTAINER_NAME + FS + remainingBlobKey, true); - } - } - } + public void testRemoveBlob_ContainerNotExists() { + storageStrategy.removeBlob("asdasdasd", "sdfsdfsdfasd"); + } - public void testRemoveBlob_ContainerNotExists() { - storageStrategy.removeBlob("asdasdasd", "sdfsdfsdfasd"); - } + public void testRemoveBlob_BlobNotExists() { + storageStrategy.createContainer(CONTAINER_NAME); + storageStrategy.removeBlob(CONTAINER_NAME, "sdfsdfsdfasd"); + } - public void testRemoveBlob_BlobNotExists() { - storageStrategy.createContainer(CONTAINER_NAME); - storageStrategy.removeBlob(CONTAINER_NAME, "sdfsdfsdfasd"); - } + public void testGetBlobKeysInsideContainer() throws IOException { + Iterable resultList; + // no container + resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME); + assertNotNull(resultList, "Result is null"); + assertFalse(resultList.iterator().hasNext(), "Blobs detected"); - public void testGetBlobKeysInsideContainer() throws IOException { - Iterable resultList; + // create blobs + storageStrategy.createContainer(CONTAINER_NAME); + Set createBlobKeys = TestUtils.createBlobsInContainer( + CONTAINER_NAME, + new String[] { TestUtils.createRandomBlobKey("GetBlobKeys-", ".jpg"), + TestUtils.createRandomBlobKey("GetBlobKeys-", ".jpg"), + TestUtils.createRandomBlobKey("563" + FS + "g3sx2" + FS + "removeBlob-", ".jpg"), + TestUtils.createRandomBlobKey("563" + FS + "g3sx2" + FS + "removeBlob-", ".jpg") }); + storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME); - //no container - resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME); - assertNotNull(resultList, "Result is null"); - assertFalse(resultList.iterator().hasNext(), "Blobs detected"); + List retrievedBlobKeys = new ArrayList(); + resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME); + Iterator containersIterator = resultList.iterator(); + while (containersIterator.hasNext()) { + retrievedBlobKeys.add(containersIterator.next()); + } + assertEquals(retrievedBlobKeys.size(), createBlobKeys.size(), "Different blobs number"); + for (String createdBlobKey : createBlobKeys) { + assertTrue(retrievedBlobKeys.contains(createdBlobKey), "Blob " + createdBlobKey + " not found"); + } + } - //create blobs - storageStrategy.createContainer(CONTAINER_NAME); - Set createBlobKeys = TestUtils.createBlobsInContainer( - CONTAINER_NAME, - new String[]{ - TestUtils.createRandomBlobKey("GetBlobKeys-", ".jpg"), - TestUtils.createRandomBlobKey("GetBlobKeys-", ".jpg"), - TestUtils.createRandomBlobKey("563" + FS + "g3sx2" + FS + "removeBlob-", ".jpg"), - TestUtils.createRandomBlobKey("563" + FS + "g3sx2" + FS + "removeBlob-", ".jpg") - }); - storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME); + public void testCountsBlob() { + try { + storageStrategy.countBlobs(CONTAINER_NAME, ListContainerOptions.NONE); + fail("Magically the method was implemented... Wow!"); + } catch (UnsupportedOperationException e) { + } + } - List retrievedBlobKeys = new ArrayList(); - resultList = storageStrategy.getBlobKeysInsideContainer(CONTAINER_NAME); - Iterator containersIterator = resultList.iterator(); - while(containersIterator.hasNext()){ - retrievedBlobKeys.add(containersIterator.next()); - } - assertEquals(retrievedBlobKeys.size(), createBlobKeys.size(), "Different blobs number"); - for(String createdBlobKey:createBlobKeys) { - assertTrue(retrievedBlobKeys.contains(createdBlobKey), "Blob " + createdBlobKey + " not found"); - } - } + public void testInvalidBlobKey() { + try { + storageStrategy.newBlob(FS + "test.jpg"); + fail("Wrong blob key not recognized"); + } catch (IllegalArgumentException e) { + } + } + public void testInvalidContainerName() { + try { + storageStrategy.createContainer("file" + FS + "system"); + fail("Wrong container name not recognized"); + } catch (IllegalArgumentException e) { + } + } - public void testCountsBlob() { - try { - storageStrategy.countBlobs(CONTAINER_NAME, ListContainerOptions.NONE); - fail("Magically the method was implemented... Wow!"); - } catch (UnsupportedOperationException e) { - } - } + // ---------------------------------------------------------- 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(); - public void testInvalidBlobKey() { - try { - storageStrategy.newBlob(FS + "test.jpg"); - fail("Wrong blob key not recognized"); - } catch (IllegalArgumentException e) {} - } - - public void testInvalidContainerName() { - try { - storageStrategy.createContainer("file" + FS + "system"); - fail("Wrong container name not recognized"); - } catch (IllegalArgumentException e) {} - } - - //---------------------------------------------------------- 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; - } - + return tempAbsolutePath; + } } diff --git a/apis/pom.xml b/apis/pom.xml index 2b0319f2f8..37c7bfae37 100644 --- a/apis/pom.xml +++ b/apis/pom.xml @@ -34,9 +34,9 @@ jclouds apis project filesystem + byon s3 ec2 - elb walrus eucalyptus swift diff --git a/apis/s3/README.txt b/apis/s3/README.txt new file mode 100644 index 0000000000..7254aefa1d --- /dev/null +++ b/apis/s3/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds API for Amazon's S3 (http://aws.amazon.com/s3/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3ContextBuilder.java b/apis/s3/src/main/java/org/jclouds/s3/S3ContextBuilder.java index 40a7126146..ed1135bb4c 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3ContextBuilder.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3ContextBuilder.java @@ -57,6 +57,6 @@ public class S3ContextBuilder extends BlobStoreContextBuilder modules) { - modules.add(new S3RestClientModule()); + modules.add(S3RestClientModule.create()); } } diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java b/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java index 374c48ea47..2f94673283 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java @@ -20,7 +20,6 @@ package org.jclouds.s3; import static org.jclouds.Constants.PROPERTY_API_VERSION; -import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_RELAX_HOSTNAME; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG; import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; @@ -49,7 +48,6 @@ public class S3PropertiesBuilder extends PropertiesBuilder { properties.setProperty(PROPERTY_S3_SERVICE_PATH, "/"); properties.setProperty(PROPERTY_S3_VIRTUAL_HOST_BUCKETS, "true"); properties.setProperty(PROPERTY_RELAX_HOSTNAME, "true"); - properties.setProperty(PROPERTY_ENDPOINT, "https://s3.amazonaws.com"); properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX, DIRECTORY_SUFFIX_FOLDER); return properties; } diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java index 85afa1b678..815d2e5ff6 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/config/S3BlobStoreContextModule.java @@ -19,17 +19,6 @@ package org.jclouds.s3.blobstore.config; -import java.util.Set; - -import javax.inject.Singleton; - -import org.jclouds.s3.S3AsyncClient; -import org.jclouds.s3.S3Client; -import org.jclouds.s3.blobstore.S3AsyncBlobStore; -import org.jclouds.s3.blobstore.S3BlobRequestSigner; -import org.jclouds.s3.blobstore.S3BlobStore; -import org.jclouds.s3.blobstore.functions.LocationFromBucketLocation; -import org.jclouds.s3.domain.BucketMetadata; import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobRequestSigner; import org.jclouds.blobstore.BlobStore; @@ -37,20 +26,18 @@ import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.config.BlobStoreMapModule; import org.jclouds.blobstore.internal.BlobStoreContextImpl; -import org.jclouds.collect.Memoized; import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.location.Provider; -import org.jclouds.location.Region; -import org.jclouds.location.suppliers.OnlyLocationOrFirstZoneOrRegionMatchingRegionId; +import org.jclouds.location.config.RegionsLocationModule; +import org.jclouds.s3.S3AsyncClient; +import org.jclouds.s3.S3Client; +import org.jclouds.s3.blobstore.S3AsyncBlobStore; +import org.jclouds.s3.blobstore.S3BlobRequestSigner; +import org.jclouds.s3.blobstore.S3BlobStore; +import org.jclouds.s3.blobstore.functions.LocationFromBucketLocation; +import org.jclouds.s3.domain.BucketMetadata; import com.google.common.base.Function; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.collect.Sets; import com.google.inject.AbstractModule; -import com.google.inject.Provides; import com.google.inject.Scopes; import com.google.inject.TypeLiteral; @@ -64,9 +51,7 @@ public class S3BlobStoreContextModule extends AbstractModule { @Override protected void configure() { install(new BlobStoreMapModule()); - bind(new TypeLiteral>() { - }).to(new TypeLiteral() { - }); + install(new RegionsLocationModule()); bind(ConsistencyModel.class).toInstance(ConsistencyModel.EVENTUAL); bind(AsyncBlobStore.class).to(S3AsyncBlobStore.class).in(Scopes.SINGLETON); bind(BlobStore.class).to(S3BlobStore.class).in(Scopes.SINGLETON); @@ -81,15 +66,5 @@ public class S3BlobStoreContextModule extends AbstractModule { }).to(LocationFromBucketLocation.class); } - @Provides - @Singleton - @Memoized - Supplier> provideLocations(@Region Set regions, @Provider String providerName) { - Set locations = Sets.newHashSet(); - Location s3 = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); - for (String zone : regions) { - locations.add(new LocationImpl(LocationScope.REGION, zone.toString(), zone.toString(), s3)); - } - return Suppliers.> ofInstance(locations); - } + } diff --git a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlob.java b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlob.java index 98302b56af..158e387a3a 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlob.java +++ b/apis/s3/src/main/java/org/jclouds/s3/blobstore/functions/ObjectToBlob.java @@ -35,7 +35,7 @@ import com.google.common.base.Function; */ @Singleton public class ObjectToBlob implements Function { - private final Blob.Factory blobFactory; + private final Factory blobFactory; private final ObjectToBlobMetadata object2BlobMd; @Inject diff --git a/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java b/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java index e1615ac10c..6a582368d6 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java +++ b/apis/s3/src/main/java/org/jclouds/s3/config/S3RestClientModule.java @@ -52,9 +52,13 @@ import com.google.inject.Scopes; */ @ConfiguresRestClient @RequiresHttp -public class S3RestClientModule extends AWSRestClientModule { - public S3RestClientModule() { - super(S3Client.class, S3AsyncClient.class); +public class S3RestClientModule extends AWSRestClientModule { + public static S3RestClientModule create() { + return new S3RestClientModule(S3Client.class, S3AsyncClient.class); + } + + public S3RestClientModule(Class sync, Class async) { + super(sync, async); } @Override @@ -91,7 +95,7 @@ public class S3RestClientModule extends AWSRestClientModule provideTimeStampCache(@Named(Constants.PROPERTY_SESSION_INTERVAL) long seconds, - final DateService dateService) { + final DateService dateService) { return Suppliers.memoizeWithExpiration(new Supplier() { public String get() { return dateService.rfc822DateFormat(); diff --git a/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java b/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java index b35b1711e6..285d50236c 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java +++ b/apis/s3/src/main/java/org/jclouds/s3/domain/AccessControlList.java @@ -19,6 +19,7 @@ package org.jclouds.s3.domain; +import java.net.URI; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -35,8 +36,8 @@ import com.google.common.collect.Collections2; * An Access Control List (ACL) describes the access control settings for a bucket or object in S3. * * ACL settings comprise a set of {@link Grant}s, each of which specifies a {@link Permission} that - * has been granted to a specific {@link Grantee}. If an payload tries to access or modify an item in - * S3, the operation will be denied unless the item has ACL settings that explicitly permit that + * has been granted to a specific {@link Grantee}. If an payload tries to access or modify an item + * in S3, the operation will be denied unless the item has ACL settings that explicitly permit that * payload to perform that action. * * @@ -80,7 +81,7 @@ public class AccessControlList { * @param grantee * @param permission */ - public AccessControlList addPermission(Grantee grantee, Permission permission) { + public AccessControlList addPermission(Grantee grantee, String permission) { Grant grant = new Grant(grantee, permission); grants.add(grant); return this; @@ -92,7 +93,7 @@ public class AccessControlList { * @param groupGranteeURI * @param permission */ - public AccessControlList addPermission(GroupGranteeURI groupGranteeURI, Permission permission) { + public AccessControlList addPermission(URI groupGranteeURI, String permission) { return addPermission(new GroupGrantee(groupGranteeURI), permission); } @@ -110,7 +111,7 @@ public class AccessControlList { * @param grantee * @param permission */ - public AccessControlList revokePermission(Grantee grantee, Permission permission) { + public AccessControlList revokePermission(Grantee grantee, String permission) { Collection grantsForGrantee = findGrantsForGrantee(grantee.getIdentifier()); for (Grant grant : grantsForGrantee) { if (grant.getPermission().equals(permission)) { @@ -134,7 +135,7 @@ public class AccessControlList { * @param groupGranteeURI * @param permission */ - public AccessControlList revokePermission(GroupGranteeURI groupGranteeURI, Permission permission) { + public AccessControlList revokePermission(URI groupGranteeURI, String permission) { return revokePermission(new GroupGrantee(groupGranteeURI), permission); } @@ -153,10 +154,10 @@ public class AccessControlList { * @param granteeId * @return the permissions assigned to a grantee, as identified by the given ID. */ - public Collection getPermissions(String granteeId) { + public Collection getPermissions(String granteeId) { Collection grantsForGrantee = findGrantsForGrantee(granteeId); - return Collections2.transform(grantsForGrantee, new Function() { - public Permission apply(Grant g) { + return Collections2.transform(grantsForGrantee, new Function() { + public String apply(Grant g) { return g.getPermission(); } }); @@ -166,7 +167,7 @@ public class AccessControlList { * @param grantee * @return the permissions assigned to a grantee. */ - public Collection getPermissions(Grantee grantee) { + public Collection getPermissions(Grantee grantee) { return getPermissions(grantee.getIdentifier()); } @@ -174,8 +175,8 @@ public class AccessControlList { * @param granteeURI * @return the permissions assigned to a group grantee. */ - public Collection getPermissions(GroupGranteeURI granteeURI) { - return getPermissions(granteeURI.getIdentifier()); + public Collection getPermissions(URI granteeURI) { + return getPermissions(granteeURI.toASCIIString()); } /** @@ -183,7 +184,7 @@ public class AccessControlList { * @param permission * @return true if the grantee has the given permission. */ - public boolean hasPermission(String granteeId, Permission permission) { + public boolean hasPermission(String granteeId, String permission) { return getPermissions(granteeId).contains(permission); } @@ -192,7 +193,7 @@ public class AccessControlList { * @param permission * @return true if the grantee has the given permission. */ - public boolean hasPermission(Grantee grantee, Permission permission) { + public boolean hasPermission(Grantee grantee, String permission) { return hasPermission(grantee.getIdentifier(), permission); } @@ -201,8 +202,8 @@ public class AccessControlList { * @param permission * @return true if the grantee has the given permission. */ - public boolean hasPermission(GroupGranteeURI granteeURI, Permission permission) { - return getPermissions(granteeURI.getIdentifier()).contains(permission); + public boolean hasPermission(URI granteeURI, String permission) { + return getPermissions(granteeURI).contains(permission); } /** @@ -226,8 +227,7 @@ public class AccessControlList { * @param cannedAP * @param ownerId */ - public static AccessControlList fromCannedAccessPolicy(CannedAccessPolicy cannedAP, - String ownerId) { + public static AccessControlList fromCannedAccessPolicy(CannedAccessPolicy cannedAP, String ownerId) { AccessControlList acl = new AccessControlList(); acl.setOwner(new CanonicalUser(ownerId)); @@ -251,16 +251,20 @@ public class AccessControlList { // Class and Enum declarations to represent Grants, Grantees and Permissions // // ///////////////////////////////////////////////////////////////////////////// - public static enum Permission { - READ, WRITE, READ_ACP, WRITE_ACP, FULL_CONTROL; + public static interface Permission { + public static final String READ = "READ"; + public static final String WRITE = "WRITE"; + public static final String READ_ACP = "READ_ACP"; + public static final String WRITE_ACP = "WRITE_ACP"; + public static final String FULL_CONTROL = "FULL_CONTROL"; }; public static class Grant implements Comparable { private Grantee grantee; - private final Permission permission; + private final String permission; - public Grant(Grantee grantee, Permission permission) { + public Grant(Grantee grantee, String permission) { this.grantee = grantee; this.permission = permission; } @@ -274,7 +278,7 @@ public class AccessControlList { this.grantee = grantee; } - public Permission getPermission() { + public String getPermission() { return permission; } @@ -417,38 +421,17 @@ public class AccessControlList { } } - public enum GroupGranteeURI { - ALL_USERS("http://acs.amazonaws.com/groups/global/AllUsers"), AUTHENTICATED_USERS( - "http://acs.amazonaws.com/groups/global/AuthenticatedUsers"), LOG_DELIVERY( - "http://acs.amazonaws.com/groups/LogDelivery"); - - private final String uri; - - GroupGranteeURI(String uri) { - this.uri = uri; - } - - public String getIdentifier() { - return this.uri; - } - - public static GroupGranteeURI fromURI(String uri) { - if (ALL_USERS.uri.equals(uri)) { - return ALL_USERS; - } else if (AUTHENTICATED_USERS.uri.equals(uri)) { - return AUTHENTICATED_USERS; - } else if (LOG_DELIVERY.uri.equals(uri)) { - return LOG_DELIVERY; - } else { - throw new IllegalArgumentException("No GroupGranteeURI constant matches " + uri); - } - } + public interface GroupGranteeURI { + public static final URI ALL_USERS = URI.create("http://acs.amazonaws.com/groups/global/AllUsers"); + public static final URI AUTHENTICATED_USERS = URI + .create("http://acs.amazonaws.com/groups/global/AuthenticatedUsers"); + public static final URI LOG_DELIVERY = URI.create("http://acs.amazonaws.com/groups/LogDelivery"); } public static class GroupGrantee extends Grantee { - public GroupGrantee(GroupGranteeURI groupURI) { - super(groupURI.getIdentifier()); + public GroupGrantee(URI groupURI) { + super(groupURI.toASCIIString()); } } diff --git a/apis/s3/src/main/java/org/jclouds/s3/domain/internal/ListBucketResponseImpl.java b/apis/s3/src/main/java/org/jclouds/s3/domain/internal/ListBucketResponseImpl.java index fc301db1f0..3cac79fc34 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/domain/internal/ListBucketResponseImpl.java +++ b/apis/s3/src/main/java/org/jclouds/s3/domain/internal/ListBucketResponseImpl.java @@ -19,7 +19,7 @@ package org.jclouds.s3.domain.internal; -import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.Set; import org.jclouds.s3.domain.ListBucketResponse; @@ -32,8 +32,7 @@ import com.google.common.collect.Iterables; * @author Adrian Cole * */ -public class ListBucketResponseImpl extends HashSet implements - ListBucketResponse { +public class ListBucketResponseImpl extends LinkedHashSet implements ListBucketResponse { /** The serialVersionUID */ private static final long serialVersionUID = -4475709781001190244L; protected final String name; @@ -45,9 +44,8 @@ public class ListBucketResponseImpl extends HashSet implements protected final Set commonPrefixes; protected final boolean truncated; - public ListBucketResponseImpl(String name, Iterable contents, String prefix, - String marker, String nextMarker, int maxKeys, String delimiter, boolean isTruncated, - Set commonPrefixes) { + public ListBucketResponseImpl(String name, Iterable contents, String prefix, String marker, + String nextMarker, int maxKeys, String delimiter, boolean isTruncated, Set commonPrefixes) { Iterables.addAll(this, contents); this.name = name; this.prefix = prefix; diff --git a/apis/s3/src/main/java/org/jclouds/s3/functions/BindRegionToXmlPayload.java b/apis/s3/src/main/java/org/jclouds/s3/functions/BindRegionToXmlPayload.java index 2936113903..1af55cd906 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/functions/BindRegionToXmlPayload.java +++ b/apis/s3/src/main/java/org/jclouds/s3/functions/BindRegionToXmlPayload.java @@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkArgument; import java.util.Set; +import javax.annotation.Nullable; import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Singleton; @@ -49,14 +50,16 @@ public class BindRegionToXmlPayload extends BindToStringPayload { private final Set regions; @Inject - BindRegionToXmlPayload(@org.jclouds.location.Region String defaultRegion, - @org.jclouds.location.Region Set regions) { + BindRegionToXmlPayload(@org.jclouds.location.Region @Nullable String defaultRegion, + @org.jclouds.location.Region Set regions) { this.defaultRegion = defaultRegion; this.regions = regions; } @Override public R bindToRequest(R request, Object input) { + if (defaultRegion == null) + return request; input = input == null ? defaultRegion : input; checkArgument(input instanceof String, "this binder is only valid for Region!"); String constraint = (String) input; @@ -70,10 +73,9 @@ public class BindRegionToXmlPayload extends BindToStringPayload { logger.warn("region %s not in %s ", constraint, regions); value = constraint; } - String payload = String - .format( - "%s", - value); + String payload = String.format( + "%s", + value); request = super.bindToRequest(request, payload); request.getPayload().getContentMetadata().setContentType(MediaType.TEXT_XML); return request; diff --git a/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java b/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java index 58fa59666c..a2ac6396f8 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java +++ b/apis/s3/src/main/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContent.java @@ -19,7 +19,17 @@ package org.jclouds.s3.handlers; +import static com.google.common.base.Predicates.equalTo; +import static com.google.common.base.Predicates.not; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Lists.newArrayList; +import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH; +import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS; + +import java.util.List; + import javax.inject.Inject; +import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.aws.domain.AWSError; @@ -31,6 +41,9 @@ import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpResponse; import org.jclouds.rest.ResourceNotFoundException; +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; + /** * @author Adrian Cole * @@ -38,27 +51,43 @@ import org.jclouds.rest.ResourceNotFoundException; @Singleton public class ParseS3ErrorFromXmlContent extends ParseAWSErrorFromXmlContent { + private final String servicePath; + private final boolean isVhostStyle; + @Inject - ParseS3ErrorFromXmlContent(AWSUtils utils) { + ParseS3ErrorFromXmlContent(AWSUtils utils, @Named(PROPERTY_S3_VIRTUAL_HOST_BUCKETS) boolean isVhostStyle, + @Named(PROPERTY_S3_SERVICE_PATH) String servicePath) { super(utils); + this.servicePath = servicePath; + this.isVhostStyle = isVhostStyle; } protected Exception refineException(HttpCommand command, HttpResponse response, Exception exception, AWSError error, - String message) { + String message) { switch (response.getStatusCode()) { - case 404: - if (!command.getCurrentRequest().getMethod().equals("DELETE")) { - exception = new ResourceNotFoundException(message, exception); - String container = command.getCurrentRequest().getEndpoint().getHost(); - String key = command.getCurrentRequest().getEndpoint().getPath(); - if (key == null || key.equals("/")) - exception = new ContainerNotFoundException(container, message); - else - exception = new KeyNotFoundException(container, key, message); - } - return exception; - default: - return super.refineException(command, response, exception, error, message); + case 404: + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { + exception = new ResourceNotFoundException(message, exception); + if (isVhostStyle) { + String container = command.getCurrentRequest().getEndpoint().getHost(); + String key = command.getCurrentRequest().getEndpoint().getPath(); + if (key == null || key.equals("/")) + exception = new ContainerNotFoundException(container, message); + else + exception = new KeyNotFoundException(container, key, message); + } else if (command.getCurrentRequest().getEndpoint().getPath().indexOf(servicePath + "/") == 0) { + String path = command.getCurrentRequest().getEndpoint().getPath().substring(servicePath.length()); + List parts = newArrayList(filter(Splitter.on('/').split(path), not(equalTo("")))); + if (parts.size() == 1) { + exception = new ContainerNotFoundException(parts.get(0), message); + } else if (parts.size() > 1) { + exception = new KeyNotFoundException(parts.remove(0), Joiner.on('/').join(parts), message); + } + } + } + return exception; + default: + return super.refineException(command, response, exception, error, message); } } } \ No newline at end of file diff --git a/apis/s3/src/main/java/org/jclouds/s3/options/CopyObjectOptions.java b/apis/s3/src/main/java/org/jclouds/s3/options/CopyObjectOptions.java index 5b3bb5606c..349b092ecb 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/options/CopyObjectOptions.java +++ b/apis/s3/src/main/java/org/jclouds/s3/options/CopyObjectOptions.java @@ -262,7 +262,7 @@ public class CopyObjectOptions extends BaseHttpRequestOptions { checkState(metadataPrefix != null, "metadataPrefix should have been injected!"); Multimap returnVal = LinkedHashMultimap.create(); for (Entry entry : headers.entries()) { - returnVal.put(entry.getKey().replace("aws", headerTag), entry.getValue()); + returnVal.put(entry.getKey().replace("amz", headerTag), entry.getValue()); } if (metadata != null) { for (String key : metadata.keySet()) { diff --git a/apis/s3/src/main/java/org/jclouds/s3/options/PutObjectOptions.java b/apis/s3/src/main/java/org/jclouds/s3/options/PutObjectOptions.java index adbbf7d777..e78396b74e 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/options/PutObjectOptions.java +++ b/apis/s3/src/main/java/org/jclouds/s3/options/PutObjectOptions.java @@ -73,7 +73,7 @@ public class PutObjectOptions extends BaseHttpRequestOptions { checkState(headerTag != null, "headerTag should have been injected!"); Multimap returnVal = LinkedHashMultimap.create(); for (Entry entry : headers.entries()) { - returnVal.put(entry.getKey().replace("aws", headerTag), entry.getValue()); + returnVal.put(entry.getKey().replace("amz", headerTag), entry.getValue()); } return returnVal; } diff --git a/apis/s3/src/main/java/org/jclouds/s3/xml/AccessControlListHandler.java b/apis/s3/src/main/java/org/jclouds/s3/xml/AccessControlListHandler.java index 16209ab7de..024b5d7f5c 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/xml/AccessControlListHandler.java +++ b/apis/s3/src/main/java/org/jclouds/s3/xml/AccessControlListHandler.java @@ -19,15 +19,15 @@ package org.jclouds.s3.xml; +import java.net.URI; + +import org.jclouds.http.functions.ParseSax; import org.jclouds.s3.domain.AccessControlList; import org.jclouds.s3.domain.CanonicalUser; import org.jclouds.s3.domain.AccessControlList.CanonicalUserGrantee; import org.jclouds.s3.domain.AccessControlList.EmailAddressGrantee; import org.jclouds.s3.domain.AccessControlList.Grantee; import org.jclouds.s3.domain.AccessControlList.GroupGrantee; -import org.jclouds.s3.domain.AccessControlList.GroupGranteeURI; -import org.jclouds.s3.domain.AccessControlList.Permission; -import org.jclouds.http.functions.ParseSax; import org.xml.sax.Attributes; /** @@ -72,18 +72,18 @@ public class AccessControlListHandler extends ParseSax.HandlerWithResult createContextSpec() { - return new RestContextFactory().createContextSpec(provider, "identity", "credential", new Properties()); + return new RestContextFactory(getProperties()).createContextSpec(provider, "identity", "credential", + new Properties()); } } diff --git a/apis/s3/src/test/java/org/jclouds/s3/ProvidersInPropertiesTest.java b/apis/s3/src/test/java/org/jclouds/s3/ProvidersInPropertiesTest.java deleted file mode 100644 index bfba916200..0000000000 --- a/apis/s3/src/test/java/org/jclouds/s3/ProvidersInPropertiesTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.s3; - -import org.jclouds.blobstore.util.BlobStoreUtils; -import org.jclouds.rest.Providers; -import org.testng.annotations.Test; - -import com.google.common.collect.Iterables; - -/** - * - * @author Adrian Cole - * - */ -@Test(groups = "unit") -public class ProvidersInPropertiesTest { - - @Test - public void testSupportedProviders() { - Iterable providers = Providers.getSupportedProviders(); - assert Iterables.contains(providers, "s3") : providers; - assert Iterables.contains(providers, "walrus") : providers; - assert Iterables.contains(providers, "googlestorage") : providers; - } - - @Test - public void testSupportedBlobStoreProviders() { - Iterable providers = BlobStoreUtils.getSupportedProviders(); - assert Iterables.contains(providers, "s3") : providers; - assert Iterables.contains(providers, "walrus") : providers; - assert Iterables.contains(providers, "googlestorage") : providers; - } - -} diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java index 0e2124d8f3..8e0c75475c 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/S3AsyncClientTest.java @@ -26,6 +26,22 @@ import java.lang.reflect.Array; import java.lang.reflect.Method; import org.jclouds.aws.domain.Region; +import org.jclouds.blobstore.binders.BindBlobToMultipartFormTest; +import org.jclouds.blobstore.functions.ReturnFalseOnContainerNotFound; +import org.jclouds.blobstore.functions.ReturnFalseOnKeyNotFound; +import org.jclouds.blobstore.functions.ReturnNullOnKeyNotFound; +import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404; +import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; +import org.jclouds.date.TimeStamp; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.RequiresHttp; +import org.jclouds.http.functions.ParseETagHeader; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReleasePayloadAndReturn; +import org.jclouds.http.functions.ReturnTrueIf2xx; +import org.jclouds.http.options.GetOptions; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.s3.config.S3RestClientModule; import org.jclouds.s3.domain.AccessControlList; import org.jclouds.s3.domain.BucketLogging; @@ -50,22 +66,6 @@ import org.jclouds.s3.xml.ListAllMyBucketsHandler; import org.jclouds.s3.xml.ListBucketHandler; import org.jclouds.s3.xml.LocationConstraintHandler; import org.jclouds.s3.xml.PayerHandler; -import org.jclouds.blobstore.binders.BindBlobToMultipartFormTest; -import org.jclouds.blobstore.functions.ReturnFalseOnContainerNotFound; -import org.jclouds.blobstore.functions.ReturnFalseOnKeyNotFound; -import org.jclouds.blobstore.functions.ReturnNullOnKeyNotFound; -import org.jclouds.blobstore.functions.ThrowContainerNotFoundOn404; -import org.jclouds.blobstore.functions.ThrowKeyNotFoundOn404; -import org.jclouds.date.TimeStamp; -import org.jclouds.http.HttpRequest; -import org.jclouds.http.RequiresHttp; -import org.jclouds.http.functions.ParseETagHeader; -import org.jclouds.http.functions.ParseSax; -import org.jclouds.http.functions.ReleasePayloadAndReturn; -import org.jclouds.http.functions.ReturnTrueIf2xx; -import org.jclouds.http.options.GetOptions; -import org.jclouds.rest.ConfiguresRestClient; -import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import org.jclouds.util.Strings2; import org.testng.annotations.Test; @@ -85,8 +85,8 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { protected String url = "s3.amazonaws.com"; public void testAllRegions() throws SecurityException, NoSuchMethodException, IOException { - Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class, String.class, - Array.newInstance(PutBucketOptions.class, 0).getClass()); + Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class, String.class, Array.newInstance( + PutBucketOptions.class, 0).getClass()); for (String region : Region.ALL_S3) { processor.createRequest(method, region, "bucket-name"); } @@ -104,8 +104,8 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { assertRequestLineEquals(request, "GET https://bucket." + url + "/?location HTTP/1.1"); assertNonPayloadHeadersEqual(request, - "Authorization: AWS identity:2fFTeYJTDwiJmaAkKj732RjNbOg=\nDate: 2009-11-08T15:54:08.897Z\nHost: bucket." - + url + "\n"); + "Authorization: AWS identity:2fFTeYJTDwiJmaAkKj732RjNbOg=\nDate: 2009-11-08T15:54:08.897Z\nHost: bucket." + + url + "\n"); assertPayloadEquals(request, null, null, false); assertResponseParserClassEquals(method, request, ParseSax.class); @@ -137,7 +137,7 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { assertRequestLineEquals(request, "PUT https://bucket." + url + "/?requestPayment HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); assertPayloadEquals(request, "BucketOwner", "text/xml", false); + + "/doc/2006-03-01/\">BucketOwner", "text/xml", false); assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); assertSaxResponseParserClassEquals(method, null); @@ -153,7 +153,7 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { assertRequestLineEquals(request, "PUT https://bucket." + url + "/?requestPayment HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); assertPayloadEquals(request, "Requester", "text/xml", false); + + "/doc/2006-03-01/\">Requester", "text/xml", false); assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); assertSaxResponseParserClassEquals(method, null); @@ -163,8 +163,8 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { } public void testListBucket() throws SecurityException, NoSuchMethodException, IOException { - Method method = S3AsyncClient.class.getMethod("listBucket", String.class, - Array.newInstance(ListBucketOptions.class, 0).getClass()); + Method method = S3AsyncClient.class.getMethod("listBucket", String.class, Array.newInstance( + ListBucketOptions.class, 0).getClass()); HttpRequest request = processor.createRequest(method, "bucket"); assertRequestLineEquals(request, "GET https://bucket." + url + "/ HTTP/1.1"); @@ -195,23 +195,23 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { @Test(expectedExceptions = IllegalArgumentException.class) public void testCopyObjectInvalidName() throws ArrayIndexOutOfBoundsException, SecurityException, - IllegalArgumentException, NoSuchMethodException, IOException { + IllegalArgumentException, NoSuchMethodException, IOException { Method method = S3AsyncClient.class.getMethod("copyObject", String.class, String.class, String.class, - String.class, Array.newInstance(CopyObjectOptions.class, 0).getClass()); + String.class, Array.newInstance(CopyObjectOptions.class, 0).getClass()); processor.createRequest(method, "sourceBucket", "sourceObject", "destinationBucket", "destinationObject"); } public void testCopyObject() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, - NoSuchMethodException, IOException { + NoSuchMethodException, IOException { Method method = S3AsyncClient.class.getMethod("copyObject", String.class, String.class, String.class, - String.class, Array.newInstance(CopyObjectOptions.class, 0).getClass()); + String.class, Array.newInstance(CopyObjectOptions.class, 0).getClass()); HttpRequest request = processor.createRequest(method, "sourceBucket", "sourceObject", "destinationbucket", - "destinationObject"); + "destinationObject"); assertRequestLineEquals(request, "PUT https://destinationbucket." + url + "/destinationObject HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: destinationbucket." + url - + "\nx-amz-copy-source: /sourceBucket/sourceObject\n"); + + "\nx-amz-copy-source: /sourceBucket/sourceObject\n"); assertPayloadEquals(request, null, null, false); assertResponseParserClassEquals(method, request, ParseSax.class); @@ -268,7 +268,7 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { } public void testGetObject() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, - NoSuchMethodException, IOException { + NoSuchMethodException, IOException { Method method = S3AsyncClient.class.getMethod("getObject", String.class, String.class, GetOptions[].class); HttpRequest request = processor.createRequest(method, "bucket", "object"); @@ -353,17 +353,17 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { public void testPutBucketACL() throws SecurityException, NoSuchMethodException, IOException { Method method = S3AsyncClient.class.getMethod("putBucketACL", String.class, AccessControlList.class); - HttpRequest request = processor.createRequest(method, "bucket", - AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234")); + HttpRequest request = processor.createRequest(method, "bucket", AccessControlList.fromCannedAccessPolicy( + CannedAccessPolicy.PRIVATE, "1234")); assertRequestLineEquals(request, "PUT https://bucket." + url + "/?acl HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); assertPayloadEquals( - request, - "12341234FULL_CONTROL", - "text/xml", false); + request, + "12341234FULL_CONTROL", + "text/xml", false); assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class); assertSaxResponseParserClassEquals(method, null); @@ -373,9 +373,9 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { } public void testPutBucketDefault() throws ArrayIndexOutOfBoundsException, SecurityException, - IllegalArgumentException, NoSuchMethodException, IOException { - Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class, String.class, - Array.newInstance(PutBucketOptions.class, 0).getClass()); + IllegalArgumentException, NoSuchMethodException, IOException { + Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class, String.class, Array.newInstance( + PutBucketOptions.class, 0).getClass()); HttpRequest request = processor.createRequest(method, (String) null, "bucket"); assertRequestLineEquals(request, "PUT https://bucket." + url + "/ HTTP/1.1"); @@ -388,33 +388,14 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { checkFilters(request); } - - public void testPutBucketEu() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, - NoSuchMethodException, IOException { - Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class, String.class, - Array.newInstance(PutBucketOptions.class, 0).getClass()); - HttpRequest request = processor.createRequest(method, "EU", "bucket"); - - assertRequestLineEquals(request, "PUT https://bucket." + url + "/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); - assertPayloadEquals(request, - "EU", - "text/xml", false); - - assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class); - assertSaxResponseParserClassEquals(method, null); - assertExceptionParserClassEquals(method, ReturnFalseIfBucketAlreadyOwnedByYouOrIllegalState.class); - - checkFilters(request); - } - + public void testPutObject() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, - NoSuchMethodException, IOException { + NoSuchMethodException, IOException { Method method = S3AsyncClient.class - .getMethod("putObject", String.class, S3Object.class, PutObjectOptions[].class); - HttpRequest request = processor.createRequest(method, "bucket", - blobToS3Object.apply(BindBlobToMultipartFormTest.TEST_BLOB)); + .getMethod("putObject", String.class, S3Object.class, PutObjectOptions[].class); + HttpRequest request = processor.createRequest(method, "bucket", blobToS3Object + .apply(BindBlobToMultipartFormTest.TEST_BLOB)); assertRequestLineEquals(request, "PUT https://bucket." + url + "/hello HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); @@ -429,18 +410,18 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { public void testPutObjectACL() throws SecurityException, NoSuchMethodException, IOException { Method method = S3AsyncClient.class - .getMethod("putObjectACL", String.class, String.class, AccessControlList.class); - HttpRequest request = processor.createRequest(method, "bucket", "key", - AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234")); + .getMethod("putObjectACL", String.class, String.class, AccessControlList.class); + HttpRequest request = processor.createRequest(method, "bucket", "key", AccessControlList.fromCannedAccessPolicy( + CannedAccessPolicy.PRIVATE, "1234")); assertRequestLineEquals(request, "PUT https://bucket." + url + "/key?acl HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); assertPayloadEquals( - request, - "12341234FULL_CONTROL", - "text/xml", false); + request, + "12341234FULL_CONTROL", + "text/xml", false); assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class); assertSaxResponseParserClassEquals(method, null); @@ -471,7 +452,7 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { assertRequestLineEquals(request, "PUT https://bucket." + url + "/?logging HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); assertPayloadEquals(request, "", "text/xml", - false); + false); assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); assertSaxResponseParserClassEquals(method, null); @@ -483,16 +464,13 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { public void testEnableBucketLoggingOwner() throws SecurityException, NoSuchMethodException, IOException { Method method = S3AsyncClient.class.getMethod("enableBucketLogging", String.class, BucketLogging.class); HttpRequest request = processor - .createRequest( - method, - "bucket", - new BucketLogging("mylogs", "access_log-", ImmutableSet. of(new Grant(new EmailAddressGrantee( - "adrian@jclouds.org"), Permission.FULL_CONTROL)))); + .createRequest(method, "bucket", new BucketLogging("mylogs", "access_log-", ImmutableSet + . of(new Grant(new EmailAddressGrantee("adrian@jclouds.org"), Permission.FULL_CONTROL)))); assertRequestLineEquals(request, "PUT https://bucket." + url + "/?logging HTTP/1.1"); assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/bucket_logging.xml")), - "text/xml", false); + "text/xml", false); assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); assertSaxResponseParserClassEquals(method, null); @@ -503,10 +481,10 @@ public class S3AsyncClientTest extends BaseS3AsyncClientTest { @RequiresHttp @ConfiguresRestClient - protected static final class TestS3RestClientModule extends S3RestClientModule { - @Override - protected void configure() { - super.configure(); + private static final class TestS3RestClientModule extends S3RestClientModule { + + public TestS3RestClientModule() { + super(S3Client.class, S3AsyncClient.class); } @Override diff --git a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java index 8bedba9ad3..c9a35e4d9a 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/S3ClientLiveTest.java @@ -86,6 +86,12 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { } } + protected URL getObjectURL(String containerName, String key) throws Exception { + URL url = new URL(String.format("http://%s.%s/%s", containerName, context.getProviderSpecificContext() + .getEndpoint().getHost(), key)); + return url; + } + public void testPutCannedAccessPolicyPublic() throws Exception { String containerName = getContainerName(); try { @@ -97,7 +103,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { withAcl(CannedAccessPolicy.PUBLIC_READ)); - URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s", containerName, key)); + URL url = this.getObjectURL(containerName, key); Strings2.toStringAndClose(url.openStream()); } finally { returnContainer(containerName); @@ -117,7 +123,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { validateContent(destinationContainer, destinationKey); - URL url = new URL(String.format("http://%1$s.s3.amazonaws.com/%2$s", destinationContainer, destinationKey)); + URL url = getObjectURL(destinationContainer, destinationKey); Strings2.toStringAndClose(url.openStream()); } finally { @@ -292,9 +298,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { getApi().putObject(containerName, object); S3Object newObject = validateObject(containerName, key); - - assert (newObject.getMetadata().getCacheControl().indexOf("no-cache") != -1) : newObject.getMetadata() - .getCacheControl(); + assertCacheControl(newObject, "no-cache"); assertEquals(newObject.getMetadata().getContentMetadata().getContentDisposition(), "attachment; filename=hello.txt"); } finally { @@ -302,6 +306,18 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { } } + protected void assertCacheControl(S3Object newObject, String string) { + assert (newObject.getMetadata().getCacheControl().indexOf(string) != -1) : newObject.getMetadata() + .getCacheControl(); + } + + protected void assertContentEncoding(S3Object newObject, String string) { + assert (newObject.getPayload().getContentMetadata().getContentEncoding().indexOf(string) != -1) : newObject + .getPayload().getContentMetadata().getContentEncoding(); + assert (newObject.getMetadata().getContentMetadata().getContentEncoding().indexOf(string) != -1) : newObject + .getMetadata().getContentMetadata().getContentEncoding(); + } + @Test(groups = { "integration", "live" }) public void testMetadataContentEncoding() throws Exception { String key = "hello"; @@ -314,8 +330,7 @@ public class S3ClientLiveTest extends BaseBlobStoreIntegrationTest { try { getApi().putObject(containerName, object); S3Object newObject = validateObject(containerName, key); - - assertEquals(newObject.getMetadata().getContentMetadata().getContentEncoding(), "x-compress"); + assertContentEncoding(newObject, "x-compress"); } finally { returnContainer(containerName); } diff --git a/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java b/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java index b67e244ec7..40b4001602 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/binders/BindAsHostPrefixIfConfiguredTest.java @@ -70,7 +70,7 @@ public class BindAsHostPrefixIfConfiguredTest extends BaseS3AsyncClientTest { @Override protected Properties getProperties() { - Properties properties = new Properties(); + Properties properties = super.getProperties(); properties.setProperty(PROPERTY_S3_SERVICE_PATH, "/services/Walrus"); properties.setProperty(PROPERTY_S3_VIRTUAL_HOST_BUCKETS, "false"); return properties; diff --git a/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java b/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java index a527128016..a0eb3c9064 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/blobstore/S3BlobRequestSignerTest.java @@ -22,10 +22,7 @@ package org.jclouds.s3.blobstore; import static org.testng.Assert.assertEquals; import java.io.IOException; -import java.util.Properties; -import org.jclouds.s3.S3AsyncClient; -import org.jclouds.s3.config.S3RestClientModule; import org.jclouds.blobstore.BlobRequestSigner; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.Blob.Factory; @@ -34,16 +31,15 @@ import org.jclouds.http.HttpRequest; import org.jclouds.http.RequiresHttp; import org.jclouds.io.payloads.PhantomPayload; import org.jclouds.rest.ConfiguresRestClient; -import org.jclouds.rest.RestClientTest; -import org.jclouds.rest.RestContextFactory; -import org.jclouds.rest.RestContextSpec; -import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.jclouds.s3.BaseS3AsyncClientTest; +import org.jclouds.s3.S3AsyncClient; +import org.jclouds.s3.S3Client; +import org.jclouds.s3.config.S3RestClientModule; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import com.google.common.base.Supplier; import com.google.inject.Module; -import com.google.inject.TypeLiteral; /** * Tests behavior of {@code S3BlobRequestSigner} @@ -52,39 +48,39 @@ import com.google.inject.TypeLiteral; */ // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "S3BlobRequestSignerTest") -public class S3BlobRequestSignerTest extends RestClientTest { +public class S3BlobRequestSignerTest extends BaseS3AsyncClientTest { private BlobRequestSigner signer; private Factory blobFactory; public void testSignGetBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, - NoSuchMethodException, IOException { + NoSuchMethodException, IOException { HttpRequest request = signer.signGetBlob("container", "name"); assertRequestLineEquals(request, "GET https://container.s3.amazonaws.com/name HTTP/1.1"); assertNonPayloadHeadersEqual( - request, - "Authorization: AWS identity:0uvBv1wEskuhFHYJF/L6kEV9A7o=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n"); + request, + "Authorization: AWS identity:0uvBv1wEskuhFHYJF/L6kEV9A7o=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n"); assertPayloadEquals(request, null, null, false); assertEquals(request.getFilters().size(), 0); } public void testSignRemoveBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, - NoSuchMethodException, IOException { + NoSuchMethodException, IOException { HttpRequest request = signer.signRemoveBlob("container", "name"); assertRequestLineEquals(request, "DELETE https://container.s3.amazonaws.com/name HTTP/1.1"); assertNonPayloadHeadersEqual( - request, - "Authorization: AWS identity:4FnyjdX/ULdDMRbVlLNjZfEo9RQ=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n"); + request, + "Authorization: AWS identity:4FnyjdX/ULdDMRbVlLNjZfEo9RQ=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n"); assertPayloadEquals(request, null, null, false); assertEquals(request.getFilters().size(), 0); } public void testSignPutBlob() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, - NoSuchMethodException, IOException { + NoSuchMethodException, IOException { Blob blob = blobFactory.create(null); blob.getMetadata().setName("name"); blob.setPayload(new PhantomPayload()); @@ -96,8 +92,8 @@ public class S3BlobRequestSignerTest extends RestClientTest { assertRequestLineEquals(request, "PUT https://container.s3.amazonaws.com/name HTTP/1.1"); assertNonPayloadHeadersEqual( - request, - "Authorization: AWS identity:j9Dy/lmmvlCKjA4lkqZenLxMkR4=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n"); + request, + "Authorization: AWS identity:j9Dy/lmmvlCKjA4lkqZenLxMkR4=\nDate: Thu, 05 Jun 2008 16:38:19 GMT\nHost: container.s3.amazonaws.com\n"); assertContentHeadersEqual(request, "text/plain", null, null, null, (long) 2l, new byte[] { 0, 2, 4, 8 }); @@ -111,16 +107,6 @@ public class S3BlobRequestSignerTest extends RestClientTest { this.signer = injector.getInstance(BlobRequestSigner.class); } - @Override - protected void checkFilters(HttpRequest request) { - } - - @Override - protected TypeLiteral> createTypeLiteral() { - return new TypeLiteral>() { - }; - } - @Override protected Module createModule() { return new TestS3RestClientModule(); @@ -128,10 +114,10 @@ public class S3BlobRequestSignerTest extends RestClientTest { @RequiresHttp @ConfiguresRestClient - private static final class TestS3RestClientModule extends S3RestClientModule { - @Override - protected void configure() { - super.configure(); + private static final class TestS3RestClientModule extends S3RestClientModule { + + public TestS3RestClientModule() { + super(S3Client.class, S3AsyncClient.class); } @Override @@ -140,9 +126,4 @@ public class S3BlobRequestSignerTest extends RestClientTest { } } - @Override - public RestContextSpec createContextSpec() { - return new RestContextFactory().createContextSpec("s3", "identity", "credential", new Properties()); - } - } diff --git a/apis/s3/src/test/java/org/jclouds/s3/config/S3RestClientModuleTest.java b/apis/s3/src/test/java/org/jclouds/s3/config/S3RestClientModuleTest.java deleted file mode 100644 index 5547c73e46..0000000000 --- a/apis/s3/src/test/java/org/jclouds/s3/config/S3RestClientModuleTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.s3.config; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; - -import java.io.IOException; -import java.util.Properties; - -import org.jclouds.aws.handlers.AWSClientErrorRetryHandler; -import org.jclouds.aws.handlers.AWSRedirectionRetryHandler; -import org.jclouds.date.internal.SimpleDateFormatDateService; -import org.jclouds.http.handlers.DelegatingErrorHandler; -import org.jclouds.http.handlers.DelegatingRetryHandler; -import org.jclouds.logging.config.NullLoggingModule; -import org.jclouds.rest.BaseRestClientTest.MockModule; -import org.jclouds.rest.RestContextFactory; -import org.jclouds.s3.handlers.ParseS3ErrorFromXmlContent; -import org.testng.annotations.Test; - -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableSet; -import com.google.inject.Injector; - -/** - * @author Adrian Cole - */ -@Test(groups = "unit") -public class S3RestClientModuleTest { - - Injector createInjector() throws IOException { - return new RestContextFactory().createContextBuilder("s3", "foo", "bar", - ImmutableSet.of(new MockModule(), new NullLoggingModule()), new Properties()) - .buildInjector(); - - } - - @Test - void testUpdatesOnlyOncePerSecond() throws NoSuchMethodException, InterruptedException { - S3RestClientModule module = new S3RestClientModule(); - - Supplier map = module.provideTimeStampCache(1, new SimpleDateFormatDateService()); - String timeStamp = map.get(); - for (int i = 0; i < 10; i++) - map.get(); - assertEquals(timeStamp, map.get()); - Thread.sleep(1001); - assertFalse(timeStamp.equals(map.get())); - } - - @Test - void testServerErrorHandler() throws IOException { - DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class); - assertEquals(handler.getServerErrorHandler().getClass(), ParseS3ErrorFromXmlContent.class); - } - - @Test - void testClientErrorHandler() throws IOException { - DelegatingErrorHandler handler = createInjector().getInstance(DelegatingErrorHandler.class); - assertEquals(handler.getClientErrorHandler().getClass(), ParseS3ErrorFromXmlContent.class); - } - - @Test - void testClientRetryHandler() throws IOException { - DelegatingRetryHandler handler = createInjector().getInstance(DelegatingRetryHandler.class); - assertEquals(handler.getClientErrorRetryHandler().getClass(), - AWSClientErrorRetryHandler.class); - } - - @Test - void testRedirectionRetryHandler() throws IOException { - DelegatingRetryHandler handler = createInjector().getInstance(DelegatingRetryHandler.class); - assertEquals(handler.getRedirectionRetryHandler().getClass(), - AWSRedirectionRetryHandler.class); - } - -} diff --git a/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java b/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java index 4c84efc63b..2d0d2fee19 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java +++ b/apis/s3/src/test/java/org/jclouds/s3/filters/RequestAuthorizeSignatureTest.java @@ -69,21 +69,21 @@ public class RequestAuthorizeSignatureTest extends BaseS3AsyncClientTest { date = request.getFirstHeaderOrNull(HttpHeaders.DATE); filter.filter(request); if (request.getFirstHeaderOrNull(HttpHeaders.DATE).equals(date)) - assert signature.equals(request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION)) : String - .format("sig: %s != %s on attempt %s", signature, request - .getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION), iterations); + assert signature.equals(request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION)) : String.format( + "sig: %s != %s on attempt %s", signature, request.getFirstHeaderOrNull(HttpHeaders.AUTHORIZATION), + iterations); else iterations++; } - System.out.printf("%s: %d iterations before the timestamp updated %n", Thread.currentThread() - .getName(), iterations); + System.out.printf("%s: %d iterations before the timestamp updated %n", Thread.currentThread().getName(), + iterations); } @Test void testAppendBucketNameHostHeader() throws SecurityException, NoSuchMethodException { - HttpRequest request = processor.createRequest(S3AsyncClient.class.getMethod( - "getBucketLocation", String.class), "bucket"); + HttpRequest request = processor.createRequest(S3AsyncClient.class.getMethod("getBucketLocation", String.class), + "bucket"); StringBuilder builder = new StringBuilder(); filter.appendBucketName(request, builder); assertEquals(builder.toString(), "/bucket"); @@ -98,9 +98,9 @@ public class RequestAuthorizeSignatureTest extends BaseS3AsyncClientTest { } private GeneratedHttpRequest putBucketAcl() throws NoSuchMethodException { - return processor.createRequest(S3AsyncClient.class.getMethod("putBucketACL", String.class, - AccessControlList.class), "bucket", AccessControlList.fromCannedAccessPolicy( - CannedAccessPolicy.PRIVATE, "1234")); + return processor.createRequest( + S3AsyncClient.class.getMethod("putBucketACL", String.class, AccessControlList.class), "bucket", + AccessControlList.fromCannedAccessPolicy(CannedAccessPolicy.PRIVATE, "1234")); } // "?acl", "?location", "?logging", or "?torrent" @@ -129,20 +129,21 @@ public class RequestAuthorizeSignatureTest extends BaseS3AsyncClientTest { S3Object object = blobToS3Object.apply(BindBlobToMultipartFormTest.TEST_BLOB); object.getMetadata().getUserMetadata().put("x-amz-Adrian", "foo"); - HttpRequest request = processor.createRequest(S3AsyncClient.class.getMethod("putObject", - String.class, S3Object.class, PutObjectOptions[].class), "bucket", object); + HttpRequest request = processor.createRequest( + S3AsyncClient.class.getMethod("putObject", String.class, S3Object.class, PutObjectOptions[].class), + "bucket", object); return request; } @Test void testAppendBucketNameURIHost() throws SecurityException, NoSuchMethodException { - HttpRequest request = processor.createRequest(S3AsyncClient.class.getMethod( - "getBucketLocation", String.class), "bucket"); + HttpRequest request = processor.createRequest(S3AsyncClient.class.getMethod("getBucketLocation", String.class), + "bucket"); assertEquals(request.getEndpoint().getHost(), "bucket.s3.amazonaws.com"); } - + protected Properties getProperties() { - Properties overrides= new Properties(); + Properties overrides = super.getProperties(); overrides.setProperty(PROPERTY_SESSION_INTERVAL, 1 + ""); return overrides; } diff --git a/apis/s3/src/test/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContentTest.java b/apis/s3/src/test/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContentTest.java new file mode 100644 index 0000000000..8ce7e2541c --- /dev/null +++ b/apis/s3/src/test/java/org/jclouds/s3/handlers/ParseS3ErrorFromXmlContentTest.java @@ -0,0 +1,122 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.s3.handlers; + +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.reportMatcher; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.easymock.classextension.EasyMock.verify; +import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG; +import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH; +import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS; + +import java.net.URI; + +import org.easymock.IArgumentMatcher; +import org.jclouds.blobstore.ContainerNotFoundException; +import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.http.HttpCommand; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.io.Payloads; +import org.jclouds.rest.RequestSigner; +import org.jclouds.util.Strings2; +import org.testng.annotations.Test; + +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.name.Names; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class ParseS3ErrorFromXmlContentTest { + private static final String SERVICE_PATH = "/services/Walrus"; + + @Test + public void test404ContainerNotFoundExceptionPath() { + assertCodeMakes("GET", URI + .create("http://partnercloud.eucalyptus.com:8773/services/Walrus/adriancole-blobstore58/"), 404, "HTTP/1.1 404 Not Found", false, + "Monster.NotFound", ContainerNotFoundException.class); + } + + + @Test + public void test404KeyNotFoundExceptionPath() { + assertCodeMakes("GET", URI + .create("http://partnercloud.eucalyptus.com:8773/services/Walrus/adriancole-blobstore58/apples"), 404, "HTTP/1.1 404 Not Found", false, + "Monster.NotFound", KeyNotFoundException.class); + } + + private void assertCodeMakes(String method, URI uri, int statusCode, String message, final boolean virtualHost, + String content, Class expected) { + + ParseS3ErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() { + + @Override + protected void configure() { + bind(RequestSigner.class).toInstance(createMock(RequestSigner.class)); + bindConstant().annotatedWith(Names.named(PROPERTY_HEADER_TAG)).to("amz"); + bindConstant().annotatedWith(Names.named(PROPERTY_S3_SERVICE_PATH)).to(SERVICE_PATH); + bindConstant().annotatedWith(Names.named(PROPERTY_S3_VIRTUAL_HOST_BUCKETS)).to(virtualHost); + } + + }).getInstance(ParseS3ErrorFromXmlContent.class); + + HttpCommand command = createMock(HttpCommand.class); + HttpRequest request = new HttpRequest(method, uri); + HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2 + .toInputStream(content))); + response.getPayload().getContentMetadata().setContentType("application/xml"); + + expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); + command.setException(classEq(expected)); + + replay(command); + + function.handleError(command, response); + + verify(command); + } + + public static Exception classEq(final Class in) { + reportMatcher(new IArgumentMatcher() { + + @Override + public void appendTo(StringBuffer buffer) { + buffer.append("classEq("); + buffer.append(in); + buffer.append(")"); + } + + @Override + public boolean matches(Object arg) { + return arg.getClass() == in; + } + + }); + return null; + } + +} \ No newline at end of file diff --git a/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java b/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java index f8c1b5bd3c..0421743f9d 100644 --- a/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java +++ b/apis/s3/src/test/java/org/jclouds/s3/internal/StubS3AsyncClient.java @@ -37,6 +37,20 @@ import javax.inject.Singleton; import org.jclouds.Constants; import org.jclouds.aws.domain.Region; +import org.jclouds.blobstore.AsyncBlobStore; +import org.jclouds.blobstore.KeyNotFoundException; +import org.jclouds.blobstore.TransientAsyncBlobStore; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobMetadata; +import org.jclouds.blobstore.domain.MutableBlobMetadata; +import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; +import org.jclouds.blobstore.options.ListContainerOptions; +import org.jclouds.concurrent.Futures; +import org.jclouds.date.DateService; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.http.options.GetOptions; import org.jclouds.s3.S3AsyncClient; import org.jclouds.s3.blobstore.S3AsyncBlobStore; import org.jclouds.s3.blobstore.functions.BlobToObject; @@ -59,20 +73,6 @@ import org.jclouds.s3.options.CopyObjectOptions; import org.jclouds.s3.options.ListBucketOptions; import org.jclouds.s3.options.PutBucketOptions; import org.jclouds.s3.options.PutObjectOptions; -import org.jclouds.blobstore.AsyncBlobStore; -import org.jclouds.blobstore.KeyNotFoundException; -import org.jclouds.blobstore.TransientAsyncBlobStore; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.domain.BlobMetadata; -import org.jclouds.blobstore.domain.MutableBlobMetadata; -import org.jclouds.blobstore.functions.HttpGetOptionsListToGetOptions; -import org.jclouds.blobstore.options.ListContainerOptions; -import org.jclouds.concurrent.Futures; -import org.jclouds.date.DateService; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.http.options.GetOptions; import com.google.common.base.Function; import com.google.common.collect.Iterables; @@ -140,7 +140,8 @@ public class StubS3AsyncClient implements S3AsyncClient { region = region == null ? Region.US_STANDARD : region; final PutBucketOptions options = (optionsList.length == 0) ? new PutBucketOptions() : optionsList[0]; keyToAcl.put(name, options.getAcl()); - return blobStore.createContainerInLocation(new LocationImpl(LocationScope.REGION, region, region, null), name); + return blobStore.createContainerInLocation(new LocationBuilder().scope(LocationScope.REGION).id(region) + .description(region).build(), name); } public ListenableFuture listBucket(final String name, ListBucketOptions... optionsList) { diff --git a/apis/s3/src/test/resources/log4j.xml b/apis/s3/src/test/resources/log4j.xml index 8799a8dd70..6279530639 100644 --- a/apis/s3/src/test/resources/log4j.xml +++ b/apis/s3/src/test/resources/log4j.xml @@ -105,12 +105,11 @@ - - - - - - + diff --git a/apis/swift/README.txt b/apis/swift/README.txt new file mode 100644 index 0000000000..2aaebfc87a --- /dev/null +++ b/apis/swift/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds API for OpenStack's Swift (http://swift.openstack.org/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/SwiftBlobStoreContextModule.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/SwiftBlobStoreContextModule.java index f89cc468e5..041f31d250 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/SwiftBlobStoreContextModule.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/config/SwiftBlobStoreContextModule.java @@ -19,10 +19,6 @@ package org.jclouds.openstack.swift.blobstore.config; -import java.util.Set; - -import javax.inject.Singleton; - import org.jclouds.blobstore.AsyncBlobStore; import org.jclouds.blobstore.BlobRequestSigner; import org.jclouds.blobstore.BlobStore; @@ -30,22 +26,14 @@ import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.config.BlobStoreMapModule; import org.jclouds.blobstore.internal.BlobStoreContextImpl; -import org.jclouds.collect.Memoized; -import org.jclouds.domain.Location; -import org.jclouds.location.Region; -import org.jclouds.location.config.ProvideRegionsViaProperties; -import org.jclouds.location.suppliers.SupplyPredefinedRegions; +import org.jclouds.location.config.JustProviderLocationModule; import org.jclouds.openstack.swift.CommonSwiftAsyncClient; import org.jclouds.openstack.swift.CommonSwiftClient; import org.jclouds.openstack.swift.blobstore.SwiftAsyncBlobStore; import org.jclouds.openstack.swift.blobstore.SwiftBlobRequestSigner; import org.jclouds.openstack.swift.blobstore.SwiftBlobStore; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.collect.Iterables; import com.google.inject.AbstractModule; -import com.google.inject.Provides; import com.google.inject.Scopes; import com.google.inject.TypeLiteral; @@ -60,12 +48,7 @@ public class SwiftBlobStoreContextModule extends AbstractModule { @Override protected void configure() { install(new BlobStoreMapModule()); - bind(new TypeLiteral>>() { - }).annotatedWith(Memoized.class).to(new TypeLiteral() { - }); - bind(new TypeLiteral>() { - }).annotatedWith(Region.class).toProvider(ProvideRegionsViaProperties.class).in(Scopes.SINGLETON); - + install(new JustProviderLocationModule()); bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT); bind(AsyncBlobStore.class).to(SwiftAsyncBlobStore.class).in(Scopes.SINGLETON); bind(BlobStore.class).to(SwiftBlobStore.class).in(Scopes.SINGLETON); @@ -74,10 +57,5 @@ public class SwiftBlobStoreContextModule extends AbstractModule { bind(BlobRequestSigner.class).to(SwiftBlobRequestSigner.class); } - @Provides - @Singleton - protected Supplier getLocation(@Memoized Supplier> locations) { - return Suppliers. ofInstance(Iterables.get(locations.get(), 0)); - } } diff --git a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/functions/ObjectToBlob.java b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/functions/ObjectToBlob.java index cfbddcf2af..41bbd9f5df 100644 --- a/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/functions/ObjectToBlob.java +++ b/apis/swift/src/main/java/org/jclouds/openstack/swift/blobstore/functions/ObjectToBlob.java @@ -35,7 +35,7 @@ import com.google.common.base.Function; */ @Singleton public class ObjectToBlob implements Function { - private final Blob.Factory blobFactory; + private final Factory blobFactory; private final ObjectToBlobMetadata object2BlobMd; @Inject diff --git a/apis/swift/src/test/java/org/jclouds/openstack/swift/domain/internal/ParseObjectInfoListFromJsonResponseTest.java b/apis/swift/src/test/java/org/jclouds/openstack/swift/domain/internal/ParseObjectInfoListFromJsonResponseTest.java index 06df1d4d3f..37ad5fb246 100644 --- a/apis/swift/src/test/java/org/jclouds/openstack/swift/domain/internal/ParseObjectInfoListFromJsonResponseTest.java +++ b/apis/swift/src/test/java/org/jclouds/openstack/swift/domain/internal/ParseObjectInfoListFromJsonResponseTest.java @@ -63,7 +63,7 @@ public class ParseObjectInfoListFromJsonResponseTest { public void testApplyInputStream() { InputStream is = getClass().getResourceAsStream("/test_list_container.json"); - Set expects = Sets.newHashSet(); + Set expects = Sets.newLinkedHashSet(); ObjectInfoImpl one = i.getInstance(ObjectInfoImpl.class); one.name = "test_obj_1"; one.hash = CryptoStreams.hex("4281c348eaf83e70ddce0e07221c3d28"); diff --git a/apis/vcloud/README.txt b/apis/vcloud/README.txt index fa4b41984a..a898e09519 100644 --- a/apis/vcloud/README.txt +++ b/apis/vcloud/README.txt @@ -18,7 +18,7 @@ ==== # -# The jclouds provider for VMware vCloud (http://www.vmware.com/solutions/cloud-computing/vcloud.html). +# The jclouds API for VMware vCloud (http://www.vmware.com/products/vcloud/). # # TODO: Implementation status. # TODO: Supported features. diff --git a/apis/vcloud/pom.xml b/apis/vcloud/pom.xml index 98abaa1c5a..f6d01c2714 100644 --- a/apis/vcloud/pom.xml +++ b/apis/vcloud/pom.xml @@ -80,10 +80,16 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j - 1.2.14 + 1.2.16 test diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java index 55e2b2d8c0..6813714173 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudAsyncClient.java @@ -47,8 +47,8 @@ import org.jclouds.rest.annotations.Endpoint; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; -import org.jclouds.rest.annotations.MapPayloadParams; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.PayloadParams; import org.jclouds.rest.annotations.ParamValidators; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.XMLResponseParser; @@ -154,8 +154,8 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppHandler.class) @MapBinder(BindInstantiateVAppTemplateParamsToXmlPayload.class) ListenableFuture instantiateVAppTemplateInVDC(@EndpointParam URI vdc, - @MapPayloadParam("template") URI template, - @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, + @PayloadParam("template") URI template, + @PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, InstantiateVAppTemplateOptions... options); /** @@ -167,8 +167,8 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @Consumes(TASK_XML) @XMLResponseParser(TaskHandler.class) @MapBinder(BindCloneVAppParamsToXmlPayload.class) - ListenableFuture cloneVAppInVDC(@EndpointParam URI vdc, @MapPayloadParam("vApp") URI toClone, - @MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, + ListenableFuture cloneVAppInVDC(@EndpointParam URI vdc, @PayloadParam("vApp") URI toClone, + @PayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, CloneVAppOptions... options); /** @@ -181,8 +181,8 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VAppTemplateHandler.class) @MapBinder(BindCaptureVAppParamsToXmlPayload.class) ListenableFuture captureVAppInVDC(@EndpointParam URI vdc, - @MapPayloadParam("vApp") URI toCapture, - @MapPayloadParam("templateName") @ParamValidators(DnsNameValidator.class) String templateName, + @PayloadParam("vApp") URI toCapture, + @PayloadParam("templateName") @ParamValidators(DnsNameValidator.class) String templateName, CaptureVAppOptions... options); /** @@ -246,7 +246,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @Produces(DEPLOYVAPPPARAMS_XML) @Path("/action/deploy") @MapBinder(BindDeployVAppParamsToXmlPayload.class) - @MapPayloadParams(keys = "powerOn", values = "true") + @PayloadParams(keys = "powerOn", values = "true") @XMLResponseParser(TaskHandler.class) ListenableFuture deployAndPowerOnVAppOrVm(@EndpointParam URI vAppOrVmId); @@ -269,7 +269,7 @@ public interface VCloudAsyncClient extends CommonVCloudAsyncClient { @Produces(UNDEPLOYVAPPPARAMS_XML) @Path("/action/undeploy") @MapBinder(BindUndeployVAppParamsToXmlPayload.class) - @MapPayloadParams(keys = "saveState", values = "true") + @PayloadParams(keys = "saveState", values = "true") @XMLResponseParser(TaskHandler.class) ListenableFuture undeployAndSaveStateOfVAppOrVm(@EndpointParam URI vAppOrVmId); diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCaptureVAppParamsToXmlPayload.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCaptureVAppParamsToXmlPayload.java index db0039012e..5d11f4e8f5 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCaptureVAppParamsToXmlPayload.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCaptureVAppParamsToXmlPayload.java @@ -66,7 +66,7 @@ public class BindCaptureVAppParamsToXmlPayload implements MapBinder { @Override public R bindToRequest(R request, Map postParams) { - checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, "this binder is only valid for GeneratedHttpRequests!"); GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; checkState(gRequest.getArgs() != null, "args should be initialized at this point"); diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java index 9eaea0a971..e076338735 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVAppTemplateParamsToXmlPayload.java @@ -94,7 +94,7 @@ public class BindInstantiateVAppTemplateParamsToXmlPayload implements MapBinder @Override public R bindToRequest(R request, Map postParams) { - checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, "this binder is only valid for GeneratedHttpRequests!"); GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; checkState(gRequest.getArgs() != null, "args should be initialized at this point"); diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/VCloudBindComputeStrategiesByClass.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/VCloudBindComputeStrategiesByClass.java index 83e89e4344..39710af9f0 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/VCloudBindComputeStrategiesByClass.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/config/VCloudBindComputeStrategiesByClass.java @@ -19,14 +19,14 @@ package org.jclouds.vcloud.compute.config; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.vcloud.compute.strategy.VCloudAddNodeWithTagStrategy; +import org.jclouds.vcloud.compute.strategy.InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn; import org.jclouds.vcloud.compute.strategy.VCloudDestroyNodeStrategy; import org.jclouds.vcloud.compute.strategy.VCloudGetNodeMetadataStrategy; import org.jclouds.vcloud.compute.strategy.VCloudListNodesStrategy; @@ -36,8 +36,8 @@ import org.jclouds.vcloud.compute.strategy.VCloudLifeCycleStrategy; */ public class VCloudBindComputeStrategiesByClass extends CommonVCloudBindComputeStrategiesByClass { @Override - protected Class defineAddNodeWithTagStrategy() { - return VCloudAddNodeWithTagStrategy.class; + protected Class defineAddNodeWithTagStrategy() { + return InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.class; } @Override diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/functions/VAppToNodeMetadata.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/functions/VAppToNodeMetadata.java index 6f2f8e9f77..a60128c890 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/functions/VAppToNodeMetadata.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/functions/VAppToNodeMetadata.java @@ -20,7 +20,7 @@ package org.jclouds.vcloud.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getCredentialsFrom; import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getPrivateIpsFromVApp; import static org.jclouds.vcloud.compute.util.VCloudComputeUtils.getPublicIpsFromVApp; @@ -71,12 +71,7 @@ public class VAppToNodeMetadata implements Function { builder.uri(from.getHref()); builder.name(from.getName()); builder.location(findLocationForResourceInVDC.apply(from.getVDC())); - String tag = parseTagFromName(from.getName()); - builder.tag(tag); - if (logger.isTraceEnabled()) { - if (tag.startsWith("NOTAG#")) - logger.warn("failed to parse tag from name %s", from); - } + builder.group(parseGroupFromName(from.getName())); builder.operatingSystem(toComputeOs(from, null)); builder.hardware(hardwareForVApp.apply(from)); builder.state(vAppStatusToNodeState.get(from.getStatus())); diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudAddNodeWithTagStrategy.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java similarity index 92% rename from apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudAddNodeWithTagStrategy.java rename to apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java index 000ef311eb..c49fa8ebf1 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudAddNodeWithTagStrategy.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn.java @@ -32,7 +32,7 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.logging.Logger; import org.jclouds.vcloud.VCloudClient; @@ -50,7 +50,7 @@ import com.google.common.collect.Iterables; * @author Adrian Cole */ @Singleton -public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy { +public class InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn implements CreateNodeWithGroupEncodedIntoName { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; @@ -60,7 +60,7 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy { protected final Predicate successTester; @Inject - protected VCloudAddNodeWithTagStrategy(Predicate successTester, VCloudClient client, + protected InstantiateVAppTemplateWithGroupEncodedIntoNameThenCustomizeDeployAndPowerOn(Predicate successTester, VCloudClient client, GetNodeMetadataStrategy getNode) { this.client = client; this.successTester = successTester; @@ -68,7 +68,7 @@ public class VCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy { } @Override - public NodeMetadata addNodeWithTag(String tag, String name, Template template) { + public NodeMetadata createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { InstantiateVAppTemplateOptions options = processorCount((int) getCores(template.getHardware())).memory( template.getHardware().getRam()).disk( (long) ((template.getHardware().getVolumes().get(0).getSize()) * 1024 * 1024l)); diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/util/VCloudComputeUtils.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/util/VCloudComputeUtils.java index d2c195257e..f17fdb4e8e 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/util/VCloudComputeUtils.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/util/VCloudComputeUtils.java @@ -63,7 +63,7 @@ public class VCloudComputeUtils { } public static CIMOperatingSystem toComputeOs(org.jclouds.vcloud.domain.ovf.OperatingSystemSection os) { - return new CIMOperatingSystem(CIMOperatingSystem.OSType.fromValue(os.getId()), null, null, os.getDescription()); + return new CIMOperatingSystem(CIMOperatingSystem.OSType.fromValue(os.getId()), "", null, os.getDescription()); } public static Credentials getCredentialsFrom(VApp vApp) { diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/CaptureVAppLiveTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/CaptureVAppLiveTest.java index 6ea071285d..b87f329f28 100644 --- a/apis/vcloud/src/test/java/org/jclouds/vcloud/CaptureVAppLiveTest.java +++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/CaptureVAppLiveTest.java @@ -51,7 +51,7 @@ public class CaptureVAppLiveTest { protected ComputeService client; - protected String tag = System.getProperty("user.name") + "cap"; + protected String group = System.getProperty("user.name") + "cap"; protected String provider = "vcloud"; protected String identity; @@ -94,7 +94,7 @@ public class CaptureVAppLiveTest { VAppTemplate vappTemplate = null; try { - node = getOnlyElement(client.runNodesWithTag(tag, 1)); + node = getOnlyElement(client.createNodesInGroup(group, 1)); VCloudClient vcloudApi = VCloudClient.class.cast(client.getContext().getProviderSpecificContext().getApi()); @@ -117,7 +117,7 @@ public class CaptureVAppLiveTest { // vdc is equiv to the node's location // vapp uri is the same as the node's id vappTemplate = vcloudApi.captureVAppInVDC(URI.create(node.getLocation().getId()), URI.create(node.getId()), - tag); + group); task = vappTemplate.getTasks().get(0); diff --git a/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java b/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java index 5c424e55c5..09acac0efe 100644 --- a/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java +++ b/apis/vcloud/src/test/java/org/jclouds/vcloud/VCloudGuestCustomizationLiveTest.java @@ -50,7 +50,7 @@ import com.google.inject.Module; /** * This tests that we can use guest customization as an alternative to bootstrapping with ssh. There - * are a few advantages to this, including the fact that it can work inside google appengine where + * are a few advangroupes to this, including the fact that it can work inside google appengine where * network sockets (ssh:22) are prohibited. * * @author Adrian Cole @@ -110,7 +110,7 @@ public class VCloudGuestCustomizationLiveTest { @Test public void testExtendedOptionsWithCustomizationScript() throws Exception { - String tag = "customize"; + String group = "customize"; String script = "cat > /root/foo.txt< + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds API for VMware vCloud (http://www.vmware.com/solutions/cloud-computing/public-cloud/vcloud-express.html). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/vcloudexpress/pom.xml b/apis/vcloudexpress/pom.xml index 0c610152ce..c32f9fa101 100644 --- a/apis/vcloudexpress/pom.xml +++ b/apis/vcloudexpress/pom.xml @@ -80,10 +80,16 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j - 1.2.14 + 1.2.16 test diff --git a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java index 7fac6530e5..35416eab36 100644 --- a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java +++ b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/VCloudExpressAsyncClient.java @@ -38,7 +38,7 @@ import org.jclouds.predicates.validators.DnsNameValidator; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.ParamValidators; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.XMLResponseParser; @@ -126,8 +126,8 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient { @XMLResponseParser(VCloudExpressVAppHandler.class) @MapBinder(BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload.class) ListenableFuture instantiateVAppTemplateInVDC(@EndpointParam URI vdc, - @MapPayloadParam("template") URI template, - @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, + @PayloadParam("template") URI template, + @PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, InstantiateVAppTemplateOptions... options); /** @@ -139,8 +139,8 @@ public interface VCloudExpressAsyncClient extends CommonVCloudAsyncClient { @Consumes(TASK_XML) @XMLResponseParser(TaskHandler.class) @MapBinder(BindCloneVAppParamsToXmlPayload.class) - ListenableFuture cloneVAppInVDC(@EndpointParam URI vdc, @MapPayloadParam("vApp") URI toClone, - @MapPayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, + ListenableFuture cloneVAppInVDC(@EndpointParam URI vdc, @PayloadParam("vApp") URI toClone, + @PayloadParam("newName") @ParamValidators(DnsNameValidator.class) String newName, CloneVAppOptions... options); /** diff --git a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload.java b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload.java index dd4b4e9372..c19be44295 100644 --- a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload.java +++ b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/binders/BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload.java @@ -87,7 +87,7 @@ public class BindInstantiateVCloudExpressVAppTemplateParamsToXmlPayload implemen @Override public R bindToRequest(R request, Map postParams) { - checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, "this binder is only valid for GeneratedHttpRequests!"); GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; checkState(gRequest.getArgs() != null, "args should be initialized at this point"); diff --git a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressBindComputeStrategiesByClass.java b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressBindComputeStrategiesByClass.java index 65039af16a..d64f1c4483 100644 --- a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressBindComputeStrategiesByClass.java +++ b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressBindComputeStrategiesByClass.java @@ -19,14 +19,14 @@ package org.jclouds.vcloud.compute.config; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.vcloud.compute.strategy.VCloudExpressAddNodeWithTagStrategy; +import org.jclouds.vcloud.compute.strategy.StartVAppWithGroupEncodedIntoName; import org.jclouds.vcloud.compute.strategy.VCloudExpressDestroyNodeStrategy; import org.jclouds.vcloud.compute.strategy.VCloudExpressGetNodeMetadataStrategy; import org.jclouds.vcloud.compute.strategy.VCloudExpressListNodesStrategy; @@ -38,8 +38,8 @@ import org.jclouds.vcloud.compute.strategy.VCloudExpressLifeCycleStrategy; public class VCloudExpressBindComputeStrategiesByClass extends CommonVCloudBindComputeStrategiesByClass { @Override - protected Class defineAddNodeWithTagStrategy() { - return VCloudExpressAddNodeWithTagStrategy.class; + protected Class defineAddNodeWithTagStrategy() { + return StartVAppWithGroupEncodedIntoName.class; } @Override diff --git a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java index 9eb35ffdf7..a156a564e7 100755 --- a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java +++ b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/config/VCloudExpressComputeServiceContextModule.java @@ -26,6 +26,7 @@ import org.jclouds.compute.config.BindComputeStrategiesByClass; import org.jclouds.compute.config.BindComputeSuppliersByClass; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.rest.RestContext; import org.jclouds.rest.internal.RestContextImpl; @@ -33,6 +34,7 @@ import org.jclouds.vcloud.VCloudExpressClient; import org.jclouds.vcloud.compute.CommonVCloudComputeClient; import org.jclouds.vcloud.compute.VCloudExpressComputeClient; import org.jclouds.vcloud.compute.functions.ImagesInVCloudExpressOrg; +import org.jclouds.vcloud.compute.functions.ParseOsFromVAppTemplateName; import org.jclouds.vcloud.compute.functions.VCloudExpressVAppToNodeMetadata; import org.jclouds.vcloud.compute.internal.VCloudExpressComputeClientImpl; import org.jclouds.vcloud.domain.Org; @@ -64,6 +66,8 @@ public class VCloudExpressComputeServiceContextModule extends CommonVCloudComput bind(new TypeLiteral>>() { }).to(new TypeLiteral() { }); + bind(new TypeLiteral>() { + }).to(ParseOsFromVAppTemplateName.class); } protected void bindVAppConverter() { diff --git a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/ImageForVCloudExpressVAppTemplate.java b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/ImageForVCloudExpressVAppTemplate.java index 7320daed15..66b613333b 100644 --- a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/ImageForVCloudExpressVAppTemplate.java +++ b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/ImageForVCloudExpressVAppTemplate.java @@ -20,21 +20,14 @@ package org.jclouds.vcloud.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrUnrecognized; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import javax.inject.Inject; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.domain.OperatingSystem; -import org.jclouds.compute.domain.OperatingSystemBuilder; -import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; -import org.jclouds.compute.util.ComputeServiceUtils; import org.jclouds.vcloud.domain.ReferenceType; import org.jclouds.vcloud.domain.VCloudExpressVAppTemplate; @@ -46,17 +39,16 @@ import com.google.common.base.Function; public class ImageForVCloudExpressVAppTemplate implements Function { private final FindLocationForResource findLocationForResource; private final PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider; - private ReferenceType parent; + private final Function osParser; - private final Map> osVersionMap; + private ReferenceType parent; @Inject protected ImageForVCloudExpressVAppTemplate(FindLocationForResource findLocationForResource, - PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider, - Map> osVersionMap) { - this.osVersionMap = osVersionMap; + PopulateDefaultLoginCredentialsForImageStrategy credentialsProvider, Function osParser) { this.findLocationForResource = checkNotNull(findLocationForResource, "findLocationForResource"); this.credentialsProvider = checkNotNull(credentialsProvider, "credentialsProvider"); + this.osParser = osParser; } public ImageForVCloudExpressVAppTemplate withParent(ReferenceType parent) { @@ -72,24 +64,8 @@ public class ImageForVCloudExpressVAppTemplate implements Function + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrUnrecognized; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.OperatingSystemBuilder; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.util.ComputeServiceUtils; + +import com.google.common.base.Function; + +/** + * @author Adrian Cole + */ +@Singleton +public class ParseOsFromVAppTemplateName implements Function { + protected static final Pattern OS_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)"); + + protected final Map> osVersionMap; + + @Inject + protected ParseOsFromVAppTemplateName(Map> osVersionMap) { + this.osVersionMap = checkNotNull(osVersionMap, "osVersionMap"); + } + + @Override + public OperatingSystem apply(String from) { + OperatingSystemBuilder builder = new OperatingSystemBuilder(); + OsFamily osFamily = parseOsFamilyOrUnrecognized(checkNotNull(from, "vapp template name")); + builder.family(osFamily); + builder.description(from); + builder.is64Bit(from.indexOf("64") != -1); + Matcher matcher = OS_PATTERN.matcher(from); + if (matcher.find()) { + builder.version(ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(3), osVersionMap)); + } + return builder.build(); + } +} \ No newline at end of file diff --git a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/VCloudExpressVAppToNodeMetadata.java b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/VCloudExpressVAppToNodeMetadata.java index 06eeb101d6..d23ecc3cf4 100644 --- a/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/VCloudExpressVAppToNodeMetadata.java +++ b/apis/vcloudexpress/src/main/java/org/jclouds/vcloud/compute/functions/VCloudExpressVAppToNodeMetadata.java @@ -20,7 +20,7 @@ package org.jclouds.vcloud.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import java.util.Map; import java.util.Set; @@ -75,7 +75,7 @@ public class VCloudExpressVAppToNodeMetadata implements Function vAppToNodeMetadata; @Inject - protected VCloudExpressAddNodeWithTagStrategy(VCloudExpressClient client, VCloudExpressComputeClient computeClient, + protected StartVAppWithGroupEncodedIntoName(VCloudExpressClient client, VCloudExpressComputeClient computeClient, Function vAppToNodeMetadata) { this.client = client; this.computeClient = computeClient; @@ -55,7 +55,7 @@ public class VCloudExpressAddNodeWithTagStrategy implements AddNodeWithTagStrate } @Override - public NodeMetadata addNodeWithTag(String tag, String name, Template template) { + public NodeMetadata createNodeWithGroupEncodedIntoName(String tag, String name, Template template) { InstantiateVAppTemplateOptions options = processorCount((int) getCores(template.getHardware())).memory( template.getHardware().getRam()).disk( (long) ((template.getHardware().getVolumes().get(0).getSize()) * 1024 * 1024l)); diff --git a/apis/vcloudexpress/src/test/java/org/jclouds/vcloud/VCloudExpressAsyncClientTest.java b/apis/vcloudexpress/src/test/java/org/jclouds/vcloud/VCloudExpressAsyncClientTest.java index 4a6b1cc663..4347a9617e 100644 --- a/apis/vcloudexpress/src/test/java/org/jclouds/vcloud/VCloudExpressAsyncClientTest.java +++ b/apis/vcloudexpress/src/test/java/org/jclouds/vcloud/VCloudExpressAsyncClientTest.java @@ -82,7 +82,6 @@ import com.google.inject.Injector; import com.google.inject.Module; import com.google.inject.TypeLiteral; - /** * Tests behavior of {@code VCloudExpressAsyncClient} * @@ -94,17 +93,16 @@ public class VCloudExpressAsyncClientTest extends RestClientTest createContextSpec() { - Properties overrides = new Properties(); - overrides.setProperty("vcloudexpress.endpoint", "https://vcloud.safesecureweb.com/api/v0.8"); - return new RestContextFactory().createContextSpec("vcloudexpress", "identity", "credential", overrides); + return new RestContextFactory(getProperties()).createContextSpec(provider, "identity", "credential", + new Properties()); } @RequiresHttp @@ -645,7 +664,7 @@ public class VCloudExpressAsyncClientTest extends RestClientTest> vDCtoOrgSupplier) { + @org.jclouds.vcloud.endpoints.VDC Supplier> vDCtoOrgSupplier) { return "vdc"; } @@ -699,13 +718,13 @@ public class VCloudExpressAsyncClientTest extends RestClientTest provideVCloudTokenCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final VCloudExpressLoginAsyncClient login) { + final VCloudExpressLoginAsyncClient login) { return Suppliers. ofInstance(new VCloudSession() { @Override public Map getOrgs() { return ImmutableMap. of("org", new ReferenceTypeImpl("org", - VCloudExpressMediaType.ORG_XML, URI.create("https://vcloud.safesecureweb.com/api/v0.8/org/1"))); + VCloudExpressMediaType.ORG_XML, URI.create("https://vcloud.safesecureweb.com/api/v0.8/org/1"))); } @Override @@ -726,20 +745,22 @@ public class VCloudExpressAsyncClientTest extends RestClientTest>> provideOrgVDCSupplierCache( - @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { + @Named(PROPERTY_SESSION_INTERVAL) long seconds, final OrgVDCSupplier supplier) { return Suppliers.>> ofInstance(ImmutableMap - .> of("org", + .> of("org", - ImmutableMap. of("vdc", new VDCImpl("vdc", null, URI - .create("https://vcloud.safesecureweb.com/api/v0.8/vdc/1"), null, null, "description", null, - null, null, null, null, ImmutableMap. of("vapp", - new ReferenceTypeImpl("vapp", "application/vnd.vmware.vcloud.vApp+xml", URI - .create("https://vcloud.safesecureweb.com/api/v0.8/vApp/188849-1")), - "network", new ReferenceTypeImpl("network", - "application/vnd.vmware.vcloud.vAppTemplate+xml", URI - .create("https://vcloud.safesecureweb.com/api/v0.8/vdcItem/2"))), - null, 0, 0, 0, false)))); + ImmutableMap. of( + "vdc", + new VDCImpl("vdc", null, URI.create("https://vcloud.safesecureweb.com/api/v0.8/vdc/1"), null, + null, "description", null, null, null, null, null, ImmutableMap. of( + "vapp", + new ReferenceTypeImpl("vapp", "application/vnd.vmware.vcloud.vApp+xml", URI + .create("https://vcloud.safesecureweb.com/api/v0.8/vApp/188849-1")), + "network", + new ReferenceTypeImpl("network", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI + .create("https://vcloud.safesecureweb.com/api/v0.8/vdcItem/2"))), null, 0, 0, 0, + false)))); } @@ -752,17 +773,21 @@ public class VCloudExpressAsyncClientTest extends RestClientTest get() { - return ImmutableMap. of("org", new OrgImpl("org", null, URI - .create("https://vcloud.safesecureweb.com/api/v0.8/org/1"), "org", null, ImmutableMap - . of("catalog", new ReferenceTypeImpl("catalog", - VCloudExpressMediaType.CATALOG_XML, URI - .create("https://vcloud.safesecureweb.com/api/v0.8/catalog/1"))), ImmutableMap - . of("vdc", new ReferenceTypeImpl("vdc", VCloudExpressMediaType.VDC_XML, - URI.create("https://vcloud.safesecureweb.com/api/v0.8/vdc/1"))), ImmutableMap - . of(), new ReferenceTypeImpl("tasksList", - VCloudExpressMediaType.TASKSLIST_XML, URI - .create("https://vcloud.safesecureweb.com/api/v0.8/tasksList/1")), ImmutableList - . of())); + return ImmutableMap. of( + "org", + new OrgImpl("org", null, URI.create("https://vcloud.safesecureweb.com/api/v0.8/org/1"), "org", null, + ImmutableMap. of( + "catalog", + new ReferenceTypeImpl("catalog", VCloudExpressMediaType.CATALOG_XML, URI + .create("https://vcloud.safesecureweb.com/api/v0.8/catalog/1"))), ImmutableMap + . of( + "vdc", + new ReferenceTypeImpl("vdc", VCloudExpressMediaType.VDC_XML, URI + .create("https://vcloud.safesecureweb.com/api/v0.8/vdc/1"))), ImmutableMap + . of(), new ReferenceTypeImpl("tasksList", + VCloudExpressMediaType.TASKSLIST_XML, URI + .create("https://vcloud.safesecureweb.com/api/v0.8/tasksList/1")), ImmutableList + . of())); } } @@ -777,14 +802,17 @@ public class VCloudExpressAsyncClientTest extends RestClientTest> get() { return ImmutableMap.> of("org", - ImmutableMap. of("catalog", new CatalogImpl("catalog", "type", - URI.create("https://vcloud.safesecureweb.com/api/v0.8/catalog/1"), null, "description", - ImmutableMap. of("item", new ReferenceTypeImpl("item", - "application/vnd.vmware.vcloud.catalogItem+xml", URI - .create("https://vcloud.safesecureweb.com/api/v0.8/catalogItem/1")), "template", + ImmutableMap. of( + "catalog", + new CatalogImpl("catalog", "type", URI.create("https://vcloud.safesecureweb.com/api/v0.8/catalog/1"), + null, "description", ImmutableMap. of( + "item", + new ReferenceTypeImpl("item", "application/vnd.vmware.vcloud.catalogItem+xml", URI + .create("https://vcloud.safesecureweb.com/api/v0.8/catalogItem/1")), + "template", new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", URI - .create("https://vcloud.safesecureweb.com/api/v0.8/catalogItem/2"))), - ImmutableList. of(), true))); + .create("https://vcloud.safesecureweb.com/api/v0.8/catalogItem/2"))), ImmutableList + . of(), true))); } } @@ -796,26 +824,15 @@ public class VCloudExpressAsyncClientTest extends RestClientTest>> get() { - return ImmutableMap - .>> of( - "org", - ImmutableMap - .> of( - "catalog", - ImmutableMap - . of( - "template", - new CatalogItemImpl( - "template", - URI - .create("https://vcloud.safesecureweb.com/api/v0.8/catalogItem/2"), - "description", - new ReferenceTypeImpl( - "template", - "application/vnd.vmware.vcloud.vAppTemplate+xml", - URI - .create("https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/2")), - ImmutableMap. of())))); + return ImmutableMap.>> of( + "org", ImmutableMap.> of( + "catalog", ImmutableMap. of( + "template", + new CatalogItemImpl("template", URI + .create("https://vcloud.safesecureweb.com/api/v0.8/catalogItem/2"), "description", + new ReferenceTypeImpl("template", "application/vnd.vmware.vcloud.vAppTemplate+xml", + URI.create("https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/2")), + ImmutableMap. of())))); } } diff --git a/apis/walrus/README.txt b/apis/walrus/README.txt new file mode 100644 index 0000000000..d866ca42ff --- /dev/null +++ b/apis/walrus/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds API for Walrus, Eucalyptus Systems' S3 flavour (http://www.eucalyptus.com/). +# +# Expects the jclouds S3 API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/apis/walrus/src/main/java/org/jclouds/walrus/WalrusAsyncClient.java b/apis/walrus/src/main/java/org/jclouds/walrus/WalrusAsyncClient.java new file mode 100644 index 0000000000..dc94936a7c --- /dev/null +++ b/apis/walrus/src/main/java/org/jclouds/walrus/WalrusAsyncClient.java @@ -0,0 +1,64 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.walrus; + +import static org.jclouds.blobstore.attr.BlobScopes.CONTAINER; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +import org.jclouds.blobstore.attr.BlobScope; +import org.jclouds.blobstore.functions.ReturnFalseOnContainerNotFound; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.ParamValidators; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.s3.Bucket; +import org.jclouds.s3.S3AsyncClient; +import org.jclouds.s3.S3Client; +import org.jclouds.s3.binders.BindAsHostPrefixIfConfigured; +import org.jclouds.s3.filters.RequestAuthorizeSignature; +import org.jclouds.s3.predicates.validators.BucketNameValidator; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * + * @author Adrian Cole + */ +@SkipEncoding('/') +@RequestFilters(RequestAuthorizeSignature.class) +@BlobScope(CONTAINER) +public interface WalrusAsyncClient extends S3AsyncClient { + + /** + * @see S3Client#bucketExists + */ + @Override + @GET + @Path("/") + @QueryParams(keys = "max-keys", values = "0") + @ExceptionParser(ReturnFalseOnContainerNotFound.class) + ListenableFuture bucketExists( + @Bucket @BinderParam(BindAsHostPrefixIfConfigured.class) @ParamValidators( { BucketNameValidator.class }) String bucketName); + +} diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindConfirmResizeToJsonPayload.java b/apis/walrus/src/main/java/org/jclouds/walrus/WalrusContextBuilder.java similarity index 64% rename from apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindConfirmResizeToJsonPayload.java rename to apis/walrus/src/main/java/org/jclouds/walrus/WalrusContextBuilder.java index 9b3b22c86e..6e7309fac3 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindConfirmResizeToJsonPayload.java +++ b/apis/walrus/src/main/java/org/jclouds/walrus/WalrusContextBuilder.java @@ -17,23 +17,29 @@ * ==================================================================== */ -package org.jclouds.cloudservers.binders; +package org.jclouds.walrus; -import javax.inject.Singleton; +import java.util.List; +import java.util.Properties; -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.Binder; +import org.jclouds.s3.S3ContextBuilder; +import org.jclouds.walrus.config.WalrusRestClientModule; + +import com.google.inject.Module; /** * - * @author Adrian Cole * + * @author Adrian Cole */ -@Singleton -public class BindConfirmResizeToJsonPayload implements Binder { +public class WalrusContextBuilder extends S3ContextBuilder { + + public WalrusContextBuilder(Properties props) { + super(props); + } + @Override - public R bindToRequest(R request, Object toBind) { - request.setPayload("{\"confirmResize\":null}"); - return request; + protected void addClientModule(List modules) { + modules.add(new WalrusRestClientModule()); } } diff --git a/apis/walrus/src/main/java/org/jclouds/walrus/config/WalrusRestClientModule.java b/apis/walrus/src/main/java/org/jclouds/walrus/config/WalrusRestClientModule.java new file mode 100644 index 0000000000..76d6722280 --- /dev/null +++ b/apis/walrus/src/main/java/org/jclouds/walrus/config/WalrusRestClientModule.java @@ -0,0 +1,51 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.walrus.config; + +import javax.inject.Singleton; + +import org.jclouds.http.RequiresHttp; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.s3.S3AsyncClient; +import org.jclouds.s3.S3Client; +import org.jclouds.s3.config.S3RestClientModule; +import org.jclouds.walrus.WalrusAsyncClient; + +import com.google.inject.Provides; + +/** + * + * @author Adrian Cole + */ +@ConfiguresRestClient +@RequiresHttp +public class WalrusRestClientModule extends S3RestClientModule { + + public WalrusRestClientModule() { + super(S3Client.class, WalrusAsyncClient.class); + } + + @Provides + @Singleton + S3AsyncClient provideS3AsyncClient(WalrusAsyncClient in) { + return in; + } + +} diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/WalrusClientLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/WalrusClientLiveTest.java index f6a5b4cf2e..473dec6d7c 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/WalrusClientLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/WalrusClientLiveTest.java @@ -19,7 +19,12 @@ package org.jclouds.walrus; +import static org.testng.Assert.assertEquals; + +import java.net.URL; + import org.jclouds.s3.S3ClientLiveTest; +import org.jclouds.s3.domain.S3Object; import org.testng.annotations.Test; /** @@ -29,5 +34,23 @@ import org.testng.annotations.Test; */ @Test(groups = "live", sequential = true, testName = "WalrusClientLiveTest") public class WalrusClientLiveTest extends S3ClientLiveTest { + // path based, not virtual host + @Override + protected URL getObjectURL(String containerName, String key) throws Exception { + URL url = new URL(String.format(context.getProviderSpecificContext().getEndpoint().toASCIIString() + + "/services/Walrus/%s/%s", containerName, key)); + return url; + } + // no support for content encoding + @Override + protected void assertContentEncoding(S3Object newObject, String string) { + assertEquals(newObject.getMetadata().getContentMetadata().getContentEncoding(), null); + } + + // no support for cache control + @Override + protected void assertCacheControl(S3Object newObject, String string) { + assertEquals(newObject.getMetadata().getCacheControl(), null); + } } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobIntegrationLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobIntegrationLiveTest.java index 1165423a4c..291124de11 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobIntegrationLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobIntegrationLiveTest.java @@ -20,21 +20,41 @@ package org.jclouds.walrus.blobstore; import java.io.IOException; -import java.util.concurrent.ExecutionException; -import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest; +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.s3.blobstore.integration.S3BlobIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ -@Test(groups = "live", testName = "WalrusBlobIntegrationLiveTest") -public class WalrusBlobIntegrationLiveTest extends BaseBlobIntegrationTest { +@Test(groups = "live", testName = "WalrusBlobIntegrationLiveTest") +public class WalrusBlobIntegrationLiveTest extends S3BlobIntegrationLiveTest { + // no support for content encoding @Override - @Test(expectedExceptions = IllegalArgumentException.class) - public void testPutObjectStream() throws InterruptedException, IOException, ExecutionException { - super.testPutObjectStream(); + protected void checkContentEncoding(Blob blob, String contentEncoding) { + assert blob.getPayload().getContentMetadata().getContentEncoding() == null; + assert blob.getMetadata().getContentMetadata().getContentEncoding() == null; } + // no support for content language + @Override + protected void checkContentLanguage(Blob blob, String contentLanguage) { + assert blob.getPayload().getContentMetadata().getContentLanguage() == null; + assert blob.getMetadata().getContentMetadata().getContentLanguage() == null; + } + + // double range not supported + @Test(groups = { "integration", "live" }) + @Override + public void testGetTwoRanges() throws InterruptedException, IOException { + + } + + // range not supported + @Test(groups = { "integration", "live" }) + @Override + public void testGetRange() throws InterruptedException, IOException { + } } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobLiveTest.java index 26473d2c10..75dc0cec0e 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobLiveTest.java @@ -19,13 +19,13 @@ package org.jclouds.walrus.blobstore; -import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest; +import org.jclouds.s3.blobstore.integration.S3BlobLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "WalrusBlobLiveTest") -public class WalrusBlobLiveTest extends BaseBlobLiveTest { +public class WalrusBlobLiveTest extends S3BlobLiveTest { } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobMapIntegrationLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobMapIntegrationLiveTest.java index 9e5e4966a8..ade5069f70 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobMapIntegrationLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobMapIntegrationLiveTest.java @@ -19,13 +19,13 @@ package org.jclouds.walrus.blobstore; -import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest; +import org.jclouds.s3.blobstore.integration.S3BlobMapIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "WalrusBlobMapIntegrationLiveTest") -public class WalrusBlobMapIntegrationLiveTest extends BaseBlobMapIntegrationTest { +public class WalrusBlobMapIntegrationLiveTest extends S3BlobMapIntegrationLiveTest { } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobSignerLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobSignerLiveTest.java index aa8a20ec47..1cdcab7280 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobSignerLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusBlobSignerLiveTest.java @@ -19,7 +19,7 @@ package org.jclouds.walrus.blobstore; -import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest; +import org.jclouds.s3.blobstore.integration.S3BlobSignerLiveTest; import org.testng.annotations.Test; /** @@ -27,6 +27,6 @@ import org.testng.annotations.Test; * @author Adrian Cole */ @Test(groups = "live", testName = "WalrusBlobSignerLiveTest") -public class WalrusBlobSignerLiveTest extends BaseBlobSignerLiveTest { +public class WalrusBlobSignerLiveTest extends S3BlobSignerLiveTest { } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerIntegrationLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerIntegrationLiveTest.java index 39c47ed82f..3e38fd5031 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerIntegrationLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerIntegrationLiveTest.java @@ -19,13 +19,13 @@ package org.jclouds.walrus.blobstore; -import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest; +import org.jclouds.s3.blobstore.integration.S3ContainerIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "WalrusContainerIntegrationLiveTest") -public class WalrusContainerIntegrationLiveTest extends BaseContainerIntegrationTest { +public class WalrusContainerIntegrationLiveTest extends S3ContainerIntegrationLiveTest { } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerLiveTest.java index ad39f9eb7c..e4ea2231a2 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusContainerLiveTest.java @@ -19,13 +19,13 @@ package org.jclouds.walrus.blobstore; -import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest; +import org.jclouds.s3.blobstore.integration.S3ContainerLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "WalrusContainerLiveTest") -public class WalrusContainerLiveTest extends BaseContainerLiveTest { +public class WalrusContainerLiveTest extends S3ContainerLiveTest { } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusInputStreamMapIntegrationLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusInputStreamMapIntegrationLiveTest.java index d861cac1e1..26795181bd 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusInputStreamMapIntegrationLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusInputStreamMapIntegrationLiveTest.java @@ -19,13 +19,13 @@ package org.jclouds.walrus.blobstore; -import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest; +import org.jclouds.s3.blobstore.integration.S3InputStreamMapIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "WalrusInputStreamMapIntegrationLiveTest") -public class WalrusInputStreamMapIntegrationLiveTest extends BaseInputStreamMapIntegrationTest { +public class WalrusInputStreamMapIntegrationLiveTest extends S3InputStreamMapIntegrationLiveTest { } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusServiceIntegrationLiveTest.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusServiceIntegrationLiveTest.java index 90c612cbf9..4b02493cf2 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusServiceIntegrationLiveTest.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusServiceIntegrationLiveTest.java @@ -19,13 +19,13 @@ package org.jclouds.walrus.blobstore; -import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest; +import org.jclouds.s3.blobstore.integration.S3ServiceIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "WalrusServiceIntegrationLiveTest") -public class WalrusServiceIntegrationLiveTest extends BaseServiceIntegrationTest { +public class WalrusServiceIntegrationLiveTest extends S3ServiceIntegrationLiveTest { } diff --git a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusTestInitializer.java b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusTestInitializer.java index 78eb23c1b9..3d729d9a29 100644 --- a/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusTestInitializer.java +++ b/apis/walrus/src/test/java/org/jclouds/walrus/blobstore/WalrusTestInitializer.java @@ -19,33 +19,18 @@ package org.jclouds.walrus.blobstore; -import java.io.IOException; +import org.jclouds.s3.blobstore.integration.S3TestInitializer; -import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.blobstore.BlobStoreContextFactory; -import org.jclouds.blobstore.integration.TransientBlobStoreTestInitializer; -import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; -import org.jclouds.logging.log4j.config.Log4JLoggingModule; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; /** * * @author Adrian Cole */ -public class WalrusTestInitializer extends TransientBlobStoreTestInitializer { +public class WalrusTestInitializer extends S3TestInitializer { public WalrusTestInitializer() { provider = "walrus"; - BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true; } - @Override - protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion, - String app, String identity, String credential) throws IOException { - return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule, - new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential)); - } } diff --git a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml index 7acd80c5db..2c319eeaf9 100644 --- a/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/compute-service-archetype/src/main/resources/archetype-resources/pom.xml @@ -100,7 +100,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml b/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml index 18909aa382..8a5ff66f0f 100644 --- a/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml +++ b/archetypes/rest-client-archetype/src/main/resources/archetype-resources/pom.xml @@ -82,7 +82,7 @@ $symbol_dollar = '$' ) log4j log4j - 1.2.14 + 1.2.16 test diff --git a/assemblies/src/main/resources/assemblies/jar-with-dependencies-descriptor.xml b/assemblies/src/main/resources/assemblies/jar-with-dependencies-descriptor.xml index e55eb314bb..e07c7fcda0 100644 --- a/assemblies/src/main/resources/assemblies/jar-with-dependencies-descriptor.xml +++ b/assemblies/src/main/resources/assemblies/jar-with-dependencies-descriptor.xml @@ -29,13 +29,6 @@ true runtime - - org.jclouds:jclouds-core - org.jclouds:jclouds-blobstore - org.jclouds:jclouds-compute - - - true @@ -43,13 +36,5 @@ ${project.build.outputDirectory} - - - - pom.xml - - META-INF/maven/${project.groupId}/${project.artifactId} - - + \ No newline at end of file diff --git a/assemblies/src/main/resources/assemblies/jar-with-dependencies-no-core-no-apis-descriptor.xml b/assemblies/src/main/resources/assemblies/jar-with-dependencies-no-core-no-apis-descriptor.xml new file mode 100644 index 0000000000..b4bc50aa95 --- /dev/null +++ b/assemblies/src/main/resources/assemblies/jar-with-dependencies-no-core-no-apis-descriptor.xml @@ -0,0 +1,60 @@ + + + + jar-with-dependencies + + jar + + false + + + true + runtime + + org.jclouds:jclouds-core + org.jclouds:jclouds-blobstore + org.jclouds:jclouds-compute + org.jclouds:jclouds-loadbalancer + org.jclouds.api:* + + org.clojure:clojure* + + + true + false + + + + + ${project.build.outputDirectory} + + + + + + pom.xml + + META-INF/maven/${project.groupId}/${project.artifactId} + + + diff --git a/assemblies/src/main/resources/assemblies/package-descriptor.xml b/assemblies/src/main/resources/assemblies/package-descriptor.xml index b27ad79fda..8374ec8b8d 100644 --- a/assemblies/src/main/resources/assemblies/package-descriptor.xml +++ b/assemblies/src/main/resources/assemblies/package-descriptor.xml @@ -28,39 +28,29 @@ LICENSE.txt README.txt core - + docs <- javadoc for core, blobstore, and compute - + lib <- core, blobstore, and compute jars and dependencies for core - + src <- expanded or source jar for core, blobstore, and compute - profiles - + enterprise - + README.txt <- how to use the profile - + lib <- not core - + docs <- not core - + src <- not core - extensions + + lib <- core, blobstore, compute (w/scriptbuilder) and loadbalancer JARs and dependencies for core + + docs <- javadoc for core, blobstore, compute and loadbalancer + + src <- expanded or source jar for core, blobstore, compute and loadbalancer + drivers + log4j - + README.txt <- how to use the extension - + lib <- not core - + docs <- not core - + src <- not core + + README.txt <- how to use the driver + + lib <- excl. core + + docs <- excl. core + + src <- excl. core + apis + + s3 + + README.txt <- status of this API + + lib <- excl. core + + docs <- excl. core + + src <- excl. core providers - + rackspace + + trmk-vcloudexpress + README.txt <- status of this provider (what is implemented/not implemented) - + lib <- not core - + docs <- not core - + src <- not core - tools <- integrations with other tools - + antcontrib - + README.txt <- how to use the tool - + lib <- not core - + docs <- not core - + src <- not core - samples <- includes samples and demos - + tweetstore - + README.txt <- how to build and run the sample - + src <- just demo + + lib <- excl. core and implemented API(s) + + docs <- excl. core and implemented API(s) + + src <- excl. core and implemented API(s) - see http://code.google.com/p/jclouds/issues/detail?id=127 + see http://code.google.com/p/jclouds/issues/detail?id=458 --> @@ -77,6 +67,7 @@ LICENSE.txt true + @@ -94,6 +85,13 @@ core/lib + + scriptbuilder/target + + jclouds-scriptbuilder-${project.version}.jar + + core/lib + compute/target @@ -101,6 +99,13 @@ core/lib + + loadbalancer/target + + jclouds-loadbalancer-${project.version}.jar + + core/lib + core/target @@ -115,6 +120,13 @@ core/src + + scriptbuilder/target + + jclouds-scriptbuilder-${project.version}-sources.jar + + core/src + compute/target @@ -122,6 +134,13 @@ core/src + + loadbalancer/target + + jclouds-loadbalancer-${project.version}-sources.jar + + core/src + core/target/apidocs core/docs @@ -130,537 +149,1321 @@ blobstore/target/apidocs core/docs + + scriptbuilder/target/apidocs + core/docs + compute/target/apidocs core/docs + + loadbalancer/target/apidocs + core/docs + - + - atmos/target + drivers/apachehc/target - jclouds-atmos-${project.version}.jar + jclouds-apachehc-${project.version}-jar-with-dependencies.jar - providers/atmos/lib + drivers/apachehc/lib - atmos/target + drivers/apachehc/target/jclouds-apachehc-${project.version}-provided-dependencies - jclouds-atmos-${project.version}-sources.jar + *.jar - providers/atmos/src + drivers/apachehc/lib - atmos/target/apidocs - providers/atmos/docs + drivers/apachehc/target + + jclouds-apachehc-${project.version}-sources.jar + + drivers/apachehc/src + + + drivers/apachehc/target/apidocs + drivers/apachehc/docs + + + drivers/apachehc + + README.txt + + drivers/apachehc + + + + + drivers/bouncycastle/target + + jclouds-bouncycastle-${project.version}-jar-with-dependencies.jar + + drivers/bouncycastle/lib + + + drivers/bouncycastle/target/jclouds-bouncycastle-${project.version}-provided-dependencies + + *.jar + + drivers/bouncycastle/lib + + + drivers/bouncycastle/target + + jclouds-bouncycastle-${project.version}-sources.jar + + drivers/bouncycastle/src + + + drivers/bouncycastle/target/apidocs + drivers/bouncycastle/docs + + + drivers/bouncycastle + + README.txt + + drivers/bouncycastle + + + + + drivers/enterprise/target + + jclouds-enterprise-${project.version}-jar-with-dependencies.jar + + drivers/enterprise/lib + + + drivers/enterprise/target + + jclouds-enterprise-${project.version}-sources.jar + + drivers/enterprise/src + + + drivers/enterprise/target/apidocs + drivers/enterprise/docs + + + drivers/enterprise + + README.txt + + drivers/enterprise + + + + + drivers/gae/target + + jclouds-gae-${project.version}-jar-with-dependencies.jar + + drivers/gae/lib + + + drivers/gae/target + + jclouds-gae-${project.version}-sources.jar + + drivers/gae/src + + + drivers/gae/target/apidocs + drivers/gae/docs + + + drivers/gae + + README.txt + + drivers/gae + + + + + drivers/joda/target + + jclouds-joda-${project.version}-jar-with-dependencies.jar + + drivers/joda/lib + + + drivers/joda/target/jclouds-joda-${project.version}-provided-dependencies + + *.jar + + drivers/joda/lib + + + drivers/joda/target + + jclouds-joda-${project.version}-sources.jar + + drivers/joda/src + + + drivers/joda/target/apidocs + drivers/joda/docs + + + drivers/joda + + README.txt + + drivers/joda + + + + + drivers/jsch/target + + jclouds-jsch-${project.version}-jar-with-dependencies.jar + + drivers/jsch/lib + + + drivers/jsch/target/jclouds-jsch-${project.version}-provided-dependencies + + *.jar + + drivers/jsch/lib + + + drivers/jsch/target + + jclouds-jsch-${project.version}-sources.jar + + drivers/jsch/src + + + drivers/jsch/target/apidocs + drivers/jsch/docs + + + drivers/jsch + + README.txt + + drivers/jsch + + + + + drivers/log4j/target + + jclouds-log4j-${project.version}-jar-with-dependencies.jar + + drivers/log4j/lib + + + drivers/log4j/target/jclouds-log4j-${project.version}-provided-dependencies + + *.jar + + drivers/log4j/lib + + + drivers/log4j/target + + jclouds-log4j-${project.version}-sources.jar + + drivers/log4j/src + + + drivers/log4j/target/apidocs + drivers/log4j/docs + + + drivers/log4j + + README.txt + + drivers/log4j + + + + + apis/atmos/target + + atmos-${project.version}-jar-with-dependencies.jar + + apis/atmos/lib + + + apis/atmos/target + + atmos-${project.version}-sources.jar + + apis/atmos/src + + + apis/atmos/target/apidocs + apis/atmos/docs - atmos + apis/atmos README.txt - providers/atmos - - - - - aws/core/target - - jclouds-aws-${project.version}.jar - - providers/aws/lib - - - aws/core/target - - jclouds-aws-${project.version}-sources.jar - - providers/aws/src - - - aws/core/target/apidocs - providers/aws/docs - - - aws/core - - README.txt - - providers/aws - - - - - azure/target - - jclouds-azure-${project.version}.jar - - providers/azure/lib - - - azure/target - - jclouds-azure-${project.version}-sources.jar - - providers/azure/src - - - azure/target/apidocs - providers/azure/docs - - - azure - - README.txt - - providers/azure + apis/atmos - + - slicehost/target + apis/byon/target - jclouds-slicehost-${project.version}.jar + byon-${project.version}-jar-with-dependencies.jar - providers/slicehost/lib + apis/byon/lib - slicehost/target + apis/byon/target - jclouds-slicehost-${project.version}-sources.jar + byon-${project.version}-sources.jar - providers/slicehost/src + apis/byon/src - slicehost/target/apidocs - providers/slicehost/docs - + apis/byon/target/apidocs + apis/byon/docs + - slicehost + apis/byon README.txt - providers/slicehost - + apis/byon + - + - rackspace/target + apis/cloudfiles/target - jclouds-rackspace-${project.version}.jar + cloudfiles-${project.version}-jar-with-dependencies.jar - providers/rackspace/lib + apis/cloudfiles/lib - rackspace/target + apis/cloudfiles/target - jclouds-rackspace-${project.version}-sources.jar + cloudfiles-${project.version}-sources.jar - providers/rackspace/src + apis/cloudfiles/src - rackspace/target/apidocs - providers/rackspace/docs - + apis/cloudfiles/target/apidocs + apis/cloudfiles/docs + - rackspace + apis/cloudfiles README.txt - providers/rackspace - + apis/cloudfiles + + + + + apis/cloudservers/target + + cloudservers-${project.version}-jar-with-dependencies.jar + + apis/cloudservers/lib + + + apis/cloudservers/target + + cloudservers-${project.version}-sources.jar + + apis/cloudservers/src + + + apis/cloudservers/target/apidocs + apis/cloudservers/docs + + + apis/cloudservers + + README.txt + + apis/cloudservers + + + + + apis/ec2/target + + ec2-${project.version}-jar-with-dependencies.jar + + apis/ec2/lib + + + apis/ec2/target + + ec2-${project.version}-sources.jar + + apis/ec2/src + + + apis/ec2/target/apidocs + apis/ec2/docs + + + apis/ec2 + + README.txt + + apis/ec2 + + + + + elasticstack/target + + elasticstack-${project.version}-jar-with-dependencies.jar + + apis/elasticstack/lib + + + elasticstack/target + + elasticstack-${project.version}-sources.jar + + apis/elasticstack/src + + + elasticstack/target/apidocs + apis/elasticstack/docs + + + elasticstack + + README.txt + + apis/elasticstack + + + + + apis/elb/target + + elb-${project.version}-jar-with-dependencies.jar + + apis/elb/lib + + + apis/elb/target + + elb-${project.version}-sources.jar + + apis/elb/src + + + apis/elb/target/apidocs + apis/elb/docs + + + apis/elb + + README.txt + + apis/elb + + + + + apis/eucalyptus/target + + eucalyptus-${project.version}-jar-with-dependencies.jar + + apis/eucalyptus/lib + + + apis/eucalyptus/target + + eucalyptus-${project.version}-sources.jar + + apis/eucalyptus/src + + + apis/eucalyptus/target/apidocs + apis/eucalyptus/docs + + + apis/eucalyptus + + README.txt + + apis/eucalyptus + + + + + apis/filesystem/target + + filesystem-${project.version}-jar-with-dependencies.jar + + apis/filesystem/lib + + + apis/filesystem/target + + filesystem-${project.version}-sources.jar + + apis/filesystem/src + + + apis/filesystem/target/apidocs + apis/filesystem/docs + + + apis/filesystem + + README.txt + + apis/filesystem + + + + + apis/s3/target + + s3-${project.version}-jar-with-dependencies.jar + + apis/s3/lib + + + apis/s3/target + + s3-${project.version}-sources.jar + + apis/s3/src + + + apis/s3/target/apidocs + apis/s3/docs + + + apis/s3 + + README.txt + + apis/s3 + + + + + apis/swift/target + + swift-${project.version}-jar-with-dependencies.jar + + apis/swift/lib + + + apis/swift/target + + swift-${project.version}-sources.jar + + apis/swift/src + + + apis/swift/target/apidocs + apis/swift/docs + + + apis/swift + + README.txt + + apis/swift + + + + + apis/vcloud/target + + vcloud-${project.version}-jar-with-dependencies.jar + + apis/vcloud/lib + + + apis/vcloud/target + + vcloud-${project.version}-sources.jar + + apis/vcloud/src + + + apis/vcloud/target/apidocs + apis/vcloud/docs + + + apis/vcloud + + README.txt + + apis/vcloud + + + + + apis/vcloudexpress/target + + vcloudexpress-${project.version}-jar-with-dependencies.jar + + apis/vcloudexpress/lib + + + apis/vcloudexpress/target + + vcloudexpress-${project.version}-sources.jar + + apis/vcloudexpress/src + + + apis/vcloudexpress/target/apidocs + apis/vcloudexpress/docs + + + apis/vcloudexpress + + README.txt + + apis/vcloudexpress + + + + + apis/walrus/target + + walrus-${project.version}-jar-with-dependencies.jar + + apis/walrus/lib + + + apis/walrus/target + + walrus-${project.version}-sources.jar + + apis/walrus/src + + + apis/walrus/target/apidocs + apis/walrus/docs + + + apis/walrus + + README.txt + + apis/walrus + + + + + providers/aws-ec2/target + + aws-ec2-${project.version}-jar-with-dependencies.jar + + providers/aws-ec2/lib + + + providers/aws-ec2/target + + aws-ec2-${project.version}-sources.jar + + providers/aws-ec2/src + + + providers/aws-ec2/target/apidocs + providers/aws-ec2/docs + + + providers/aws-ec2 + + README.txt + + providers/aws-ec2 + + + + + providers/aws-elb/target + + aws-elb-${project.version}-jar-with-dependencies.jar + + providers/aws-elb/lib + + + providers/aws-elb/target + + aws-elb-${project.version}-sources.jar + + providers/aws-elb/src + + + providers/aws-elb/target/apidocs + providers/aws-elb/docs + + + providers/aws-elb + + README.txt + + providers/aws-elb + + + + + providers/aws-s3/target + + aws-s3-${project.version}-jar-with-dependencies.jar + + providers/aws-s3/lib + + + providers/aws-s3/target + + aws-s3-${project.version}-sources.jar + + providers/aws-s3/src + + + providers/aws-s3/target/apidocs + providers/aws-s3/docs + + + providers/aws-s3 + + README.txt + + providers/aws-s3 + + + + + providers/azureblob/target + + azureblob-${project.version}-jar-with-dependencies.jar + + providers/azureblob/lib + + + providers/azureblob/target + + azureblob-${project.version}-sources.jar + + providers/azureblob/src + + + providers/azureblob/target/apidocs + providers/azureblob/docs + + + providers/azureblob + + README.txt + + providers/azureblob + + + + + providers/bluelock-vcdirector/target + + bluelock-vcdirector-${project.version}-jar-with-dependencies.jar + + providers/bluelock-vcdirector/lib + + + providers/bluelock-vcdirector/target + + bluelock-vcdirector-${project.version}-sources.jar + + providers/bluelock-vcdirector/src + + + providers/bluelock-vcdirector/target/apidocs + providers/bluelock-vcdirector/docs + + + providers/bluelock-vcdirector + + README.txt + + providers/bluelock-vcdirector + + + + + providers/cloudfiles-uk/target + + cloudfiles-uk-${project.version}-jar-with-dependencies.jar + + providers/cloudfiles-uk/lib + + + providers/cloudfiles-uk/target + + cloudfiles-uk-${project.version}-sources.jar + + providers/cloudfiles-uk/src + + + providers/cloudfiles-uk/target/apidocs + providers/cloudfiles-uk/docs + + + providers/cloudfiles-uk + + README.txt + + providers/cloudfiles-uk + + + + + providers/cloudfiles-us/target + + cloudfiles-us-${project.version}-jar-with-dependencies.jar + + providers/cloudfiles-us/lib + + + providers/cloudfiles-us/target + + cloudfiles-us-${project.version}-sources.jar + + providers/cloudfiles-us/src + + + providers/cloudfiles-us/target/apidocs + providers/cloudfiles-us/docs + + + providers/cloudfiles-us + + README.txt + + providers/cloudfiles-us + + + + + providers/cloudonestorage/target + + cloudonestorage-${project.version}-jar-with-dependencies.jar + + providers/cloudonestorage/lib + + + providers/cloudonestorage/target + + cloudonestorage-${project.version}-sources.jar + + providers/cloudonestorage/src + + + providers/cloudonestorage/target/apidocs + providers/cloudonestorage/docs + + + providers/cloudonestorage + + README.txt + + providers/cloudonestorage + + + + + providers/cloudservers-uk/target + + cloudservers-uk-${project.version}-jar-with-dependencies.jar + + providers/cloudservers-uk/lib + + + providers/cloudservers-uk/target + + cloudservers-uk-${project.version}-sources.jar + + providers/cloudservers-uk/src + + + providers/cloudservers-uk/target/apidocs + providers/cloudservers-uk/docs + + + providers/cloudservers-uk + + README.txt + + providers/cloudservers-uk + + + + + providers/cloudservers-us/target + + cloudservers-us-${project.version}-jar-with-dependencies.jar + + providers/cloudservers-us/lib + + + providers/cloudservers-us/target + + cloudservers-us-${project.version}-sources.jar + + providers/cloudservers-us/src + + + providers/cloudservers-us/target/apidocs + providers/cloudservers-us/docs + + + providers/cloudservers-us + + README.txt + + providers/cloudservers-us + + + + + providers/cloudsigma-zrh/target + + cloudsigma-zrh-${project.version}-jar-with-dependencies.jar + + providers/cloudsigma-zrh/lib + + + providers/cloudsigma-zrh/target + + cloudsigma-zrh-${project.version}-sources.jar + + providers/cloudsigma-zrh/src + + + providers/cloudsigma-zrh/target/apidocs + providers/cloudsigma-zrh/docs + + + providers/cloudsigma-zrh + + README.txt + + providers/cloudsigma-zrh + + + + + providers/elastichosts-lon-b/target + + elastichosts-lon-b-${project.version}-jar-with-dependencies.jar + + providers/elastichosts-lon-b/lib + + + providers/elastichosts-lon-b/target + + elastichosts-lon-b-${project.version}-sources.jar + + providers/elastichosts-lon-b/src + + + providers/elastichosts-lon-b/target/apidocs + providers/elastichosts-lon-b/docs + + + providers/elastichosts-lon-b + + README.txt + + providers/elastichosts-lon-b + + + + + providers/elastichosts-lon-p/target + + elastichosts-lon-p-${project.version}-jar-with-dependencies.jar + + providers/elastichosts-lon-p/lib + + + providers/elastichosts-lon-p/target + + elastichosts-lon-p-${project.version}-sources.jar + + providers/elastichosts-lon-p/src + + + providers/elastichosts-lon-p/target/apidocs + providers/elastichosts-lon-p/docs + + + providers/elastichosts-lon-p + + README.txt + + providers/elastichosts-lon-p + + + + + providers/elastichosts-sat-p/target + + elastichosts-sat-p-${project.version}-jar-with-dependencies.jar + + providers/elastichosts-sat-p/lib + + + providers/elastichosts-sat-p/target + + elastichosts-sat-p-${project.version}-sources.jar + + providers/elastichosts-sat-p/src + + + providers/elastichosts-sat-p/target/apidocs + providers/elastichosts-sat-p/docs + + + providers/elastichosts-sat-p + + README.txt + + providers/elastichosts-sat-p + + + + + providers/eucalyptus-partnercloud-ec2/target + + eucalyptus-partnercloud-ec2-${project.version}-jar-with-dependencies.jar + + providers/eucalyptus-partnercloud-ec2/lib + + + providers/eucalyptus-partnercloud-ec2/target + + eucalyptus-partnercloud-ec2-${project.version}-sources.jar + + providers/eucalyptus-partnercloud-ec2/src + + + providers/eucalyptus-partnercloud-ec2/target/apidocs + providers/eucalyptus-partnercloud-ec2/docs + + + providers/eucalyptus-partnercloud-ec2 + + README.txt + + providers/eucalyptus-partnercloud-ec2 + + + + + providers/eucalyptus-partnercloud-s3/target + + eucalyptus-partnercloud-s3-${project.version}-jar-with-dependencies.jar + + providers/eucalyptus-partnercloud-s3/lib + + + providers/eucalyptus-partnercloud-s3/target + + eucalyptus-partnercloud-s3-${project.version}-sources.jar + + providers/eucalyptus-partnercloud-s3/src + + + providers/eucalyptus-partnercloud-s3/target/apidocs + providers/eucalyptus-partnercloud-s3/docs + + + providers/eucalyptus-partnercloud-s3 + + README.txt + + providers/eucalyptus-partnercloud-s3 + - gogrid/target + providers/gogrid/target - jclouds-gogrid-${project.version}.jar + gogrid-${project.version}-jar-with-dependencies.jar providers/gogrid/lib - gogrid/target + providers/gogrid/target - jclouds-gogrid-${project.version}-sources.jar + gogrid-${project.version}-sources.jar providers/gogrid/src - gogrid/target/apidocs + providers/gogrid/target/apidocs providers/gogrid/docs - + - gogrid + providers/gogrid README.txt providers/gogrid - - - - - rimuhosting/target - - jclouds-rimuhosting-${project.version}.jar - - providers/rimuhosting/lib - - - rimuhosting/target - - jclouds-rimuhosting-${project.version}-sources.jar - - providers/rimuhosting/src - - - rimuhosting/target/apidocs - providers/rimuhosting/docs - - - rimuhosting - - README.txt - - providers/rimuhosting - - - - - vcloud/core/target - - jclouds-vcloud-${project.version}.jar - - providers/vcloud/lib - - - vcloud/core/target - - jclouds-vcloud-${project.version}-sources.jar - - providers/vcloud/src - - - vcloud/vcloud/target/apidocs - providers/vcloud/docs - - - vcloud/core - - README.txt - - providers/vcloud - + - vcloud/core/target + providers/googlestorage/target - jclouds-vcloud-${project.version}.jar + googlestorage-${project.version}-jar-with-dependencies.jar - providers/bluelock/lib + providers/googlestorage/lib - vcloud/core/target + providers/googlestorage/target - jclouds-vcloud-${project.version}-sources.jar + googlestorage-${project.version}-sources.jar - providers/bluelock/src + providers/googlestorage/src - vcloud/bluelock/target - - jclouds-bluelock-${project.version}.jar - - providers/bluelock/lib - + providers/googlestorage/target/apidocs + providers/googlestorage/docs + - vcloud/bluelock/target - - jclouds-bluelock-${project.version}-sources.jar - - providers/bluelock/src - - - vcloud/bluelock/target/apidocs - providers/bluelock/docs - - - vcloud/bluelock + providers/googlestorage README.txt - providers/bluelock + providers/googlestorage - + - vcloud/core/target + providers/openhosting-east1/target - jclouds-vcloud-${project.version}.jar + openhosting-east1-${project.version}-jar-with-dependencies.jar - providers/terremark/lib + providers/openhosting-east1/lib - vcloud/core/target + providers/openhosting-east1/target - jclouds-vcloud-${project.version}-sources.jar + openhosting-east1-${project.version}-sources.jar - providers/terremark/src + providers/openhosting-east1/src - vcloud/terremark/target - - jclouds-terremark-${project.version}.jar - - providers/terremark/lib - + providers/openhosting-east1/target/apidocs + providers/openhosting-east1/docs + - vcloud/terremark/target - - jclouds-terremark-${project.version}-sources.jar - - providers/terremark/src - - - vcloud/terremark/target/apidocs - providers/terremark/docs - - - vcloud/terremark + providers/openhosting-east1 README.txt - providers/terremark + providers/openhosting-east1 - + - extensions/bouncycastle/target + providers/scaleup-storage/target - jclouds-bouncycastle-${project.version}-jar-with-dependencies.jar + scaleup-storage-${project.version}-jar-with-dependencies.jar - extensions/bouncycastle/lib + providers/scaleup-storage/lib - extensions/bouncycastle/target + providers/scaleup-storage/target - jclouds-bouncycastle-${project.version}-sources.jar + scaleup-storage-${project.version}-sources.jar - extensions/bouncycastle/src + providers/scaleup-storage/src - extensions/bouncycastle/target/apidocs - extensions/bouncycastle/docs - + providers/scaleup-storage/target/apidocs + providers/scaleup-storage/docs + - extensions/bouncycastle + providers/scaleup-storage README.txt - extensions/bouncycastle - - - + providers/scaleup-storage + + + - extensions/enterprise/target + providers/serverlove-z1-man/target - jclouds-enterprise-${project.version}-jar-with-dependencies.jar + serverlove-z1-man-${project.version}-jar-with-dependencies.jar - extensions/enterprise/lib + providers/serverlove-z1-man/lib - extensions/enterprise/target + providers/serverlove-z1-man/target - jclouds-enterprise-${project.version}-sources.jar + serverlove-z1-man-${project.version}-sources.jar - extensions/enterprise/src + providers/serverlove-z1-man/src - extensions/enterprise/target/apidocs - extensions/enterprise/docs - + providers/serverlove-z1-man/target/apidocs + providers/serverlove-z1-man/docs + - extensions/enterprise + providers/serverlove-z1-man README.txt - extensions/enterprise - - - + providers/serverlove-z1-man + + + - extensions/gae/target + providers/skalicloud-sdg-my/target - jclouds-gae-${project.version}.jar + skalicloud-sdg-my-${project.version}-jar-with-dependencies.jar - extensions/gae/lib + providers/skalicloud-sdg-my/lib - extensions/gae/target + providers/skalicloud-sdg-my/target - jclouds-gae-${project.version}-sources.jar + skalicloud-sdg-my-${project.version}-sources.jar - extensions/gae/src + providers/skalicloud-sdg-my/src - extensions/gae/target/apidocs - extensions/gae/docs - + providers/skalicloud-sdg-my/target/apidocs + providers/skalicloud-sdg-my/docs + - extensions/gae + providers/skalicloud-sdg-my README.txt - extensions/gae - - - - - extensions/joda/target - - jclouds-joda-${project.version}-jar-with-dependencies.jar - - extensions/joda/lib - - - extensions/joda/target - - jclouds-joda-${project.version}-sources.jar - - extensions/joda/src - - - extensions/joda/target/apidocs - extensions/joda/docs - - - extensions/joda - - README.txt - - extensions/joda - - - - - extensions/apachehc/target - - jclouds-apachehc-${project.version}.jar - - extensions/apachehc/lib - - - extensions/apachehc/target - - jclouds-apachehc-${project.version}-sources.jar - - extensions/apachehc/src - - - extensions/apachehc/target/apidocs - extensions/apachehc/docs - - - extensions/apachehc - - README.txt - - extensions/apachehc + providers/skalicloud-sdg-my - + - extensions/ssh/jsch/target + providers/slicehost/target - jclouds-jsch-${project.version}.jar + slicehost-${project.version}-jar-with-dependencies.jar - extensions/jsch/lib + providers/slicehost/lib - extensions/ssh/jsch/target + providers/slicehost/target - jclouds-jsch-${project.version}-sources.jar + slicehost-${project.version}-sources.jar - extensions/jsch/src + providers/slicehost/src - extensions/ssh/jsch/target/apidocs - extensions/jsch/docs - + providers/slicehost/target/apidocs + providers/slicehost/docs + - extensions/ssh/jsch + providers/slicehost README.txt - extensions/jsch + providers/slicehost + + + + + providers/synaptic-storage/target + + synaptic-storage-${project.version}-jar-with-dependencies.jar + + providers/synaptic-storage/lib + + + providers/synaptic-storage/target + + synaptic-storage-${project.version}-sources.jar + + providers/synaptic-storage/src + + + providers/synaptic-storage/target/apidocs + providers/synaptic-storage/docs + + + providers/synaptic-storage + + README.txt + + providers/synaptic-storage - + - extensions/log4j/target + providers/trmk-ecloud/target - jclouds-log4j-${project.version}.jar + trmk-ecloud-${project.version}-jar-with-dependencies.jar - extensions/log4j/lib + providers/trmk-ecloud/lib - extensions/log4j/target + providers/trmk-ecloud/target - jclouds-log4j-${project.version}-sources.jar + trmk-ecloud-${project.version}-sources.jar - extensions/log4j/src + providers/trmk-ecloud/src - extensions/log4j/target/apidocs - extensions/log4j/docs - + providers/trmk-ecloud/target/apidocs + providers/trmk-ecloud/docs + - extensions/log4j + providers/trmk-ecloud README.txt - extensions/log4j - - - - - tools/antcontrib/target - - jclouds-antcontrib-${project.version}-jar-with-dependencies.jar - - tools/antcontrib/lib - - - tools/antcontrib/target - - jclouds-antcontrib-${project.version}-sources.jar - - tools/antcontrib/src - - - tools/antcontrib/target/apidocs - tools/antcontrib/docs - - - tools/antcontrib - - README.txt - - tools/antcontrib - + providers/trmk-ecloud + - + - demos/gae-tweetstore/target/jclouds-demo-gae-tweetstore - samples/gae-tweetstore + providers/trmk-vcloudexpress/target + + trmk-vcloudexpress-${project.version}-jar-with-dependencies.jar + + providers/trmk-vcloudexpress/lib - aws/demos/createandlistbuckets/target/jclouds-aws-demo-createandlistbuckets-src - samples/aws/createandlistbuckes + providers/trmk-vcloudexpress/target + + trmk-vcloudexpress-${project.version}-sources.jar + + providers/trmk-vcloudexpress/src - aws/demos/googleappengine/target/jclouds-aws-demo-googleappengine-src - samples/aws/googleappengine - - + providers/trmk-vcloudexpress/target/apidocs + providers/trmk-vcloudexpress/docs + + + providers/trmk-vcloudexpress + + README.txt + + providers/trmk-vcloudexpress + + diff --git a/assemblies/src/main/resources/assemblies/core-jar-with-dependencies-descriptor.xml b/assemblies/src/main/resources/assemblies/provided-dependencies-descriptor.xml similarity index 67% rename from assemblies/src/main/resources/assemblies/core-jar-with-dependencies-descriptor.xml rename to assemblies/src/main/resources/assemblies/provided-dependencies-descriptor.xml index e07c7fcda0..3e7784bbe5 100644 --- a/assemblies/src/main/resources/assemblies/core-jar-with-dependencies-descriptor.xml +++ b/assemblies/src/main/resources/assemblies/provided-dependencies-descriptor.xml @@ -1,40 +1,44 @@ - - - - jar-with-dependencies - - jar - - false - - - true - runtime - - - - - ${project.build.outputDirectory} - - - - \ No newline at end of file + + + + provided-dependencies + + dir + + false + + + provided + false + + + + + + + pom.xml + + META-INF/maven/${project.groupId}/${project.artifactId} + + + diff --git a/blobstore/src/main/clojure/org/jclouds/blobstore.clj b/blobstore/src/main/clojure/org/jclouds/blobstore.clj index a69676aea0..d48034cac6 100644 --- a/blobstore/src/main/clojure/org/jclouds/blobstore.clj +++ b/blobstore/src/main/clojure/org/jclouds/blobstore.clj @@ -21,7 +21,7 @@ "A clojure binding for the jclouds BlobStore. Current supported services are: - [transient, filesystem, s3, azureblob, atmos, cloudfiles, walrus, + [transient, filesystem, azureblob, atmos, walrus, scaleup-storage, googlestorage, synaptic, peer1-storage, aws-s3, eucalyptus-partnercloud-s3, cloudfiles-us, cloudfiles-uk, swift] diff --git a/blobstore/src/main/java/org/jclouds/blobstore/AsyncBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/AsyncBlobStore.java index 73516b2c79..c71c81ab72 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/AsyncBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/AsyncBlobStore.java @@ -24,6 +24,7 @@ import java.util.Set; import javax.annotation.Nullable; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; @@ -47,8 +48,14 @@ public interface AsyncBlobStore { /** * @see BlobStore#newBlob */ + @Deprecated Blob newBlob(String name); + /** + * @see BlobStore#blobBuilder + */ + BlobBuilder blobBuilder(String name); + /** * @see BlobStore#listAssignableLocations */ diff --git a/blobstore/src/main/java/org/jclouds/blobstore/BlobMap.java b/blobstore/src/main/java/org/jclouds/blobstore/BlobMap.java index 03cbbedc6a..03db0199fd 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/BlobMap.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/BlobMap.java @@ -20,6 +20,7 @@ package org.jclouds.blobstore; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.internal.BlobMapImpl; import org.jclouds.blobstore.options.ListContainerOptions; @@ -34,9 +35,19 @@ import com.google.inject.ImplementedBy; */ @ImplementedBy(BlobMapImpl.class) public interface BlobMap extends ListableMap { - + /** + * @see #blobBuilder + * @param name + */ + @Deprecated Blob newBlob(String name); + /** + * + * @return builder for creating new {@link Blob}s + */ + BlobBuilder blobBuilder(); + public static interface Factory { BlobMap create(String containerName, ListContainerOptions options); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java index 392f3c5462..82bd9961e1 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/BlobStore.java @@ -24,6 +24,7 @@ import java.util.Set; import javax.annotation.Nullable; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; @@ -47,9 +48,17 @@ public interface BlobStore { /** * creates a new blob with the specified name. + * @see #blobBuilder */ + @Deprecated Blob newBlob(String name); - + + /** + * + * @return builder for creating new {@link Blob}s + */ + BlobBuilder blobBuilder(String name); + /** * The get locations command returns all the valid locations for containers. A location has a * scope, which is typically region or zone. A region is a general area, like eu-west, where a diff --git a/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java index 62b0a4f54e..706339ff1f 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/TransientAsyncBlobStore.java @@ -19,6 +19,7 @@ package org.jclouds.blobstore; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Throwables.getCausalChain; @@ -125,7 +126,7 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { protected TransientAsyncBlobStore(BlobStoreContext context, DateService dateService, Crypto crypto, ConcurrentMap> containerToBlobs, ConcurrentMap containerToLocation, HttpGetOptionsListToGetOptions httpGetOptionsConverter, - IfDirectoryReturnNameStrategy ifDirectoryReturnName, Blob.Factory blobFactory, BlobUtils blobUtils, + IfDirectoryReturnNameStrategy ifDirectoryReturnName, Factory blobFactory, BlobUtils blobUtils, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, @Memoized Supplier> locations) { super(context, blobUtils, service, defaultLocation, locations); @@ -487,6 +488,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { */ @Override public ListenableFuture putBlob(String containerName, Blob in) { + checkArgument(containerName != null, "containerName must be set"); + checkArgument(in != null, "blob must be set"); ConcurrentMap container = getContainerToBlobs().get(containerName); if (container == null) { new IllegalStateException("containerName not found: " + containerName); @@ -513,6 +516,8 @@ public class TransientAsyncBlobStore extends BaseAsyncBlobStore { } protected Blob createUpdatedCopyOfBlob(Blob in) { + checkNotNull(in, "blob"); + checkNotNull(in.getPayload(), "blob.payload"); ByteArrayPayload payload = (in.getPayload() instanceof ByteArrayPayload) ? ByteArrayPayload.class.cast(in .getPayload()) : null; if (payload == null) diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java b/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java index 0e1bde6028..c0ba62efc2 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/BlobStoreMapModule.java @@ -20,11 +20,12 @@ package org.jclouds.blobstore.config; import javax.inject.Inject; +import javax.inject.Provider; import org.jclouds.blobstore.BlobMap; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.InputStreamMap; -import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.internal.BlobMapImpl; import org.jclouds.blobstore.internal.InputStreamMapImpl; import org.jclouds.blobstore.options.ListContainerOptions; @@ -65,10 +66,12 @@ public class BlobStoreMapModule extends AbstractModule { PutBlobsStrategy putBlobsStrategy; @Inject ListContainerAndRecurseThroughFolders listStrategy; + @Inject + Provider blobBuilders; public BlobMap create(String containerName, ListContainerOptions options) { - return new BlobMapImpl(connection, getAllBlobs, containsValueStrategy, putBlobsStrategy, - listStrategy, containerName, options); + return new BlobMapImpl(connection, getAllBlobs, containsValueStrategy, putBlobsStrategy, listStrategy, + containerName, options, blobBuilders); } } @@ -77,7 +80,7 @@ public class BlobStoreMapModule extends AbstractModule { @Inject BlobStore connection; @Inject - Blob.Factory blobFactory; + Provider blobBuilders; @Inject GetBlobsInListStrategy getAllBlobs; @Inject @@ -90,9 +93,8 @@ public class BlobStoreMapModule extends AbstractModule { ListContainerAndRecurseThroughFolders listStrategy; public InputStreamMap create(String containerName, ListContainerOptions options) { - return new InputStreamMapImpl(connection, blobFactory, getAllBlobs, listStrategy, - containsValueStrategy, putBlobsStrategy, containerName, options, - crypto); + return new InputStreamMapImpl(connection, blobBuilders, getAllBlobs, listStrategy, containsValueStrategy, + putBlobsStrategy, containerName, options, crypto); } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java b/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java index 8e42ca78c3..5eeaf238ca 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/config/TransientBlobStoreContextModule.java @@ -19,7 +19,6 @@ package org.jclouds.blobstore.config; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -34,15 +33,9 @@ import org.jclouds.blobstore.TransientBlobRequestSigner; import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.internal.BlobStoreContextImpl; -import org.jclouds.collect.Memoized; import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.location.Provider; +import org.jclouds.location.config.JustProviderLocationModule; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -70,6 +63,7 @@ public class TransientBlobStoreContextModule extends AbstractModule { }).toInstance(containerToLocation); install(new BlobStoreObjectModule()); install(new BlobStoreMapModule()); + install(new JustProviderLocationModule()); bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT); bind(BlobRequestSigner.class).to(TransientBlobRequestSigner.class); } @@ -79,18 +73,4 @@ public class TransientBlobStoreContextModule extends AbstractModule { BlobStore provide(TransientBlobStore in) { return in; } - - @Provides - @Singleton - @Memoized - Supplier> provideLocations(Supplier defaultLocation) { - return Suppliers.> ofInstance(ImmutableSet.of(defaultLocation.get())); - } - - @Provides - @Singleton - Supplier provideDefaultLocation(@Provider String providerName) { - return Suppliers - . ofInstance(new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null)); - } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java new file mode 100644 index 0000000000..bb39a2c767 --- /dev/null +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/BlobBuilder.java @@ -0,0 +1,123 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.blobstore.domain; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; + +import org.jclouds.blobstore.domain.internal.BlobBuilderImpl; +import org.jclouds.io.Payload; +import org.jclouds.io.Payloads; + +import com.google.inject.ImplementedBy; + +/** + * + * In case the name was confusing, this indeed builds a Blob. + * + * @author Adrian Cole + */ +@ImplementedBy(BlobBuilderImpl.class) +public interface BlobBuilder { + /** + * @param name + * The name of the {@link Blob}. Typically refers to an http path. + */ + BlobBuilder name(String name); + + /** + * @param type + * overrides default type of {@link StorageType#BLOB} + */ + BlobBuilder type(StorageType type); + + /** + * @param userMetadata + * User defined metadata associated with this {@link Blob}. + * + */ + BlobBuilder userMetadata(Map userMetadata); + + /** + * + * @param payload + * payload you wish to construct the {@link Blob} with. + */ + PayloadBlobBuilder payload(Payload payload); + + /** + * + * @param payload + * payload you wish to construct the {@link Blob} with. + */ + PayloadBlobBuilder payload(InputStream payload); + + /** + * + * @param payload + * payload you wish to construct the {@link Blob} with. + */ + PayloadBlobBuilder payload(byte[] payload); + + /** + * + * @param payload + * payload you wish to construct the {@link Blob} with. + */ + PayloadBlobBuilder payload(String payload); + + /** + * + * @param payload + * payload you wish to construct the {@link Blob} with. + */ + PayloadBlobBuilder payload(File payload); + + /** + * This makes a blob from the currently configured parameters. + * + * @return a new blob from the current parameters + */ + Blob build(); + + public interface PayloadBlobBuilder extends BlobBuilder { + + PayloadBlobBuilder contentLength(long contentLength); + + PayloadBlobBuilder contentMD5(byte[] md5); + + PayloadBlobBuilder contentType(String contentType); + + PayloadBlobBuilder contentDisposition(String contentDisposition); + + PayloadBlobBuilder contentLanguage(String contentLanguage); + + PayloadBlobBuilder contentEncoding(String contentEncoding); + + /** + * + * @see Payloads#calculateMD5 + */ + PayloadBlobBuilder calculateMD5() throws IOException; + + } +} \ No newline at end of file diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java new file mode 100644 index 0000000000..db4b0a0b26 --- /dev/null +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/BlobBuilderImpl.java @@ -0,0 +1,229 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.blobstore.domain.internal; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.io.Payloads.newPayload; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; + +import javax.annotation.Nullable; +import javax.inject.Inject; + +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; +import org.jclouds.blobstore.domain.StorageType; +import org.jclouds.crypto.Crypto; +import org.jclouds.io.Payload; +import org.jclouds.io.Payloads; + +import com.google.common.base.Throwables; +import com.google.common.collect.Maps; + +/** + * @author Adrian Cole + */ +public class BlobBuilderImpl implements BlobBuilder { + + private Payload payload; + private String name; + private Map userMetadata = Maps.newLinkedHashMap(); + private StorageType type = StorageType.BLOB; + @Inject + private Crypto crypto; + + @Override + public BlobBuilder name(String name) { + this.name = name; + return this; + } + + @Override + public BlobBuilder type(StorageType type) { + this.type = type; + return this; + } + + @Override + public BlobBuilder userMetadata(Map userMetadata) { + this.userMetadata = Maps.newLinkedHashMap(checkNotNull(userMetadata, "userMetadata")); + return this; + } + + @Override + public PayloadBlobBuilder payload(Payload payload) { + this.payload = payload; + return new PayloadBlobBuilderImpl(this, payload, crypto); + } + + /** + * {@inheritDoc} + */ + @Override + public PayloadBlobBuilder payload(InputStream data) { + return payload(newPayload(checkNotNull(data, "data"))); + } + + /** + * {@inheritDoc} + */ + @Override + public PayloadBlobBuilder payload(byte[] data) { + return payload(newPayload(checkNotNull(data, "data"))); + } + + /** + * {@inheritDoc} + */ + @Override + public PayloadBlobBuilder payload(String data) { + return payload(newPayload(checkNotNull(data, "data"))); + } + + /** + * {@inheritDoc} + */ + @Override + public PayloadBlobBuilder payload(File data) { + return payload(newPayload(checkNotNull(data, "data"))); + } + + @Override + public Blob build() { + Blob blob = new BlobImpl(new MutableBlobMetadataImpl()); + if (name != null) + blob.getMetadata().setName(name); + if (payload != null) + blob.setPayload(payload); + blob.getMetadata().setUserMetadata(userMetadata); + blob.getMetadata().setType(type); + return blob; + } + + public class PayloadBlobBuilderImpl implements PayloadBlobBuilder { + private final BlobBuilder builder; + private final Payload payload; + private MessageDigest digest; + + public PayloadBlobBuilderImpl(BlobBuilder builder, Payload payload, @Nullable Crypto crypto) { + this.builder = checkNotNull(builder, "builder"); + this.payload = checkNotNull(payload, "payload"); + try { + this.digest = crypto != null ? crypto.md5() : MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + Throwables.propagate(e); + this.digest = null; + } + } + + @Override + public BlobBuilder name(String name) { + return builder.name(name); + } + + @Override + public BlobBuilder type(StorageType type) { + return builder.type(type); + } + + @Override + public BlobBuilder userMetadata(Map userMetadata) { + return builder.userMetadata(userMetadata); + } + + @Override + public PayloadBlobBuilder payload(Payload payload) { + return builder.payload(payload); + } + + @Override + public PayloadBlobBuilder calculateMD5() throws IOException { + return builder.payload(Payloads.calculateMD5(payload, digest)); + } + + @Override + public PayloadBlobBuilder payload(InputStream payload) { + return builder.payload(payload); + } + + @Override + public PayloadBlobBuilder payload(byte[] payload) { + return builder.payload(payload); + } + + @Override + public PayloadBlobBuilder payload(String payload) { + return builder.payload(payload); + } + + @Override + public PayloadBlobBuilder payload(File payload) { + return builder.payload(payload); + } + + @Override + public Blob build() { + return builder.build(); + } + + @Override + public PayloadBlobBuilder contentLength(long contentLength) { + payload.getContentMetadata().setContentLength(contentLength); + return this; + } + + @Override + public PayloadBlobBuilder contentMD5(byte[] md5) { + payload.getContentMetadata().setContentMD5(md5); + return this; + } + + @Override + public PayloadBlobBuilder contentType(String contentType) { + payload.getContentMetadata().setContentType(contentType); + return this; + } + + @Override + public PayloadBlobBuilder contentDisposition(String contentDisposition) { + payload.getContentMetadata().setContentDisposition(contentDisposition); + return this; + } + + @Override + public PayloadBlobBuilder contentLanguage(String contentLanguage) { + payload.getContentMetadata().setContentLanguage(contentLanguage); + return this; + + } + + @Override + public PayloadBlobBuilder contentEncoding(String contentEncoding) { + payload.getContentMetadata().setContentEncoding(contentEncoding); + return this; + } + + } +} diff --git a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/PageSetImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/PageSetImpl.java index 1297a00715..413b62bed5 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/PageSetImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/domain/internal/PageSetImpl.java @@ -19,7 +19,7 @@ package org.jclouds.blobstore.domain.internal; -import java.util.HashSet; +import java.util.LinkedHashSet; import javax.annotation.Nullable; @@ -27,7 +27,7 @@ import org.jclouds.blobstore.domain.PageSet; import com.google.common.collect.Iterables; -public class PageSetImpl extends HashSet implements PageSet { +public class PageSetImpl extends LinkedHashSet implements PageSet { /** The serialVersionUID */ private static final long serialVersionUID = -7133632087734650835L; diff --git a/blobstore/src/main/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeaders.java b/blobstore/src/main/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeaders.java index f7f75cab64..d925af97d7 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeaders.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeaders.java @@ -97,7 +97,7 @@ public class ParseSystemAndUserMetadataFromHeaders implements Function defaultLocation, - @Memoized Supplier> locations) { + @Named(Constants.PROPERTY_USER_THREADS) ExecutorService service, Supplier defaultLocation, + @Memoized Supplier> locations) { this.context = checkNotNull(context, "context"); this.blobUtils = checkNotNull(blobUtils, "blobUtils"); this.service = checkNotNull(service, "service"); @@ -83,6 +84,14 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { return blobUtils.newBlob(name); } + /** + * invokes {@link BlobUtilsImpl#blobBuilder } + */ + @Override + public BlobBuilder blobBuilder(String name) { + return blobUtils.blobBuilder().name(name); + } + /** * This implementation invokes * {@link #list(String,org.jclouds.blobstore.options.ListContainerOptions)} @@ -201,12 +210,12 @@ public abstract class BaseAsyncBlobStore implements AsyncBlobStore { public ListenableFuture createDirectory(final String containerName, final String directory) { return blobUtils.directoryExists(containerName, directory) ? Futures.immediateFuture((Void) null) - : org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { - public Void call() throws Exception { - blobUtils.createDirectory(containerName, directory); - return null; - } - }), service); + : org.jclouds.concurrent.Futures.makeListenable(service.submit(new Callable() { + public Void call() throws Exception { + blobUtils.createDirectory(containerName, directory); + return null; + } + }), service); } /** diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java index afe7da24d1..6d2bf0c40e 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobMap.java @@ -19,12 +19,16 @@ package org.jclouds.blobstore.internal; +import static com.google.common.base.Functions.identity; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.transform; import java.util.Map; import java.util.Set; +import javax.inject.Inject; + import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.ListableMap; import org.jclouds.blobstore.domain.Blob; @@ -39,9 +43,7 @@ import org.jclouds.blobstore.strategy.PutBlobsStrategy; import org.jclouds.blobstore.strategy.internal.ListContainerAndRecurseThroughFolders; import com.google.common.base.Function; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; -import com.google.inject.Inject; +import com.google.common.collect.ImmutableSet; /** * Implements core Map functionality with a {@link BlobStore} @@ -88,26 +90,19 @@ public abstract class BaseBlobMap implements ListableMap { } } - static class PassThrough implements Function { - public T apply(T from) { - return from; - } - } - @Inject public BaseBlobMap(BlobStore blobstore, GetBlobsInListStrategy getAllBlobs, - ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy, - ListContainerAndRecurseThroughFolders listStrategy, String containerName, - ListContainerOptions options) { + ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy, + ListContainerAndRecurseThroughFolders listStrategy, String containerName, ListContainerOptions options) { this.blobstore = checkNotNull(blobstore, "blobstore"); this.containerName = checkNotNull(containerName, "container"); checkArgument(containerName.indexOf('/') == -1, - "please specify directory path using the option: inDirectory, not encoded in the container name"); + "please specify directory path using the option: inDirectory, not encoded in the container name"); this.options = checkNotNull(options, "options") instanceof ImmutableListContainerOptions ? options - : new ImmutableListContainerOptions(options); + : new ImmutableListContainerOptions(options); String dir = options.getDir(); if (dir == null) { - prefixer = new PassThrough(); + prefixer = identity(); pathStripper = prefixer; } else { prefixer = new PrefixKey(dir, "/"); @@ -122,13 +117,12 @@ public abstract class BaseBlobMap implements ListableMap { @Override public Set> entrySet() { - return Sets.newHashSet(Iterables.transform(list(), - new Function>() { - @Override - public java.util.Map.Entry apply(BlobMetadata from) { - return new Entry(pathStripper.apply(from.getName())); - } - })); + return ImmutableSet.copyOf(transform(list(), new Function>() { + @Override + public java.util.Map.Entry apply(BlobMetadata from) { + return new Entry(pathStripper.apply(from.getName())); + } + })); } public class Entry implements java.util.Map.Entry { @@ -187,7 +181,7 @@ public abstract class BaseBlobMap implements ListableMap { @Override public Set keySet() { - return Sets.newHashSet(Iterables.transform(list(), new Function() { + return ImmutableSet.copyOf(transform(list(), new Function() { @Override public String apply(BlobMetadata from) { return from.getName(); @@ -197,7 +191,7 @@ public abstract class BaseBlobMap implements ListableMap { @Override public boolean containsKey(Object key) { - String realKey = prefixer.apply(key.toString()); + String realKey = prefixer.apply(checkNotNull(key, "key").toString()); return blobstore.blobExists(containerName, realKey); } @@ -207,21 +201,20 @@ public abstract class BaseBlobMap implements ListableMap { } public Iterable list() { - return Iterables.transform(listStrategy.execute(containerName, options), - new Function() { - public BlobMetadata apply(BlobMetadata from) { - MutableBlobMetadata md = new MutableBlobMetadataImpl(from); - if (options.getDir() != null) - md.setName(pathStripper.apply(from.getName())); - return md; - } + return transform(listStrategy.execute(containerName, options), new Function() { + public BlobMetadata apply(BlobMetadata from) { + MutableBlobMetadata md = new MutableBlobMetadataImpl(from); + if (options.getDir() != null) + md.setName(pathStripper.apply(from.getName())); + return md; + } - }); + }); } @Override public String toString() { - return "BaseBlobMap [containerName=" + containerName + ", options=" + options + "]"; + return "[containerName=" + containerName + ", options=" + options + "]"; } } \ No newline at end of file diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java index 3ca6a77004..f3fa14b1a2 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BaseBlobStore.java @@ -30,6 +30,7 @@ import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.options.ListContainerOptions; @@ -54,7 +55,7 @@ public abstract class BaseBlobStore implements BlobStore { @Inject protected BaseBlobStore(BlobStoreContext context, BlobUtils blobUtils, Supplier defaultLocation, - @Memoized Supplier> locations) { + @Memoized Supplier> locations) { this.context = checkNotNull(context, "context"); this.blobUtils = checkNotNull(blobUtils, "blobUtils"); this.defaultLocation = checkNotNull(defaultLocation, "defaultLocation"); @@ -74,6 +75,14 @@ public abstract class BaseBlobStore implements BlobStore { return blobUtils.newBlob(name); } + /** + * invokes {@link BlobUtilsImpl#blobBuilder } + */ + @Override + public BlobBuilder blobBuilder(String name) { + return blobUtils.blobBuilder().name(name); + } + /** * This implementation invokes * {@link #list(String,org.jclouds.blobstore.options.ListContainerOptions)} diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobMapImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobMapImpl.java index 78f5e3036e..2e8fac8fea 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobMapImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/BlobMapImpl.java @@ -19,22 +19,28 @@ package org.jclouds.blobstore.internal; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.transform; + import java.util.Collection; import java.util.Map; import javax.inject.Inject; +import javax.inject.Provider; import org.jclouds.blobstore.BlobMap; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.KeyNotFoundException; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.ContainsValueInListStrategy; import org.jclouds.blobstore.strategy.GetBlobsInListStrategy; import org.jclouds.blobstore.strategy.PutBlobsStrategy; import org.jclouds.blobstore.strategy.internal.ListContainerAndRecurseThroughFolders; -import com.google.common.collect.Sets; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; /** * Map representation of a live connection to a Blob Service. @@ -45,36 +51,59 @@ import com.google.common.collect.Sets; * @author Adrian Cole */ public class BlobMapImpl extends BaseBlobMap implements BlobMap { + public static class CorrectBlobName implements Function, Blob> { + private final Function prefixer; + + public CorrectBlobName(Function prefixer) { + this.prefixer = checkNotNull(prefixer, "prefixer"); + } + + @Override + public Blob apply(java.util.Map.Entry arg0) { + return apply(arg0.getKey(), arg0.getValue()); + } + + public Blob apply(String key, Blob blob) { + blob.getMetadata().setName(prefixer.apply(key)); + return blob; + } + } + + private final CorrectBlobName correctBlobName; + private final Provider blobBuilders; @Inject public BlobMapImpl(BlobStore blobstore, GetBlobsInListStrategy getAllBlobs, - ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy, - ListContainerAndRecurseThroughFolders listStrategy, String containerName, ListContainerOptions options) { + ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy, + ListContainerAndRecurseThroughFolders listStrategy, String containerName, ListContainerOptions options, + Provider blobBuilders) { super(blobstore, getAllBlobs, containsValueStrategy, putBlobsStrategy, listStrategy, containerName, options); + this.correctBlobName = new CorrectBlobName(prefixer); + this.blobBuilders = checkNotNull(blobBuilders, "blobBuilders"); } @Override public Blob get(Object key) { - String realKey = prefixer.apply(key.toString()); + String realKey = prefixer.apply(checkNotNull(key, "key").toString()); Blob blob = blobstore.getBlob(containerName, realKey); return blob != null ? stripPrefix(blob) : null; } @Override public Blob put(String key, Blob value) { - Blob returnVal = getLastValue(key); - blobstore.putBlob(containerName, value); + Blob returnVal = getLastValue(checkNotNull(key, "key")); + blobstore.putBlob(containerName, correctBlobName.apply(key, value)); return returnVal; } @Override public void putAll(Map map) { - putBlobsStrategy.execute(containerName, map.values()); + putBlobsStrategy.execute(containerName, transform(checkNotNull(map, "map").entrySet(), correctBlobName)); } @Override public Blob remove(Object key) { - Blob old = getLastValue(key); + Blob old = getLastValue(checkNotNull(key, "key")); String realKey = prefixer.apply(key.toString()); blobstore.removeBlob(containerName, realKey); return old; @@ -83,7 +112,7 @@ public class BlobMapImpl extends BaseBlobMap implements BlobMap { private Blob getLastValue(Object key) { Blob old; try { - old = get(key); + old = get(checkNotNull(key, "key")); } catch (KeyNotFoundException e) { old = null; } @@ -92,12 +121,16 @@ public class BlobMapImpl extends BaseBlobMap implements BlobMap { @Override public Collection values() { - return Sets.newLinkedHashSet(getAllBlobs.execute(containerName, options)); + return ImmutableSet.copyOf(getAllBlobs.execute(containerName, options)); } @Override public Blob newBlob(String name) { - return blobstore.newBlob(name); + return blobBuilder().name(name).build(); } + @Override + public BlobBuilder blobBuilder() { + return blobBuilders.get(); + } } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java index f710cb3a54..67b8fb58ef 100755 --- a/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/internal/InputStreamMapImpl.java @@ -30,11 +30,13 @@ import java.util.Collection; import java.util.Map; import javax.inject.Inject; +import javax.inject.Provider; import org.jclouds.blobstore.BlobMap; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.InputStreamMap; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.ContainsValueInListStrategy; import org.jclouds.blobstore.strategy.GetBlobsInListStrategy; @@ -66,12 +68,11 @@ public class InputStreamMapImpl extends BaseBlobMap implements Inpu protected final Crypto crypto; @Inject - public InputStreamMapImpl(BlobStore connection, Blob.Factory blobFactory, - GetBlobsInListStrategy getAllBlobs, ListContainerAndRecurseThroughFolders listStrategy, - ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy, - String containerName, ListContainerOptions options, Crypto crypto) { - super(connection, getAllBlobs, containsValueStrategy, putBlobsStrategy, listStrategy, - containerName, options); + public InputStreamMapImpl(BlobStore connection, Provider blobBuilders, + GetBlobsInListStrategy getAllBlobs, ListContainerAndRecurseThroughFolders listStrategy, + ContainsValueInListStrategy containsValueStrategy, PutBlobsStrategy putBlobsStrategy, String containerName, + ListContainerOptions options, Crypto crypto) { + super(connection, getAllBlobs, containsValueStrategy, putBlobsStrategy, listStrategy, containerName, options); this.crypto = crypto; } @@ -96,12 +97,11 @@ public class InputStreamMapImpl extends BaseBlobMap implements Inpu @Override public Collection values() { - return newArrayList(transform(getAllBlobs.execute(containerName, options), - new Function() { - public InputStream apply(Blob from) { - return getInputStreamOrNull(from); - } - })); + return newArrayList(transform(getAllBlobs.execute(containerName, options), new Function() { + public InputStream apply(Blob from) { + return getInputStreamOrNull(from); + } + })); } @Override @@ -132,22 +132,21 @@ public class InputStreamMapImpl extends BaseBlobMap implements Inpu */ @VisibleForTesting void putAllInternal(Map map) { - putBlobsStrategy.execute(containerName, transform(map.entrySet(), - new Function, Blob>() { - @Override - public Blob apply(Map.Entry from) { - String name = from.getKey(); - Object value = from.getValue(); - return newBlobWithMD5(name, value); - } + putBlobsStrategy.execute(containerName, + transform(map.entrySet(), new Function, Blob>() { + @Override + public Blob apply(Map.Entry from) { + String name = from.getKey(); + Object value = from.getValue(); + return newBlobWithMD5(name, value); + } - })); + })); } @VisibleForTesting Blob newBlobWithMD5(String name, Object value) { - Blob blob = blobstore.newBlob(prefixer.apply(name)); - blob.setPayload(newPayload(value)); + Blob blob = blobstore.blobBuilder(prefixer.apply(name)).payload(newPayload(value)).build(); try { Payloads.calculateMD5(blob, crypto.md5()); } catch (IOException e) { diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkerFileMkdirStrategy.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkerFileMkdirStrategy.java index 2b823be174..b9d954e2fa 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkerFileMkdirStrategy.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/MarkerFileMkdirStrategy.java @@ -19,15 +19,15 @@ package org.jclouds.blobstore.strategy.internal; +import static org.jclouds.io.Payloads.newByteArrayPayload; + import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.blobstore.BlobStore; -import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.domain.StorageType; import org.jclouds.blobstore.reference.BlobStoreConstants; import org.jclouds.blobstore.strategy.MkdirStrategy; -import org.jclouds.io.Payloads; import com.google.inject.Inject; @@ -44,18 +44,17 @@ public class MarkerFileMkdirStrategy implements MkdirStrategy { @Inject(optional = true) @Named(BlobStoreConstants.PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX) protected String directorySuffix = ""; - private final BlobStore connection; + private final BlobStore blobStore; @Inject - MarkerFileMkdirStrategy(BlobStore connection) { - this.connection = connection; + MarkerFileMkdirStrategy(BlobStore blobStore) { + this.blobStore = blobStore; } public void execute(String containerName, String directory) { - Blob blob = connection.newBlob(directory + directorySuffix); - blob.setPayload(Payloads.newByteArrayPayload(new byte[] {})); - blob.getPayload().getContentMetadata().setContentType("application/directory"); - blob.getMetadata().setType(StorageType.RELATIVE_PATH); - connection.putBlob(containerName, blob); + blobStore.putBlob( + containerName, + blobStore.blobBuilder(directory + directorySuffix).type(StorageType.RELATIVE_PATH) + .payload(newByteArrayPayload(new byte[] {})).contentType("application/directory").build()); } } \ No newline at end of file diff --git a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java index e0326ea504..b8ed7ba217 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/strategy/internal/PutBlobsStrategyImpl.java @@ -68,7 +68,7 @@ public class PutBlobsStrategyImpl implements PutBlobsStrategy { @Override public void execute(String containerName, Iterable blobs) { - Map> responses = Maps.newHashMap(); + Map> responses = Maps.newLinkedHashMap(); for (Blob blob : blobs) { responses.put(blob, ablobstore.putBlob(containerName, blob)); } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java b/blobstore/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java index 8372e1a896..4397ca5643 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/util/BlobStoreUtils.java @@ -80,7 +80,8 @@ public class BlobStoreUtils { } public static Blob newBlob(BlobStore blobStore, StorageMetadata blobMeta) { - Blob blob = checkNotNull(blobStore, "blobStore").newBlob(checkNotNull(blobMeta, "blobMeta").getName()); + Blob blob = checkNotNull(blobStore, "blobStore").blobBuilder(checkNotNull(blobMeta, "blobMeta").getName()) + .userMetadata(blobMeta.getUserMetadata()).build(); if (blobMeta instanceof BlobMetadata) { HttpUtils.copy(((BlobMetadata) blobMeta).getContentMetadata(), blob.getMetadata().getContentMetadata()); } @@ -89,7 +90,6 @@ public class BlobStoreUtils { blob.getMetadata().setLastModified(blobMeta.getLastModified()); blob.getMetadata().setLocation(blobMeta.getLocation()); blob.getMetadata().setUri(blobMeta.getUri()); - blob.getMetadata().setUserMetadata(blobMeta.getUserMetadata()); return blob; } diff --git a/blobstore/src/main/java/org/jclouds/blobstore/util/BlobUtils.java b/blobstore/src/main/java/org/jclouds/blobstore/util/BlobUtils.java index 839aadc455..6f55ffb886 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/util/BlobUtils.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/util/BlobUtils.java @@ -20,6 +20,7 @@ package org.jclouds.blobstore.util; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.util.internal.BlobUtilsImpl; @@ -31,6 +32,7 @@ import com.google.inject.ImplementedBy; */ @ImplementedBy(BlobUtilsImpl.class) public interface BlobUtils { + BlobBuilder blobBuilder(); Blob newBlob(String name); diff --git a/blobstore/src/main/java/org/jclouds/blobstore/util/internal/BlobUtilsImpl.java b/blobstore/src/main/java/org/jclouds/blobstore/util/internal/BlobUtilsImpl.java index 807f121539..95047cf5f5 100644 --- a/blobstore/src/main/java/org/jclouds/blobstore/util/internal/BlobUtilsImpl.java +++ b/blobstore/src/main/java/org/jclouds/blobstore/util/internal/BlobUtilsImpl.java @@ -22,9 +22,11 @@ package org.jclouds.blobstore.util.internal; import static com.google.common.base.Preconditions.checkNotNull; import javax.inject.Inject; +import javax.inject.Provider; import javax.inject.Singleton; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.blobstore.strategy.ClearListStrategy; import org.jclouds.blobstore.strategy.CountListStrategy; @@ -41,7 +43,7 @@ import org.jclouds.blobstore.util.BlobUtils; @Singleton public class BlobUtilsImpl implements BlobUtils { - protected final Blob.Factory blobFactory; + protected final Provider blobBuilders; protected final ClearListStrategy clearContainerStrategy; protected final GetDirectoryStrategy getDirectoryStrategy; protected final MkdirStrategy mkdirStrategy; @@ -49,10 +51,10 @@ public class BlobUtilsImpl implements BlobUtils { protected final CountListStrategy countBlobsStrategy; @Inject - protected BlobUtilsImpl(Blob.Factory blobFactory, ClearListStrategy clearContainerStrategy, - GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy, - CountListStrategy countBlobsStrategy, DeleteDirectoryStrategy rmDirStrategy) { - this.blobFactory = checkNotNull(blobFactory, "blobFactory"); + protected BlobUtilsImpl(Provider blobBuilders, ClearListStrategy clearContainerStrategy, + GetDirectoryStrategy getDirectoryStrategy, MkdirStrategy mkdirStrategy, CountListStrategy countBlobsStrategy, + DeleteDirectoryStrategy rmDirStrategy) { + this.blobBuilders = checkNotNull(blobBuilders, "blobBuilders"); this.clearContainerStrategy = checkNotNull(clearContainerStrategy, "clearContainerStrategy"); this.getDirectoryStrategy = checkNotNull(getDirectoryStrategy, "getDirectoryStrategy"); this.mkdirStrategy = checkNotNull(mkdirStrategy, "mkdirStrategy"); @@ -60,10 +62,14 @@ public class BlobUtilsImpl implements BlobUtils { this.countBlobsStrategy = checkNotNull(countBlobsStrategy, "countBlobsStrategy"); } + @Override public Blob newBlob(String name) { - Blob blob = blobFactory.create(null); - blob.getMetadata().setName(name); - return blob; + return blobBuilder().name(name).build(); + } + + @Override + public BlobBuilder blobBuilder() { + return blobBuilders.get(); } public boolean directoryExists(String containerName, String directory) { diff --git a/blobstore/src/test/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeadersTest.java b/blobstore/src/test/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeadersTest.java index 5b45245efc..ce90dab61c 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeadersTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/functions/ParseSystemAndUserMetadataFromHeadersTest.java @@ -86,6 +86,18 @@ public class ParseSystemAndUserMetadataFromHeadersTest { .rfc822DateParse("Wed, 09 Sep 2009 19:50:23 GMT")); } + + @Test + public void testSetLastModifiedIso8601() { + HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload(""), ImmutableMultimap.of( + HttpHeaders.LAST_MODIFIED, "2011-01-28T17:35:08.000+0000")); + MutableBlobMetadata metadata = blobMetadataProvider.get(); + parser.parseLastModifiedOrThrowException(from, metadata); + assertEquals(metadata.getLastModified(), new SimpleDateFormatDateService() + .iso8601DateParse("2011-01-28T17:35:08.000Z")); + } + + @Test(expectedExceptions = HttpException.class) public void testSetLastModifiedException() { HttpResponse from = new HttpResponse(200, "ok", Payloads.newStringPayload("")); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java index a3c6f9f4e6..7240da1bee 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/TransientContainerIntegrationTest.java @@ -19,6 +19,7 @@ package org.jclouds.blobstore.integration; +import static com.google.common.collect.Iterables.getOnlyElement; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults; import static org.testng.Assert.assertEquals; @@ -31,7 +32,7 @@ import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest; import org.testng.annotations.Test; -import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableMap; /** * @author James Murty @@ -44,22 +45,19 @@ public class TransientContainerIntegrationTest extends BaseContainerIntegrationT public void testNotWithDetails() throws InterruptedException { String key = "hello"; - - Blob object = context.getBlobStore().newBlob(key); - object.setPayload(TEST_STRING); - object.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN); // NOTE all metadata in jclouds comes out as lowercase, in an effort to normalize the // providers. - object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); + Blob blob = context.getBlobStore().blobBuilder("hello").userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).build(); + String containerName = getContainerName(); try { - addBlobToContainer(containerName, object); + addBlobToContainer(containerName, blob); validateContent(containerName, key); - PageSet container = context.getBlobStore().list(containerName, - maxResults(1)); + PageSet container = context.getBlobStore().list(containerName, maxResults(1)); - BlobMetadata metadata = (BlobMetadata) Iterables.getOnlyElement(container); + BlobMetadata metadata = (BlobMetadata) getOnlyElement(container); // transient container should be lenient and not return metadata on undetailed listing. assertEquals(metadata.getUserMetadata().size(), 0); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java index 9cc4438a7b..4eedeab093 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobIntegrationTest.java @@ -49,6 +49,7 @@ import javax.ws.rs.core.MediaType; import org.jclouds.blobstore.ContainerNotFoundException; import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobBuilder.PayloadBlobBuilder; import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; @@ -73,6 +74,7 @@ import org.testng.annotations.Test; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.io.ByteStreams; @@ -147,13 +149,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } private void uploadConstitution(String containerName, String key, String contentDisposition) throws IOException { - Blob sourceObject = context.getBlobStore().newBlob(key); - sourceObject.setPayload(oneHundredOneConstitutions.getInput()); - sourceObject.getMetadata().getContentMetadata().setContentType("text/plain"); - sourceObject.getMetadata().getContentMetadata().setContentMD5(oneHundredOneConstitutionsMD5); - sourceObject.getMetadata().getContentMetadata().setContentLength(oneHundredOneConstitutionsLength); - sourceObject.getMetadata().getContentMetadata().setContentDisposition(contentDisposition); - context.getBlobStore().putBlob(containerName, sourceObject); + context.getBlobStore().putBlob( + containerName, + context.getBlobStore().blobBuilder(key).payload(oneHundredOneConstitutions.getInput()) + .contentType("text/plain").contentMD5(oneHundredOneConstitutionsMD5) + .contentLength(oneHundredOneConstitutionsLength).contentDisposition(contentDisposition).build()); } @Test(groups = { "integration", "live" }) @@ -421,14 +421,13 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }, dataProvider = "putTests") public void testPutObject(String key, String type, Object content, Object realObject) throws InterruptedException, IOException { - Blob blob = context.getBlobStore().newBlob(key); - blob.setPayload(Payloads.newPayload(content)); - blob.getMetadata().getContentMetadata().setContentType(type); - addContentMetadata(blob); - + PayloadBlobBuilder blobBuilder = context.getBlobStore().blobBuilder(key).payload(Payloads.newPayload(content)) + .contentType(type); + addContentMetadata(blobBuilder); if (content instanceof InputStream) { - Payloads.calculateMD5(blob, context.utils().crypto().md5()); + blobBuilder.calculateMD5(); } + Blob blob = blobBuilder.build(); String containerName = getContainerName(); try { assertNotNull(context.getBlobStore().putBlob(containerName, blob)); @@ -446,14 +445,15 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void testPutObjectStream() throws InterruptedException, IOException, ExecutionException { - Blob blob = context.getBlobStore().newBlob("streaming"); - blob.setPayload(new StreamingPayload(new WriteTo() { + PayloadBlobBuilder blobBuilder = context.getBlobStore().blobBuilder("streaming").payload(new StreamingPayload(new WriteTo() { @Override public void writeTo(OutputStream outstream) throws IOException { outstream.write("foo".getBytes()); } })); - addContentMetadata(blob); + addContentMetadata(blobBuilder); + + Blob blob = blobBuilder.build(); String containerName = getContainerName(); try { @@ -478,11 +478,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { checkContentLanguage(blob, "en"); } - private void addContentMetadata(Blob blob) { - blob.getMetadata().getContentMetadata().setContentType("text/csv"); - blob.getMetadata().getContentMetadata().setContentDisposition("attachment; filename=photo.jpg"); - blob.getMetadata().getContentMetadata().setContentEncoding("gzip"); - blob.getMetadata().getContentMetadata().setContentLanguage("en"); + private void addContentMetadata(PayloadBlobBuilder blobBuilder) { + blobBuilder.contentType("text/csv"); + blobBuilder.contentDisposition("attachment; filename=photo.jpg"); + blobBuilder.contentEncoding("gzip"); + blobBuilder.contentLanguage("en"); } protected void checkContentType(Blob blob, String contentType) { @@ -501,11 +501,10 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { } protected void checkContentEncoding(Blob blob, String contentEncoding) { - assert blob.getPayload().getContentMetadata().getContentEncoding().startsWith(contentEncoding) : blob + assert (blob.getPayload().getContentMetadata().getContentEncoding().indexOf(contentEncoding) != -1) : blob .getPayload().getContentMetadata().getContentEncoding(); - assert blob.getMetadata().getContentMetadata().getContentEncoding().startsWith(contentEncoding) : blob + assert (blob.getMetadata().getContentMetadata().getContentEncoding().indexOf(contentEncoding) != -1) : blob .getMetadata().getContentMetadata().getContentEncoding(); - } protected void checkContentLanguage(Blob blob, String contentLanguage) { @@ -529,15 +528,11 @@ public class BaseBlobIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void testMetadata() throws InterruptedException, IOException { String key = "hello"; - - Blob blob = context.getBlobStore().newBlob(key); - blob.setPayload(TEST_STRING); - blob.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN); // NOTE all metadata in jclouds comes out as lowercase, in an effort to // normalize the // providers. - blob.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); - Payloads.calculateMD5(blob, context.utils().crypto().md5()); + Blob blob = context.getBlobStore().blobBuilder(key).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).calculateMD5().build(); String containerName = getContainerName(); try { assertNull(context.getBlobStore().blobMetadata(containerName, "powderpuff")); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java index 140a838d46..877663276d 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobLiveTest.java @@ -46,7 +46,7 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest { private static final String sysHttpStreamETag = System.getProperty("jclouds.blobstore.httpstream.md5"); @Test - @Parameters( { "jclouds.blobstore.httpstream.url", "jclouds.blobstore.httpstream.md5" }) + @Parameters({ "jclouds.blobstore.httpstream.url", "jclouds.blobstore.httpstream.md5" }) public void testCopyUrl(@Optional String httpStreamUrl, @Optional String httpStreamETag) throws Exception { httpStreamUrl = checkNotNull(httpStreamUrl != null ? httpStreamUrl : sysHttpStreamUrl, "httpStreamUrl"); @@ -61,10 +61,7 @@ public class BaseBlobLiveTest extends BaseBlobStoreIntegrationTest { long length = connection.getContentLength(); InputStream input = connection.getInputStream(); - Blob blob = context.getBlobStore().newBlob(name); - blob.setPayload(input); - blob.getPayload().getContentMetadata().setContentLength(length); - blob.getPayload().getContentMetadata().setContentMD5(md5); + Blob blob = context.getBlobStore().blobBuilder(name).payload(input).contentLength(length).contentMD5(md5).build(); String container = getContainerName(); try { context.getBlobStore().putBlob(container, blob); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java index eb7637827f..70b2a750e1 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobMapIntegrationTest.java @@ -20,17 +20,16 @@ package org.jclouds.blobstore.integration.internal; import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.blobstore.options.ListContainerOptions.Builder.inDirectory; import static org.jclouds.blobstore.options.ListContainerOptions.Builder.maxResults; import static org.jclouds.blobstore.util.BlobStoreUtils.getContentAsStringOrNullAndClose; import static org.testng.Assert.assertEquals; import java.io.IOException; import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -42,7 +41,12 @@ import org.jclouds.io.Payloads; import org.jclouds.util.Strings2; import org.testng.annotations.Test; +import com.google.common.base.Function; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; /** @@ -52,19 +56,32 @@ import com.google.common.collect.Sets; */ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest { + private static class StringToBlob implements Function { + private final BlobMap map; + + private StringToBlob(BlobMap map) { + this.map = map; + } + + @Override + public Blob apply(String arg0) { + return map.blobBuilder().payload(arg0).build(); + } + } + @Override @Test(groups = { "integration", "live" }) public void testValues() throws IOException, InterruptedException { String bucketName = getContainerName(); try { - Map map = createMap(context, bucketName); + BlobMap map = createMap(context, bucketName); putFiveStrings(map); putFiveStringsUnderPath(map); Collection blobs = map.values(); assertConsistencyAwareMapSize(map, 5); - Set blobsAsString = new HashSet(); + Set blobsAsString = Sets.newLinkedHashSet(); for (Blob blob : blobs) { blobsAsString.add(getContentAsStringOrNullAndClose(blob)); } @@ -92,7 +109,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< } private void assertConsistencyAwareContentEquals(final Map map, final String key, final String blob) - throws InterruptedException { + throws InterruptedException { assertConsistencyAware(new Runnable() { public void run() { Blob old = map.remove(key); @@ -110,7 +127,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< public void testEntrySet() throws IOException, InterruptedException { String bucketName = getContainerName(); try { - final Map map = createMap(context, bucketName); + final BlobMap map = createMap(context, bucketName); putFiveStrings(map); assertConsistencyAwareMapSize(map, 5); Set> entries = map.entrySet(); @@ -145,9 +162,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< try { Map map = createMap(context, bucketName); putStringWithMD5(map, "one", "apple"); - Blob blob = context.getBlobStore().newBlob("one"); - blob.setPayload("apple"); - Payloads.calculateMD5(blob); + Blob blob = context.getBlobStore().blobBuilder("one").payload("apple").calculateMD5().build(); assertConsistencyAwareContainsValue(map, blob); } finally { returnContainer(bucketName); @@ -161,7 +176,7 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< } void getOneReturnsBearAndOldValueIsApple(Map map, Blob oldValue) throws IOException, - InterruptedException { + InterruptedException { assertEquals(getContentAsStringOrNullAndClose(checkNotNull(map.get("one"), "one")), "bear"); assertEquals(getContentAsStringOrNullAndClose(oldValue), "apple"); assertConsistencyAwareMapSize(map, 1); @@ -172,9 +187,8 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< String bucketName = getContainerName(); try { Map map = createMap(context, bucketName); - Blob blob = context.getBlobStore().newBlob("one"); - blob.setPayload(Strings2.toInputStream("apple")); - Payloads.calculateMD5(blob); + Blob blob = context.getBlobStore().blobBuilder("one").payload(Strings2.toInputStream("apple")).calculateMD5() + .build(); Blob old = map.put(blob.getMetadata().getName(), blob); getOneReturnsAppleAndOldValueIsNull(map, old); blob.setPayload(Strings2.toInputStream("bear")); @@ -191,16 +205,16 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< String bucketName = getContainerName(); try { Map map = createMap(context, bucketName); - Map newMap = new HashMap(); + ImmutableMap.Builder newMap = ImmutableMap. builder(); for (String key : fiveInputs.keySet()) { - Blob blob = context.getBlobStore().newBlob(key); - blob.setPayload(fiveInputs.get(key)); - blob.getPayload().getContentMetadata().setContentLength((long) fiveBytes.get(key).length); - newMap.put(key, blob); + newMap.put( + key, + context.getBlobStore().blobBuilder(key).payload(fiveInputs.get(key)) + .contentLength((long) fiveBytes.get(key).length).build()); } - map.putAll(newMap); + map.putAll(newMap.build()); assertConsistencyAwareMapSize(map, 5); - assertConsistencyAwareKeySetEquals(map, new HashSet(fiveInputs.keySet())); + assertConsistencyAwareKeySetEquals(map, ImmutableSet.copyOf(fiveInputs.keySet())); fourLeftRemovingOne(map); } finally { returnContainer(bucketName); @@ -213,23 +227,21 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< return; String bucketName = getContainerName(); try { - Map map = createMap(context, bucketName); - Set keySet = Sets.newHashSet(); + BlobMap map = createMap(context, bucketName); + Builder keySet = ImmutableSet. builder(); for (int i = 0; i < maxResultsForTestListings() + 1; i++) { keySet.add(i + ""); } - Map newMap = new HashMap(); - for (String key : keySet) { - Blob blob = context.getBlobStore().newBlob(key); - blob.setPayload(key); - newMap.put(key, blob); + Map newMap = Maps.newLinkedHashMap(); + for (String key : keySet.build()) { + newMap.put(key, map.blobBuilder().payload(key).build()); } map.putAll(newMap); newMap.clear(); assertConsistencyAwareMapSize(map, maxResultsForTestListings() + 1); - assertConsistencyAwareKeySetEquals(map, keySet); + assertConsistencyAwareKeySetEquals(map, keySet.build()); map.clear(); assertConsistencyAwareMapSize(map, 0); } finally { @@ -239,30 +251,15 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< @Override protected void putStringWithMD5(Map map, String key, String text) throws IOException { - Blob blob = context.getBlobStore().newBlob(key); - blob.setPayload(text); - Payloads.calculateMD5(blob); - map.put(key, blob); + map.put(key, context.getBlobStore().blobBuilder(key).payload(text).calculateMD5().build()); } - protected void putFiveStrings(Map map) { - Map newMap = new HashMap(); - for (Map.Entry entry : fiveStrings.entrySet()) { - Blob blob = context.getBlobStore().newBlob(entry.getKey()); - blob.setPayload(entry.getValue()); - newMap.put(entry.getKey(), blob); - } - map.putAll(newMap); + protected void putFiveStrings(BlobMap map) { + map.putAll(Maps.transformValues(fiveStrings, new StringToBlob(map))); } - protected void putFiveStringsUnderPath(Map map) { - Map newMap = new HashMap(); - for (Map.Entry entry : fiveStringsUnderPath.entrySet()) { - Blob blob = context.getBlobStore().newBlob(entry.getKey()); - blob.setPayload(entry.getValue()); - newMap.put(entry.getKey(), blob); - } - map.putAll(newMap); + protected void putFiveStringsUnderPath(BlobMap map) { + map.putAll(Maps.transformValues(fiveStringsUnderPath, new StringToBlob(map))); } protected int maxResultsForTestListings() { @@ -276,4 +273,20 @@ public abstract class BaseBlobMapIntegrationTest extends BaseMapIntegrationTest< protected BlobMap createMap(BlobStoreContext context, String bucket, ListContainerOptions options) { return context.createBlobMap(bucket, options); } + + @Override + protected void addTenObjectsUnderPrefix(String containerName, String prefix) throws InterruptedException { + BlobMap blobMap = createMap(context, containerName, inDirectory(prefix)); + for (int i = 0; i < 10; i++) { + blobMap.put(i + "", blobMap.blobBuilder().payload(i + "content").build()); + } + } + + @Override + protected void addTenObjectsUnderRoot(String containerName) throws InterruptedException { + BlobMap blobMap = createMap(context, containerName, ListContainerOptions.NONE); + for (int i = 0; i < 10; i++) { + blobMap.put(i + "", blobMap.blobBuilder().payload(i + "content").build()); + } + } } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java index 484c8ae275..b1604f2bf0 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobSignerLiveTest.java @@ -41,9 +41,7 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest { String name = "hello"; String text = "fooooooooooooooooooooooo"; - Blob blob = context.getBlobStore().newBlob(name); - blob.setPayload(text); - blob.getPayload().getContentMetadata().setContentType("text/plain"); + Blob blob = context.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); String container = getContainerName(); try { context.getBlobStore().putBlob(container, blob); @@ -62,9 +60,7 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest { String name = "hello"; String text = "fooooooooooooooooooooooo"; - Blob blob = context.getBlobStore().newBlob(name); - blob.setPayload(text); - blob.getPayload().getContentMetadata().setContentType("text/plain"); + Blob blob = context.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); String container = getContainerName(); try { context.getBlobStore().putBlob(container, blob); @@ -82,9 +78,7 @@ public class BaseBlobSignerLiveTest extends BaseBlobStoreIntegrationTest { String name = "hello"; String text = "fooooooooooooooooooooooo"; - Blob blob = context.getBlobStore().newBlob(name); - blob.setPayload(text); - blob.getPayload().getContentMetadata().setContentType("text/plain"); + Blob blob = context.getBlobStore().blobBuilder(name).payload(text).contentType("text/plain").build(); String container = getContainerName(); try { HttpRequest request = context.getSigner().signPutBlob(container, blob); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java index e928ea6840..de48e24c81 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseBlobStoreIntegrationTest.java @@ -244,17 +244,14 @@ public class BaseBlobStoreIntegrationTest { } protected String addBlobToContainer(String sourceContainer, String key, String payload, String contentType) { - Blob sourceObject = context.getBlobStore().newBlob(key); - sourceObject.setPayload(payload); - sourceObject.getMetadata().getContentMetadata().setContentType(contentType); + Blob sourceObject = context.getBlobStore().blobBuilder(key).payload(payload).contentType(contentType).build(); return addBlobToContainer(sourceContainer, sourceObject); } protected void add5BlobsUnderPathAnd5UnderRootToContainer(String sourceContainer) { for (Entry entry : Iterables.concat(fiveStrings.entrySet(), fiveStringsUnderPath.entrySet())) { - Blob sourceObject = context.getBlobStore().newBlob(entry.getKey()); - sourceObject.setPayload(entry.getValue()); - sourceObject.getMetadata().getContentMetadata().setContentType("text/xml"); + Blob sourceObject = context.getBlobStore().blobBuilder(entry.getKey()).payload(entry.getValue()) + .contentType("text/xml").build(); addBlobToContainer(sourceContainer, sourceObject); } } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java index b4d1321ceb..757e009534 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseContainerIntegrationTest.java @@ -40,9 +40,10 @@ import org.jclouds.blobstore.domain.PageSet; import org.jclouds.blobstore.domain.StorageMetadata; import org.jclouds.crypto.CryptoStreams; import org.jclouds.io.InputSuppliers; -import org.jclouds.io.Payloads; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; + /** * @author Adrian Cole */ @@ -60,8 +61,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { try { context.getBlobStore().createContainerInLocation(null, containerName); - Blob blob = context.getBlobStore().newBlob("hello"); - blob.setPayload(TEST_STRING); + Blob blob = context.getBlobStore().blobBuilder("hello").payload(TEST_STRING).build(); context.getBlobStore().putBlob(containerName, blob); context.getBlobStore().createContainerInLocation(null, containerName); @@ -74,26 +74,22 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void testWithDetails() throws InterruptedException, IOException { String key = "hello"; - - Blob object = context.getBlobStore().newBlob(key); - object.setPayload(TEST_STRING); - object.getMetadata().getContentMetadata().setContentType(MediaType.TEXT_PLAIN); - // NOTE all metadata in jclouds comes out as lowercase, in an effort to - // normalize the - // providers. - object.getMetadata().getUserMetadata().put("Adrian", "powderpuff"); - Payloads.calculateMD5(object, context.utils().crypto().md5()); String containerName = getContainerName(); try { - addBlobToContainer(containerName, object); + addBlobToContainer(containerName, + // NOTE all metadata in jclouds comes out as lowercase, in an effort to + // normalize the providers. + context.getBlobStore().blobBuilder(key).userMetadata(ImmutableMap.of("Adrian", "powderpuff")) + .payload(TEST_STRING).contentType(MediaType.TEXT_PLAIN).calculateMD5().build()); validateContent(containerName, key); PageSet container = context.getBlobStore().list(containerName, - maxResults(1).withDetails()); + maxResults(1).withDetails()); BlobMetadata metadata = BlobMetadata.class.cast(get(container, 0)); - assert metadata.getContentMetadata().getContentType().startsWith("text/plain") : metadata.getContentMetadata().getContentType(); + assert metadata.getContentMetadata().getContentType().startsWith("text/plain") : metadata.getContentMetadata() + .getContentType(); assertEquals(metadata.getContentMetadata().getContentLength(), new Long(TEST_STRING.length())); assertEquals(metadata.getUserMetadata().get("adrian"), "powderpuff"); checkMD5(metadata); @@ -123,6 +119,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { String containerName = getContainerName(); try { addAlphabetUnderRoot(containerName); + PageSet container = context.getBlobStore().list(containerName, maxResults(1)); assert container.getNextMarker() != null; @@ -132,7 +129,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { container = context.getBlobStore().list(containerName, afterMarker(marker)); assertEquals(container.getNextMarker(), null); assert container.size() == 25 : String.format("size should have been 25, but was %d: %s", container.size(), - container); + container); assert container.getNextMarker() == null; } finally { @@ -255,6 +252,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { String containerName = getContainerName(); try { addAlphabetUnderRoot(containerName); + PageSet container = context.getBlobStore().list(containerName, maxResults(5)); assertEquals(container.size(), 5); assert container.getNextMarker() != null; @@ -302,7 +300,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { public void run() { try { assert !context.getBlobStore().containerExists(containerName) : "container " + containerName - + " still exists"; + + " still exists"; } catch (Exception e) { propagateIfPossible(e); } @@ -312,7 +310,7 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { @Test(groups = { "integration", "live" }) public void testListContainer() throws InterruptedException, ExecutionException, TimeoutException, - UnsupportedEncodingException { + UnsupportedEncodingException { String containerName = getContainerName(); try { add15UnderRoot(containerName); @@ -326,25 +324,36 @@ public class BaseContainerIntegrationTest extends BaseBlobStoreIntegrationTest { protected void addAlphabetUnderRoot(String containerName) throws InterruptedException { for (char letter = 'a'; letter <= 'z'; letter++) { - Blob blob = context.getBlobStore().newBlob(letter + ""); - blob.setPayload(letter + "content"); - context.getBlobStore().putBlob(containerName, blob); + context.getBlobStore().putBlob(containerName, + context.getBlobStore().blobBuilder(letter + "").payload(letter + "content").build()); } + assertContainerSize(containerName, 26); + + } + + protected void assertContainerSize(final String containerName, final int size) throws InterruptedException { + assertConsistencyAware(new Runnable() { + public void run() { + try { + assertEquals(context.getBlobStore().countBlobs(containerName), size); + } catch (Exception e) { + propagateIfPossible(e); + } + } + }); } protected void add15UnderRoot(String containerName) throws InterruptedException { for (int i = 0; i < 15; i++) { - Blob blob = context.getBlobStore().newBlob(i + ""); - blob.setPayload(i + "content"); - context.getBlobStore().putBlob(containerName, blob); + context.getBlobStore().putBlob(containerName, + context.getBlobStore().blobBuilder(i + "").payload(i + "content").build()); } } protected void addTenObjectsUnderPrefix(String containerName, String prefix) throws InterruptedException { for (int i = 0; i < 10; i++) { - Blob blob = context.getBlobStore().newBlob(prefix + "/" + i); - blob.setPayload(i + "content"); - context.getBlobStore().putBlob(containerName, blob); + context.getBlobStore().putBlob(containerName, + context.getBlobStore().blobBuilder(prefix + "/" + i).payload(i + "content").build()); } } } \ No newline at end of file diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java index 474a224a78..f4dfca93eb 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseInputStreamMapIntegrationTest.java @@ -27,11 +27,10 @@ import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; -import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -61,7 +60,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati assertConsistencyAwareMapSize(map, 5); Collection values = map.values(); assertEquals(values.size(), 5); - Set valuesAsString = new HashSet(); + Set valuesAsString = Sets.newLinkedHashSet(); for (InputStream stream : values) { valuesAsString.add(Strings2.toStringAndClose(stream)); } @@ -77,7 +76,7 @@ public abstract class BaseInputStreamMapIntegrationTest extends BaseMapIntegrati String containerName = getContainerName(); try { InputStreamMap map = createMap(context, containerName); - Set keySet = Sets.newHashSet(); + Set keySet = Sets.newLinkedHashSet(); for (int i = 0; i < maxResultsForTestListings() + 1; i++) { keySet.add(i + ""); } diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java index c0cbf9b6b2..6b81666478 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseMapIntegrationTest.java @@ -30,15 +30,14 @@ import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; -import java.util.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.ListableMap; -import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.options.ListContainerOptions; import org.jclouds.util.Strings2; import org.testng.annotations.BeforeClass; @@ -50,6 +49,7 @@ import org.testng.annotations.Test; import com.google.common.base.Charsets; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedSet; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -82,14 +82,14 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } @BeforeClass(groups = { "integration", "live" }) - @Parameters( { "basedir" }) + @Parameters({ "basedir" }) protected void setUpTempDir(@Optional String basedir) throws InterruptedException, ExecutionException, - FileNotFoundException, IOException, TimeoutException { + FileNotFoundException, IOException, TimeoutException { if (basedir == null) { basedir = System.getProperty("java.io.tmpdir"); } tmpDirectory = basedir + File.separator + "target" + File.separator + "testFiles" + File.separator - + getClass().getSimpleName(); + + getClass().getSimpleName(); new File(tmpDirectory).mkdirs(); fiveFiles = Maps.newHashMap(); for (Entry entry : fiveStrings.entrySet()) { @@ -102,7 +102,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration protected abstract Map createMap(BlobStoreContext context, String containerName); protected abstract Map createMap(BlobStoreContext context, String containerName, - ListContainerOptions options); + ListContainerOptions options); @Test(groups = { "integration", "live" }) public void testClear() throws InterruptedException, ExecutionException, TimeoutException, IOException { @@ -138,17 +138,15 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration protected void addTenObjectsUnderPrefix(String containerName, String prefix) throws InterruptedException { for (int i = 0; i < 10; i++) { - Blob blob = context.getBlobStore().newBlob(prefix + "/" + i); - blob.setPayload(i + "content"); - context.getBlobStore().putBlob(containerName, blob); + context.getBlobStore().putBlob(containerName, + context.getBlobStore().blobBuilder(prefix + "/" + i).payload(i + "content").build()); } } protected void addTenObjectsUnderRoot(String containerName) throws InterruptedException { for (int i = 0; i < 10; i++) { - Blob blob = context.getBlobStore().newBlob(i + ""); - blob.setPayload(i + "content"); - context.getBlobStore().putBlob(containerName, blob); + context.getBlobStore().putBlob(containerName, + context.getBlobStore().blobBuilder(i + "").payload(i + "content").build()); } } @@ -165,15 +163,28 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration context.getBlobStore().createDirectory(containerName, directory); addTenObjectsUnderRoot(containerName); assertEquals(rootMap.size(), 10); + assertEquals(ImmutableSortedSet.copyOf(rootMap.keySet()), + ImmutableSortedSet.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")); assertEquals(rootRecursiveMap.size(), 10); + assertEquals(ImmutableSortedSet.copyOf(rootRecursiveMap.keySet()), + ImmutableSortedSet.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")); assertEquals(inDirectoryMap.size(), 0); assertEquals(inDirectoryRecursiveMap.size(), 0); addTenObjectsUnderPrefix(containerName, directory); assertEquals(rootMap.size(), 10); + assertEquals(ImmutableSortedSet.copyOf(rootMap.keySet()), + ImmutableSortedSet.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")); assertEquals(rootRecursiveMap.size(), 20); + assertEquals(ImmutableSortedSet.copyOf(rootRecursiveMap.keySet()), ImmutableSet.of("0", "1", "2", "3", "4", + "5", "6", "7", "8", "9", "apps/0", "apps/1", "apps/2", "apps/3", "apps/4", "apps/5", "apps/6", "apps/7", + "apps/8", "apps/9")); assertEquals(inDirectoryMap.size(), 10); + assertEquals(ImmutableSortedSet.copyOf(inDirectoryMap.keySet()), + ImmutableSortedSet.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")); assertEquals(inDirectoryRecursiveMap.size(), 10); + assertEquals(ImmutableSortedSet.copyOf(inDirectoryRecursiveMap.keySet()), + ImmutableSortedSet.of("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")); context.getBlobStore().createDirectory(containerName, directory + "/" + directory); assertEquals(rootMap.size(), 10); @@ -200,7 +211,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } protected void assertConsistencyAwareKeySetEquals(final Map map, final Set expected) - throws InterruptedException { + throws InterruptedException { assertConsistencyAware(new Runnable() { public void run() { Set toMatch = map.keySet(); @@ -214,7 +225,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } protected void assertConsistencyAwareRemoveEquals(final Map map, final String key, final Object equals) - throws InterruptedException { + throws InterruptedException { assertConsistencyAware(new Runnable() { public void run() { assertEquals(map.remove(key), equals); @@ -223,7 +234,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } protected void assertConsistencyAwareGetEquals(final Map map, final String key, final Object equals) - throws InterruptedException { + throws InterruptedException { assertConsistencyAware(new Runnable() { public void run() { assertEquals(map.get(key), equals); @@ -257,7 +268,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration * eventual consistency problems. */ protected void assertConsistencyAwareContainsValue(final Map map, final Object value) - throws InterruptedException { + throws InterruptedException { assertConsistencyAware(new Runnable() { public void run() { assert map.containsValue(value); @@ -311,7 +322,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } abstract protected void putStringWithMD5(Map map, String key, String value) throws InterruptedException, - ExecutionException, TimeoutException, IOException; + ExecutionException, TimeoutException, IOException; protected void fourLeftRemovingOne(Map map) throws InterruptedException { map.remove("one"); @@ -342,7 +353,7 @@ public abstract class BaseMapIntegrationTest extends BaseBlobStoreIntegration } protected void assertConsistencyAwareListContainer(final ListableMap map, final String containerNameName) - throws InterruptedException { + throws InterruptedException { assertConsistencyAware(new Runnable() { public void run() { assertTrue(Iterables.size(map.list()) >= 0); diff --git a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java index 59c9818203..2578c20fdc 100755 --- a/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/integration/internal/BaseServiceIntegrationTest.java @@ -31,6 +31,7 @@ import org.jclouds.domain.LocationScope; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; /** @@ -61,11 +62,9 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest { PageSet list = context.getBlobStore().list(); assert Iterables.any(list, new Predicate() { public boolean apply(StorageMetadata md) { - return containerName.equals(md.getName()) - && location.equals(md.getLocation()); + return containerName.equals(md.getName()) && location.equals(md.getLocation()); } - }) : String.format("container %s/%s not found in list %s", location, - containerName, list); + }) : String.format("container %s/%s not found in list %s", location, containerName, list); } }); @@ -75,10 +74,14 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest { } } + protected Set getIso3166Codes() { + return ImmutableSet. of(); + } + @Test(groups = { "integration", "live" }) public void testGetAssignableLocations() throws Exception { - for (Location location : context.getBlobStore() - .listAssignableLocations()) { + assertProvider(context.getProviderSpecificContext()); + for (Location location : context.getBlobStore().listAssignableLocations()) { System.err.printf("location %s%n", location); assert location.getId() != null : location; assert location != location.getParent() : location; @@ -89,6 +92,9 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest { break; case REGION: assertProvider(location.getParent()); + assert location.getIso3166Codes().size() == 0 + || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + + " ||" + location.getParent(); break; case ZONE: Location provider = location.getParent().getParent(); @@ -96,6 +102,9 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest { if (provider == null) provider = location.getParent(); assertProvider(provider); + assert location.getIso3166Codes().size() == 0 + || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + + " ||" + location.getParent(); break; case HOST: Location provider2 = location.getParent().getParent().getParent(); @@ -108,9 +117,10 @@ public class BaseServiceIntegrationTest extends BaseBlobStoreIntegrationTest { } } - public void assertProvider(Location provider) { + void assertProvider(Location provider) { assertEquals(provider.getScope(), LocationScope.PROVIDER); assertEquals(provider.getParent(), null); + assertEquals(provider.getIso3166Codes(), getIso3166Codes()); } } \ No newline at end of file diff --git a/blobstore/src/test/java/org/jclouds/blobstore/strategy/internal/BiggerThanPageSizeTest.java b/blobstore/src/test/java/org/jclouds/blobstore/strategy/internal/BiggerThanPageSizeTest.java index 5f91aae19d..0354cba0ac 100644 --- a/blobstore/src/test/java/org/jclouds/blobstore/strategy/internal/BiggerThanPageSizeTest.java +++ b/blobstore/src/test/java/org/jclouds/blobstore/strategy/internal/BiggerThanPageSizeTest.java @@ -25,10 +25,7 @@ import java.io.IOException; import org.jclouds.blobstore.BlobStore; import org.jclouds.blobstore.BlobStoreContextFactory; -import org.jclouds.blobstore.domain.Blob; import org.jclouds.blobstore.options.ListContainerOptions; -import org.jclouds.blobstore.strategy.internal.ConcatenateContainerLists; -import org.jclouds.blobstore.strategy.internal.ListContainerAndRecurseThroughFolders; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -48,9 +45,7 @@ public class BiggerThanPageSizeTest { public void test() throws IOException { blobstore.createContainerInLocation(null, "goodies"); for (int i = 0; i < 1001; i++) { - Blob blob = blobstore.newBlob(i + ""); - blob.setPayload(i + ""); - blobstore.putBlob("goodies", blob); + blobstore.putBlob("goodies", blobstore.blobBuilder(i + "").payload(i + "").build()); } assertEquals(blobstore.countBlobs("goodies"), 1001); blobstore.clearContainer("goodies"); @@ -60,9 +55,7 @@ public class BiggerThanPageSizeTest { public void testStrategies() throws IOException { blobstore.createContainerInLocation(null, "poo"); for (int i = 0; i < 1001; i++) { - Blob blob = blobstore.newBlob(i + ""); - blob.setPayload(i + ""); - blobstore.putBlob("poo", blob); + blobstore.putBlob("poo", blobstore.blobBuilder(i + "").payload(i + "").build()); } ListContainerAndRecurseThroughFolders lister = new ListContainerAndRecurseThroughFolders( diff --git a/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java b/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java index 06075ba138..8dd375b5be 100644 --- a/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java +++ b/common/aws/src/main/java/org/jclouds/aws/config/AWSRestClientModule.java @@ -25,6 +25,7 @@ import java.net.URI; import java.util.Map; import java.util.Set; +import javax.annotation.Nullable; import javax.inject.Singleton; import org.jclouds.aws.handlers.AWSClientErrorRetryHandler; @@ -79,12 +80,13 @@ public class AWSRestClientModule extends RestClientModule { @Provides @Singleton + @Nullable @Region protected String getDefaultRegion(@Provider URI uri, @Region Map map, LoggerFactory logFactory) { String region = ImmutableBiMap.copyOf(map).inverse().get(uri); - if (region == null) { + if (region == null && map.size() > 0) { logFactory.getLogger(getClass().getName()).warn( - "failed to find region for current endpoint %s in %s; choosing first: %s", uri, map, region); + "failed to find region for current endpoint %s in %s; choosing first: %s", uri, map, region); region = get(map.keySet(), 0); } return region; diff --git a/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java b/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java index 3e1613b4fc..76c06390d7 100755 --- a/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java +++ b/common/aws/src/main/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContent.java @@ -82,7 +82,7 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler { } } message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(), - response.getStatusLine()); + response.getStatusLine()); exception = refineException(command, response, exception, error, message); } finally { releasePayload(response); @@ -91,33 +91,36 @@ public class ParseAWSErrorFromXmlContent implements HttpErrorHandler { } protected Exception refineException(HttpCommand command, HttpResponse response, Exception exception, AWSError error, - String message) { + String message) { switch (response.getStatusCode()) { - case 400: - if (error != null && error.getCode() != null && (error.getCode().equals("UnsupportedOperation"))) - exception = new UnsupportedOperationException(message, exception); - if (error != null && error.getCode() != null - && (error.getCode().endsWith("NotFound") || error.getCode().endsWith(".Unknown"))) - exception = new ResourceNotFoundException(message, exception); - else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error - .getCode().endsWith(".Duplicate"))) || (message != null && (message.indexOf("already exists") != -1))) - exception = new IllegalStateException(message, exception); - else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure")) + case 400: + if (error != null && error.getCode() != null && (error.getCode().equals("UnsupportedOperation"))) + exception = new UnsupportedOperationException(message, exception); + if (error != null && error.getCode() != null + && (error.getCode().endsWith("NotFound") || error.getCode().endsWith(".Unknown"))) + exception = new ResourceNotFoundException(message, exception); + else if ((error != null && error.getCode() != null && (error.getCode().equals("IncorrectState") || error + .getCode().endsWith(".Duplicate") + | error.getCode().endsWith(".InUse"))) + || (message != null && (message.indexOf("already exists") != -1 || message.indexOf("is in use") != -1))) + exception = new IllegalStateException(message, exception); + else if (error != null && error.getCode() != null && error.getCode().equals("AuthFailure")) + exception = new AuthorizationException(message, exception); + else if (message != null + && (message.indexOf("Invalid id") != -1 || message.indexOf("Failed to bind") != -1)) + exception = new IllegalArgumentException(message, exception); + break; + case 401: + case 403: exception = new AuthorizationException(message, exception); - else if (message != null && message.indexOf("Failed to bind the following fields") != -1)// Nova - exception = new IllegalArgumentException(message, exception); - break; - case 401: - case 403: - exception = new AuthorizationException(message, exception); - break; - case 404: - if (!command.getCurrentRequest().getMethod().equals("DELETE")) { - exception = new ResourceNotFoundException(message, exception); - } - break; - case 409: - exception = new IllegalStateException(message, exception); + break; + case 404: + if (!command.getCurrentRequest().getMethod().equals("DELETE")) { + exception = new ResourceNotFoundException(message, exception); + } + break; + case 409: + exception = new IllegalStateException(message, exception); } return exception; } diff --git a/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java b/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java index e30a6aa5c5..c52703e78a 100644 --- a/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java +++ b/common/aws/src/test/java/org/jclouds/aws/filters/FormSignerTest.java @@ -51,7 +51,7 @@ import com.google.inject.name.Names; public class FormSignerTest { @SuppressWarnings("unchecked") public static final RestContextSpec DUMMY_SPEC = new RestContextSpec("provider", "endpoint", - "apiVersion", "identity", "credential", Map.class, List.class, PropertiesBuilder.class, + "apiVersion", "", "identity", "credential", Map.class, List.class, PropertiesBuilder.class, (Class) RestContextBuilder.class, ImmutableList. of(new MockModule(), new NullLoggingModule(), new AbstractModule() { @Override diff --git a/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java b/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java index 00fd23b35c..fee547ece9 100644 --- a/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java +++ b/common/aws/src/test/java/org/jclouds/aws/handlers/ParseAWSErrorFromXmlContentTest.java @@ -54,87 +54,106 @@ public class ParseAWSErrorFromXmlContentTest { @Test public void test400WithNotFoundSetsResourceNotFoundException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "Monster.NotFound", ResourceNotFoundException.class); + "Monster.NotFound", ResourceNotFoundException.class); + } + + @Test + public void test400WithInvalidIdIllegalArgumentException() { + assertCodeMakes("POST", URI.create("https://ec2.us-east-1.amazonaws.com"), 400, "HTTP/1.1 400", "", + "Invalid id: \"asdaasdsa\" (expecting \"ami-...\")", IllegalArgumentException.class); } @Test public void test400WithLoadBalancerNotFoundSetsResourceNotFoundException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "LoadBalancerNotFound", ResourceNotFoundException.class); + "LoadBalancerNotFound", ResourceNotFoundException.class); } @Test public void test400WithUnsupportedCodeMakesUnsupportedOperationException() { assertCodeMakes("POST", URI.create("https://ec2.us-west-1.amazonaws.com/"), 400, "", - "UnsupportedOperation", UnsupportedOperationException.class); + "UnsupportedOperation", UnsupportedOperationException.class); + } + + @Test + public void test400WithInUseCodeSetsIllegalStateException() { + assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", + "InvalidPlacementGroup.InUse", IllegalStateException.class); } @Test public void test400WithUnknownSetsResourceNotFoundException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "InvalidPlacementGroup.Unknown", ResourceNotFoundException.class); + "InvalidPlacementGroup.Unknown", ResourceNotFoundException.class); } @Test public void test400WithIncorrectStateSetsIllegalStateException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "IncorrectState", IllegalStateException.class); + "IncorrectState", IllegalStateException.class); + } + + @Test + public void test400WithInUseSetsIllegalStateException() { + assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", "text/plain", + "The placement group 'jclouds#adriancoleec2cccluster#us-east-1' is in use and may not be deleted.", + IllegalStateException.class); } @Test public void test409SetsIllegalStateException() { assertCodeMakes( - "PUT", - URI.create("https://adriancole-blobstore011.s3.amazonaws.com/"), - 409, - "", - "OperationAbortedA conflicting conditional operation is currently in progress against this resource. Please try again.F716E81C3D814E59SDprHxWzG/YXzanVnV7VTz/wP+6fRt1dS+q00kH1rz248YOOSddkFiTXF04XtqNO", - IllegalStateException.class); + "PUT", + URI.create("https://adriancole-blobstore011.s3.amazonaws.com/"), + 409, + "", + "OperationAbortedA conflicting conditional operation is currently in progress against this resource. Please try again.F716E81C3D814E59SDprHxWzG/YXzanVnV7VTz/wP+6fRt1dS+q00kH1rz248YOOSddkFiTXF04XtqNO", + IllegalStateException.class); } @Test public void test400WithInvalidGroupDuplicateIllegalStateException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "application/unknown", - "InvalidGroup.Duplicate", IllegalStateException.class); + "InvalidGroup.Duplicate", IllegalStateException.class); } @Test public void test400WithInvalidKeyPairGroupDuplicateIllegalStateException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "application/unknown", - "InvalidKeyPair.Duplicate", IllegalStateException.class); + "InvalidKeyPair.Duplicate", IllegalStateException.class); } @Test public void test400WithTextPlainIllegalArgumentException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "Bad Request", "text/plain", - "Failure: 400 Bad Request\nFailed to bind the following fields\nMonitoring.Enabled = true\n\n\n", - IllegalArgumentException.class); + "Failure: 400 Bad Request\nFailed to bind the following fields\nMonitoring.Enabled = true\n\n\n", + IllegalArgumentException.class); } @Test public void test400WithGroupAlreadyExistsEucalyptusIllegalStateException() { assertCodeMakes( - "GET", - URI.create("https://amazonaws.com/foo"), - 400, - "", - "Groups\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists\nError adding network group: group named jclouds#eucrun#Eucalyptus already existse0133975-3bc5-456d-9753-1d61b27e07e9", - IllegalStateException.class); + "GET", + URI.create("https://amazonaws.com/foo"), + 400, + "", + "Groups\nError adding network group: group named jclouds#eucrun#Eucalyptus already exists\nError adding network group: group named jclouds#eucrun#Eucalyptus already existse0133975-3bc5-456d-9753-1d61b27e07e9", + IllegalStateException.class); } @Test public void test400WithAuthFailureSetsAuthorizationException() { assertCodeMakes("GET", URI.create("https://amazonaws.com/foo"), 400, "", - "AuthFailure", AuthorizationException.class); + "AuthFailure", AuthorizationException.class); } private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content, - Class expected) { + Class expected) { assertCodeMakes(method, uri, statusCode, message, "text/xml", content, expected); } private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType, - String content, Class expected) { + String content, Class expected) { ParseAWSErrorFromXmlContent function = Guice.createInjector(new SaxParserModule(), new AbstractModule() { @@ -149,7 +168,7 @@ public class ParseAWSErrorFromXmlContentTest { HttpCommand command = createMock(HttpCommand.class); HttpRequest request = new HttpRequest(method, uri); HttpResponse response = new HttpResponse(statusCode, message, Payloads.newInputStreamPayload(Strings2 - .toInputStream(content))); + .toInputStream(content))); response.getPayload().getContentMetadata().setContentType(contentType); expect(command.getCurrentRequest()).andReturn(request).atLeastOnce(); diff --git a/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java b/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java index 617900f00d..acf082ab5d 100755 --- a/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java +++ b/common/azure/src/test/java/org/jclouds/azure/storage/filters/SharedKeyLiteAuthenticationTest.java @@ -139,8 +139,9 @@ public class SharedKeyLiteAuthenticationTest { @SuppressWarnings("unchecked") public static final RestContextSpec DUMMY_SPEC = new RestContextSpec("provider", "endpoint", - "apiVersion", "identity", "credential", Map.class, List.class, PropertiesBuilder.class, + "apiVersion", "", "identity", "credential", Map.class, List.class, PropertiesBuilder.class, (Class) RestContextBuilder.class, ImmutableList. of(new MockModule(), new NullLoggingModule(), - new AzureStorageRestClientModule(Exception.class, RuntimeException.class))); + new AzureStorageRestClientModule(Exception.class, + RuntimeException.class))); } \ No newline at end of file diff --git a/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java b/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java index 052fab388e..d9ed86b50c 100644 --- a/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java +++ b/common/azure/src/test/java/org/jclouds/azure/storage/handlers/ParseAzureErrorFromXmlContentTest.java @@ -63,6 +63,7 @@ public class ParseAzureErrorFromXmlContentTest { "", IllegalArgumentException.class); } + @Test public void test412WithTextHtmlHttpResponseException() { assertCodeMakes( diff --git a/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java b/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java index 281db9b27d..a77674bcdb 100755 --- a/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java +++ b/common/openstack/src/test/java/org/jclouds/openstack/OpenStackAuthAsyncClientTest.java @@ -63,8 +63,8 @@ public class OpenStackAuthAsyncClientTest extends RestClientTest createContextSpec() { - return contextSpec("test", "http://localhost:8080", "1.0", "identity", "credential", OpenStackAuthClient.class, - OpenStackAuthAsyncClient.class); + return contextSpec("test", "http://localhost:8080", "1.0", "", "identity", "credential", + OpenStackAuthClient.class, OpenStackAuthAsyncClient.class); } @Override diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClient.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClient.java index 899ba69813..6737eac568 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClient.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudAsyncClient.java @@ -47,7 +47,7 @@ import org.jclouds.predicates.validators.DnsNameValidator; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.ParamValidators; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; @@ -191,8 +191,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient { @XMLResponseParser(VCloudExpressVAppHandler.class) @MapBinder(TerremarkBindInstantiateVAppTemplateParamsToXmlPayload.class) ListenableFuture instantiateVAppTemplateInVDC(@EndpointParam URI vdc, - @MapPayloadParam("template") URI template, - @MapPayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, + @PayloadParam("template") URI template, + @PayloadParam("name") @ParamValidators(DnsNameValidator.class) String appName, InstantiateVAppTemplateOptions... options); /** @@ -215,8 +215,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient { @XMLResponseParser(InternetServiceHandler.class) @MapBinder(AddInternetServiceOptions.class) ListenableFuture addInternetServiceToExistingIp(@EndpointParam URI publicIpId, - @MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol, - @MapPayloadParam("port") int port, AddInternetServiceOptions... options); + @PayloadParam("name") String serviceName, @PayloadParam("protocol") Protocol protocol, + @PayloadParam("port") int port, AddInternetServiceOptions... options); /** * @see TerremarkVCloudExpressClient#deletePublicIp @@ -280,8 +280,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient { @XMLResponseParser(NodeHandler.class) @MapBinder(AddNodeOptions.class) ListenableFuture addNode(@EndpointParam URI internetServiceId, - @MapPayloadParam("ipAddress") String ipAddress, @MapPayloadParam("name") String name, - @MapPayloadParam("port") int port, AddNodeOptions... options); + @PayloadParam("ipAddress") String ipAddress, @PayloadParam("name") String name, + @PayloadParam("port") int port, AddNodeOptions... options); /** * @see TerremarkVCloudExpressClient#getNodes @@ -310,8 +310,8 @@ public interface TerremarkVCloudAsyncClient extends VCloudExpressAsyncClient { @Consumes(NODESERVICE_XML) @XMLResponseParser(NodeHandler.class) @MapBinder(BindNodeConfigurationToXmlPayload.class) - ListenableFuture configureNode(@EndpointParam URI nodeId, @MapPayloadParam("name") String name, - @MapPayloadParam("enabled") boolean enabled, @Nullable @MapPayloadParam("description") String description); + ListenableFuture configureNode(@EndpointParam URI nodeId, @PayloadParam("name") String name, + @PayloadParam("enabled") boolean enabled, @Nullable @PayloadParam("description") String description); /** * @see TerremarkVCloudExpressClient#deleteNode diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudClient.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudClient.java index bb6d3d5955..3239407105 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudClient.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudClient.java @@ -51,19 +51,33 @@ import org.jclouds.vcloud.terremark.options.AddNodeOptions; */ @Timeout(duration = 300, timeUnit = TimeUnit.SECONDS) public interface TerremarkVCloudClient extends VCloudExpressClient { - + /** + * {@inheritDoc} + */ @Override TerremarkCatalogItem getCatalogItem(URI catalogItem); + /** + * {@inheritDoc} + */ @Override TerremarkVDC getVDC(URI catalogItem); + /** + * {@inheritDoc} + */ @Override TerremarkCatalogItem findCatalogItemInOrgCatalogNamed(String orgName, String catalogName, String itemName); + /** + * {@inheritDoc} + */ @Override TerremarkOrg getOrg(URI orgId); + /** + * {@inheritDoc} + */ @Override TerremarkOrg findOrgNamed(String orgName); diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java index 54264ca16b..66ac91e874 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudComputeService.java @@ -45,7 +45,7 @@ import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; @@ -69,7 +69,7 @@ public class TerremarkVCloudComputeService extends BaseComputeService { protected TerremarkVCloudComputeService(ComputeServiceContext context, Map credentialStore, @Memoized Supplier> images, @Memoized Supplier> sizes, @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, + GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy, Provider templateBuilderProvider, Provider templateOptionsProvider, diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkBindComputeStrategiesByClass.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkBindComputeStrategiesByClass.java index ddda7bfd16..20f280945c 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkBindComputeStrategiesByClass.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkBindComputeStrategiesByClass.java @@ -19,23 +19,23 @@ package org.jclouds.vcloud.terremark.compute.config; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.vcloud.compute.config.VCloudExpressBindComputeStrategiesByClass; import org.jclouds.vcloud.terremark.compute.strategy.TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy; -import org.jclouds.vcloud.terremark.compute.strategy.TerremarkVCloudAddNodeWithTagStrategy; +import org.jclouds.vcloud.terremark.compute.strategy.StartVAppWithGroupEncodedIntoName; /** * @author Adrian Cole */ public class TerremarkBindComputeStrategiesByClass extends VCloudExpressBindComputeStrategiesByClass { @Override - protected Class defineRunNodesAndAddToSetStrategy() { + protected Class defineRunNodesAndAddToSetStrategy() { return TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.class; } @Override - protected Class defineAddNodeWithTagStrategy() { - return TerremarkVCloudAddNodeWithTagStrategy.class; + protected Class defineAddNodeWithTagStrategy() { + return StartVAppWithGroupEncodedIntoName.class; } } \ No newline at end of file diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/functions/NodeMetadataToOrgAndName.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/functions/NodeMetadataToOrgAndName.java index cf61611705..c8d3219de1 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/functions/NodeMetadataToOrgAndName.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/functions/NodeMetadataToOrgAndName.java @@ -61,12 +61,12 @@ public class NodeMetadataToOrgAndName implements Function orgTags = filter(transform(deadOnes, nodeToOrgAndName), notNull()); - for (OrgAndName orgTag : orgTags) { - Iterable nodesInOrg = listNodes.listDetailsOnNodesMatching(parentLocationId(orgTag + Iterable orgGroups = filter(transform(deadOnes, nodeToOrgAndName), notNull()); + for (OrgAndName orgGroup : orgGroups) { + Iterable nodesInOrg = listNodes.listDetailsOnNodesMatching(parentLocationId(orgGroup .getOrg().toASCIIString())); - Iterable nodesWithTag = filter(nodesInOrg, withTag(orgTag.getName())); - if (size(nodesWithTag) == 0 || all(nodesWithTag, TERMINATED)) - deleteKeyPair.execute(orgTag); + Iterable nodesInGroup = filter(nodesInOrg, inGroup(orgGroup.getName())); + if (size(nodesInGroup) == 0 || all(nodesInGroup, TERMINATED)) + deleteKeyPair.execute(orgGroup); } } diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/TerremarkVCloudAddNodeWithTagStrategy.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/StartVAppWithGroupEncodedIntoName.java similarity index 90% rename from common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/TerremarkVCloudAddNodeWithTagStrategy.java rename to common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/StartVAppWithGroupEncodedIntoName.java index 0a1789e570..c8e11bef6f 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/TerremarkVCloudAddNodeWithTagStrategy.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/StartVAppWithGroupEncodedIntoName.java @@ -30,7 +30,7 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.Template; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.domain.Credentials; import org.jclouds.vcloud.domain.VCloudExpressVApp; import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeClient; @@ -43,14 +43,14 @@ import com.google.common.base.Function; * @author Adrian Cole */ @Singleton -public class TerremarkVCloudAddNodeWithTagStrategy implements AddNodeWithTagStrategy { +public class StartVAppWithGroupEncodedIntoName implements CreateNodeWithGroupEncodedIntoName { protected final TerremarkVCloudComputeClient computeClient; protected final TemplateToInstantiateOptions getOptions; protected final Function vAppToNodeMetadata; private final Map credentialStore; @Inject - protected TerremarkVCloudAddNodeWithTagStrategy(TerremarkVCloudComputeClient computeClient, + protected StartVAppWithGroupEncodedIntoName(TerremarkVCloudComputeClient computeClient, Function vAppToNodeMetadata, TemplateToInstantiateOptions getOptions, Map credentialStore) { this.computeClient = computeClient; @@ -60,7 +60,7 @@ public class TerremarkVCloudAddNodeWithTagStrategy implements AddNodeWithTagStra } @Override - public NodeMetadata addNodeWithTag(String tag, String name, Template template) { + public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { TerremarkInstantiateVAppTemplateOptions options = getOptions.apply(template); VCloudExpressVApp vApp = computeClient.start(URI.create(template.getLocation().getId()), URI.create(template .getImage().getId()), name, options, template.getOptions().getInboundPorts()); diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java index 47f52204d1..b3062d13c2 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/compute/strategy/TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy.java @@ -33,10 +33,10 @@ import org.jclouds.Constants; import org.jclouds.compute.config.CustomizationResponse; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; -import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; import org.jclouds.domain.LocationScope; import org.jclouds.vcloud.terremark.compute.options.TerremarkVCloudTemplateOptions; @@ -48,13 +48,13 @@ import com.google.common.collect.Multimap; * @author Adrian Cole */ @Singleton -public class TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy extends EncodeTagIntoNameRunNodesAndAddToSetStrategy { +public class TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy extends CreateNodesWithGroupEncodedIntoNameThenAddToSet { private final CreateNewKeyPairUnlessUserSpecifiedOtherwise createNewKeyPairUnlessUserSpecifiedOtherwise; @Inject protected TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy( - AddNodeWithTagStrategy addNodeWithTagStrategy, + CreateNodeWithGroupEncodedIntoName addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy, @Named("NAMING_CONVENTION") String nodeNamingConvention, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponse.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponse.java index 2426af62cf..482d0500c0 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponse.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponse.java @@ -34,6 +34,7 @@ import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponseException; import org.jclouds.logging.Logger; import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.InsufficientResourcesException; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.util.Strings2; @@ -61,6 +62,9 @@ public class ParseTerremarkVCloudErrorFromHttpResponse implements HttpErrorHandl || (response.getMessage().indexOf("because it is already powered off") != -1) || (response.getMessage().indexOf("exists") != -1))) exception = new IllegalStateException(response.getMessage(), exception); + else if (response.getMessage() != null + && ((response.getMessage().indexOf("There are no additional Public IPs available") != -1))) + exception = new InsufficientResourcesException(response.getMessage(), exception); else switch (response.getStatusCode()) { case 400: diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/CustomizationParametersHandler.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/CustomizationParametersHandler.java index 50ba368606..ba84a692cc 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/CustomizationParametersHandler.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/CustomizationParametersHandler.java @@ -39,17 +39,19 @@ public class CustomizationParametersHandler extends HandlerWithResult { } public void endElement(String uri, String name, String qName) { - if (qName.equals("Href") && currentOrNull() != null) { - if (inPublicIpAddress) - addressLocation = URI.create(currentOrNull()); - else - location = URI.create(currentOrNull()); - } else if (qName.equals("Name")) { - if (inPublicIpAddress) - address = currentOrNull(); - else - serviceName = currentOrNull(); - } else if (qName.equals("PublicIpAddress")) { + String current = currentOrNull(); + if (qName.equals("PublicIpAddress")) { publicIpAddress = new PublicIpAddress(address, addressLocation); address = null; addressLocation = null; inPublicIpAddress = false; - } else if (qName.equals("Port")) { - port = Integer.parseInt(currentOrNull()); - } else if (qName.equals("Protocol")) { - protocol = Protocol.valueOf(currentOrNull()); - } else if (qName.equals("Enabled")) { - enabled = Boolean.parseBoolean(currentOrNull()); - } else if (qName.equals("Timeout")) { - timeout = Integer.parseInt(currentOrNull()); - } else if (qName.equals("Description")) { - description = currentOrNull(); + } else if (current != null) { + if (qName.equals("Href")) { + if (inPublicIpAddress) + addressLocation = URI.create(current); + else + location = URI.create(current); + } else if (qName.equals("Name")) { + if (inPublicIpAddress) + address = current; + else + serviceName = current; + } else if (qName.equals("Port")) { + port = Integer.parseInt(current); + } else if (qName.equals("Protocol")) { + protocol = Protocol.valueOf(current); + } else if (qName.equals("Enabled")) { + enabled = Boolean.parseBoolean(current); + } else if (qName.equals("Timeout")) { + timeout = Integer.parseInt(current); + } else if (qName.equals("Description")) { + description = current; + } } currentText = new StringBuilder(); } diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/IpAddressesHandler.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/IpAddressesHandler.java index 8b99aa53ce..abb6f6cb66 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/IpAddressesHandler.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/IpAddressesHandler.java @@ -53,8 +53,7 @@ public class IpAddressesHandler extends ParseSax.HandlerWithResult { } public void endElement(String uri, String name, String qName) { - if (qName.equals("Href") && currentOrNull() != null) { - location = URI.create(currentOrNull()); - } else if (qName.equals("Name")) { - this.name = currentOrNull(); - } else if (qName.equals("IsDefault")) { - isDefault = Boolean.parseBoolean(currentOrNull()); - } else if (qName.equals("PrivateKey")) { - privateKey = currentOrNull(); - } else if (qName.equals("FingerPrint")) { - fingerPrint = currentOrNull(); + String current = currentOrNull(); + if (current != null) { + if (qName.equals("Href")) { + location = URI.create(current); + } else if (qName.equals("Name")) { + this.name = current; + } else if (qName.equals("IsDefault")) { + isDefault = Boolean.parseBoolean(current); + } else if (qName.equals("PrivateKey")) { + privateKey = current; + } else if (qName.equals("FingerPrint")) { + fingerPrint = current; + } } currentText = new StringBuilder(); } diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/NodeHandler.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/NodeHandler.java index a313445d0c..8e731cef25 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/NodeHandler.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/NodeHandler.java @@ -54,18 +54,21 @@ public class NodeHandler extends HandlerWithResult { } public void endElement(String uri, String name, String qName) { - if (qName.equals("Href") && currentOrNull() != null) { - location = URI.create(currentOrNull()); - } else if (qName.equals("Name")) { - serviceName = currentOrNull(); - } else if (qName.equals("Port")) { - port = Integer.parseInt(currentOrNull()); - } else if (qName.equals("Enabled")) { - enabled = Boolean.parseBoolean(currentOrNull()); - } else if (qName.equals("IpAddress")) { - address = currentOrNull(); - } else if (qName.equals("Description")) { - description = currentOrNull(); + String current = currentOrNull(); + if (current != null) { + if (qName.equals("Href")) { + location = URI.create(current); + } else if (qName.equals("Name")) { + serviceName = current; + } else if (qName.equals("Port")) { + port = Integer.parseInt(current); + } else if (qName.equals("Enabled")) { + enabled = Boolean.parseBoolean(current); + } else if (qName.equals("IpAddress")) { + address = current; + } else if (qName.equals("Description")) { + description = current; + } } currentText = new StringBuilder(); } diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/PublicIpAddressHandler.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/PublicIpAddressHandler.java index d9e17c164e..afc81d5ae2 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/PublicIpAddressHandler.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/PublicIpAddressHandler.java @@ -52,10 +52,13 @@ public class PublicIpAddressHandler extends HandlerWithResult { } public void endElement(String uri, String name, String qName) { - if (qName.equals("Href") && currentOrNull() != null) { - location = URI.create(currentOrNull()); - } else if (qName.equals("Name")) { - address = currentOrNull(); + String current = currentOrNull(); + if (current != null) { + if (qName.equals("Href")) { + location = URI.create(current); + } else if (qName.equals("Name")) { + address = current; + } } currentText = new StringBuilder(); } diff --git a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/TerremarkNetworkHandler.java b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/TerremarkNetworkHandler.java index c19bfe954c..e02d92b410 100644 --- a/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/TerremarkNetworkHandler.java +++ b/common/trmk/src/main/java/org/jclouds/vcloud/terremark/xml/TerremarkNetworkHandler.java @@ -60,26 +60,29 @@ public class TerremarkNetworkHandler extends HandlerWithResult } public void endElement(String uri, String name, String qName) { - if (qName.equals("Href") && currentOrNull() != null) { - href = URI.create(currentOrNull()); - } else if (qName.equals("Id")) { - id = currentOrNull(); - } else if (qName.equals("Name")) { - this.name = currentOrNull(); - } else if (qName.equals("RnatAddress")) { - rnatAddress = currentOrNull(); - } else if (qName.equals("Address")) { - address = currentOrNull(); - } else if (qName.equals("BroadcastAddress")) { - broadcastAddress = currentOrNull(); - } else if (qName.equals("GatewayAddress")) { - gatewayAddress = currentOrNull(); - } else if (qName.equals("NetworkType")) { - networkType = TerremarkNetwork.Type.fromValue(currentOrNull()); - } else if (qName.equals("Vlan")) { - vlan = currentOrNull(); - } else if (qName.equals("FriendlyName")) { - friendlyName = currentOrNull(); + String current = currentOrNull(); + if (current != null) { + if (qName.equals("Href")) { + href = URI.create(current); + } else if (qName.equals("Id")) { + id = current; + } else if (qName.equals("Name")) { + this.name = current; + } else if (qName.equals("RnatAddress")) { + rnatAddress = current; + } else if (qName.equals("Address")) { + address = current; + } else if (qName.equals("BroadcastAddress")) { + broadcastAddress = current; + } else if (qName.equals("GatewayAddress")) { + gatewayAddress = current; + } else if (qName.equals("NetworkType")) { + networkType = TerremarkNetwork.Type.fromValue(current); + } else if (qName.equals("Vlan")) { + vlan = current; + } else if (qName.equals("FriendlyName")) { + friendlyName = current; + } } currentText = new StringBuilder(); } diff --git a/common/trmk/src/test/resources/terremark/ConfigureInternetService.xml b/common/trmk/src/main/resources/terremark/ConfigureInternetService.xml similarity index 100% rename from common/trmk/src/test/resources/terremark/ConfigureInternetService.xml rename to common/trmk/src/main/resources/terremark/ConfigureInternetService.xml diff --git a/common/trmk/src/test/resources/terremark/CreateInternetService.xml b/common/trmk/src/main/resources/terremark/CreateInternetService.xml similarity index 100% rename from common/trmk/src/test/resources/terremark/CreateInternetService.xml rename to common/trmk/src/main/resources/terremark/CreateInternetService.xml diff --git a/common/trmk/src/test/resources/terremark/CreateKey.xml b/common/trmk/src/main/resources/terremark/CreateKey.xml similarity index 100% rename from common/trmk/src/test/resources/terremark/CreateKey.xml rename to common/trmk/src/main/resources/terremark/CreateKey.xml diff --git a/common/trmk/src/test/resources/terremark/CreateNodeService.xml b/common/trmk/src/main/resources/terremark/CreateNodeService.xml similarity index 100% rename from common/trmk/src/test/resources/terremark/CreateNodeService.xml rename to common/trmk/src/main/resources/terremark/CreateNodeService.xml diff --git a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/TerremarkClientLiveTest.java b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/TerremarkClientLiveTest.java index 8baf7694bf..5c58625632 100644 --- a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/TerremarkClientLiveTest.java +++ b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/TerremarkClientLiveTest.java @@ -220,16 +220,13 @@ public abstract class TerremarkClientLiveTest extends VCloudExpressClientLiveTes abstract TerremarkInstantiateVAppTemplateOptions createInstantiateOptions(); - protected abstract Entry getNewInternetServiceAndIpForSSH(URI vdc); + protected abstract Entry getNewInternetServiceAndIpForSSH(VCloudExpressVApp vApp); - @Test + @Test(enabled = true, dependsOnMethods = "testInstantiateAndPowerOn") public void testAddInternetService() throws InterruptedException, ExecutionException, TimeoutException, IOException { - - Entry entry = getNewInternetServiceAndIpForSSH(tmClient.findVDCInOrgNamed(null, - null).getHref()); + Entry entry = getNewInternetServiceAndIpForSSH(vApp); is = entry.getKey(); publicIp = entry.getValue().getAddress(); - } @Test(enabled = true, dependsOnMethods = "testInstantiateAndPowerOn") diff --git a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/compute/strategy/CleanupOrphanKeysTest.java b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/compute/strategy/CleanupOrphanKeysTest.java index 30110cb7a4..5a06f15d76 100644 --- a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/compute/strategy/CleanupOrphanKeysTest.java +++ b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/compute/strategy/CleanupOrphanKeysTest.java @@ -88,13 +88,13 @@ public class CleanupOrphanKeysTest { CleanupOrphanKeys strategy = setupStrategy(); NodeMetadata nodeMetadata = createMock(NodeMetadata.class); Iterable deadOnes = ImmutableSet. of(nodeMetadata); - OrgAndName orgTag = new OrgAndName(URI.create("location"), "tag"); + OrgAndName orgTag = new OrgAndName(URI.create("location"), "group"); // setup expectations expect(strategy.nodeToOrgAndName.apply(nodeMetadata)).andReturn(orgTag).atLeastOnce(); expect((Object) strategy.listNodes.listDetailsOnNodesMatching(parentLocationId(orgTag.getOrg().toASCIIString()))) .andReturn(ImmutableSet.of(nodeMetadata)); - expect(nodeMetadata.getTag()).andReturn(orgTag.getName()).atLeastOnce(); + expect(nodeMetadata.getGroup()).andReturn(orgTag.getName()).atLeastOnce(); expect(nodeMetadata.getState()).andReturn(NodeState.RUNNING).atLeastOnce(); expectCleanupCredentialStore(strategy, nodeMetadata); @@ -115,13 +115,13 @@ public class CleanupOrphanKeysTest { CleanupOrphanKeys strategy = setupStrategy(); NodeMetadata nodeMetadata = createMock(NodeMetadata.class); Iterable deadOnes = ImmutableSet. of(nodeMetadata); - OrgAndName orgTag = new OrgAndName(URI.create("location"), "tag"); + OrgAndName orgTag = new OrgAndName(URI.create("location"), "group"); // setup expectations expect(strategy.nodeToOrgAndName.apply(nodeMetadata)).andReturn(orgTag).atLeastOnce(); expect((Object) strategy.listNodes.listDetailsOnNodesMatching(parentLocationId(orgTag.getOrg().toASCIIString()))) .andReturn(ImmutableSet.of(nodeMetadata)); - expect(nodeMetadata.getTag()).andReturn(orgTag.getName()).atLeastOnce(); + expect(nodeMetadata.getGroup()).andReturn(orgTag.getName()).atLeastOnce(); expect(nodeMetadata.getState()).andReturn(NodeState.TERMINATED).atLeastOnce(); strategy.deleteKeyPair.execute(orgTag); expectCleanupCredentialStore(strategy, nodeMetadata); @@ -149,7 +149,7 @@ public class CleanupOrphanKeysTest { CleanupOrphanKeys strategy = setupStrategy(); NodeMetadata nodeMetadata = createMock(NodeMetadata.class); Iterable deadOnes = ImmutableSet. of(nodeMetadata); - OrgAndName orgTag = new OrgAndName(URI.create("location"), "tag"); + OrgAndName orgTag = new OrgAndName(URI.create("location"), "group"); // setup expectations expect(strategy.nodeToOrgAndName.apply(nodeMetadata)).andReturn(orgTag).atLeastOnce(); diff --git a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponseTest.java b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponseTest.java index 1c1365a1cc..b43b5c1650 100644 --- a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponseTest.java +++ b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/handlers/ParseTerremarkVCloudErrorFromHttpResponseTest.java @@ -24,6 +24,7 @@ import java.net.URI; import org.jclouds.http.BaseHttpErrorHandlerTest; import org.jclouds.http.HttpErrorHandler; import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.InsufficientResourcesException; import org.jclouds.rest.ResourceNotFoundException; import org.testng.annotations.Test; @@ -71,6 +72,12 @@ public class ParseTerremarkVCloudErrorFromHttpResponseTest extends BaseHttpError "", "", AuthorizationException.class); } + @Test + public void test403SetsInsufficientResourcesException() { + assertCodeMakes("GET", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/vdc/32"), 403, + "There are no additional Public IPs available", "", InsufficientResourcesException.class); + } + @Test public void test501SetsNotImplementedMakesUnsupportedOperationException() { assertCodeMakes("POST", URI @@ -87,11 +94,12 @@ public class ParseTerremarkVCloudErrorFromHttpResponseTest extends BaseHttpError @Test public void testKeyAlreadyExistsSetsIllegalStateException() { - assertCodeMakes("POST", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/extensions/org/48/keys"), 400, + assertCodeMakes("POST", URI + .create("https://services.vcloudexpress.terremark.com/api/v0.8a-ext1.6/extensions/org/48/keys"), 400, "Security key with name livetest exists.", "Security key with name livetest exists.", IllegalStateException.class); } - + @Override protected Class getHandlerClass() { return ParseTerremarkVCloudErrorFromHttpResponse.class; diff --git a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/xml/InternetServicesHandlerTest.java b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/xml/InternetServicesHandlerTest.java index eb315e2d0a..6d1bab2491 100644 --- a/common/trmk/src/test/java/org/jclouds/vcloud/terremark/xml/InternetServicesHandlerTest.java +++ b/common/trmk/src/test/java/org/jclouds/vcloud/terremark/xml/InternetServicesHandlerTest.java @@ -43,13 +43,21 @@ import com.google.common.collect.ImmutableSet; @Test(groups = "unit", testName = "InternetServicesHandlerTest") public class InternetServicesHandlerTest extends BaseHandlerTest { - public void test2() throws UnknownHostException { + public void test() throws UnknownHostException { InputStream is = getClass().getResourceAsStream("/terremark/InternetServices.xml"); Set result = factory.create(injector.getInstance(InternetServicesHandler.class)).parse(is); assertEquals(result, ImmutableSet.of(new InternetService("IS_for_Jim2", URI - .create("https://services.vcloudexpress.terremark.com/api/v0.8/InternetServices/524"), new PublicIpAddress( - "10.1.22.159", URI.create("https://services.vcloudexpress.terremark.com/api/v0.8/PublicIps/4208")), 45, - Protocol.HTTP, false, 1, "Some test service"))); + .create("https://services.vcloudexpress.terremark.com/api/v0.8/InternetServices/524"), + new PublicIpAddress("10.1.22.159", URI + .create("https://services.vcloudexpress.terremark.com/api/v0.8/PublicIps/4208")), 45, + Protocol.HTTP, false, 1, "Some test service"))); + } + + public void test2() throws UnknownHostException { + InputStream is = getClass().getResourceAsStream("/terremark/InternetServices-2.xml"); + + Set result = factory.create(injector.getInstance(InternetServicesHandler.class)).parse(is); + assertEquals(result.size(), 6); } } diff --git a/common/trmk/src/test/resources/terremark/InternetServices-2.xml b/common/trmk/src/test/resources/terremark/InternetServices-2.xml new file mode 100644 index 0000000000..a35468c961 --- /dev/null +++ b/common/trmk/src/test/resources/terremark/InternetServices-2.xml @@ -0,0 +1,155 @@ + + + 18792 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/internetService/18792 + cl960b-62752757-443 + + 29232 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/publicIp/29232 + 209.251.180.145 + + 443 + TCP + true + 2 + + + + false + + + SourceIP + + + + 19264 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/internetService/19264 + OpenVPN + + 36648 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/publicIp/36648 + 209.251.180.245 + + 1194 + UDP + true + 2 + + + + false + + + SourceIP + + + + 20870 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/internetService/20870 + cid6b2-64d1f1e8-443 + + 40097 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/publicIp/40097 + 209.251.181.14 + + 443 + TCP + true + 2 + + + + false + + + SourceIP + + + + 21170 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/internetService/21170 + cic908-6b6a0ac2-443 + + 40162 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/publicIp/40162 + 209.251.181.16 + + 443 + TCP + true + + + + + Disabled + + + + 0 + 0 + 0 + 0 + true + + false + + + None + + + + 21319 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/internetService/21319 + ci7eeb-7a6baa70-443 + + 40203 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/publicIp/40203 + 209.251.181.17 + + 443 + TCP + true + 2 + + + + Disabled + + + + 0 + 0 + 0 + 0 + true + + false + + + SourceIP + + + + 13798 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/internetService/13798 + cl8116-4df02afd-443 + + 48625 + https://services.enterprisecloud.terremark.com/api/v0.8b-ext2.6/extensions/publicIp/48625 + 209.251.181.60 + + 443 + TCP + true + 2 + + + + false + + + SourceIP + + + \ No newline at end of file diff --git a/common/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCloneVAppParamsToXmlPayload.java b/common/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCloneVAppParamsToXmlPayload.java index fa460fd7e3..2ce7e8b5ab 100644 --- a/common/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCloneVAppParamsToXmlPayload.java +++ b/common/vcloud/src/main/java/org/jclouds/vcloud/binders/BindCloneVAppParamsToXmlPayload.java @@ -66,7 +66,7 @@ public class BindCloneVAppParamsToXmlPayload implements MapBinder { @Override public R bindToRequest(R request, Map postParams) { - checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, "this binder is only valid for GeneratedHttpRequests!"); GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; checkState(gRequest.getArgs() != null, "args should be initialized at this point"); diff --git a/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudBindComputeStrategiesByClass.java b/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudBindComputeStrategiesByClass.java index 07df6bccc1..8541eaf173 100644 --- a/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudBindComputeStrategiesByClass.java +++ b/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudBindComputeStrategiesByClass.java @@ -20,8 +20,8 @@ package org.jclouds.vcloud.compute.config; import org.jclouds.compute.config.BindComputeStrategiesByClass; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; -import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; +import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; /** * @author Adrian Cole @@ -29,8 +29,8 @@ import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStr public abstract class CommonVCloudBindComputeStrategiesByClass extends BindComputeStrategiesByClass { @Override - protected Class defineRunNodesAndAddToSetStrategy() { - return EncodeTagIntoNameRunNodesAndAddToSetStrategy.class; + protected Class defineRunNodesAndAddToSetStrategy() { + return CreateNodesWithGroupEncodedIntoNameThenAddToSet.class; } } \ No newline at end of file diff --git a/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java b/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java index c4936facfe..3a14171817 100644 --- a/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java +++ b/common/vcloud/src/main/java/org/jclouds/vcloud/compute/config/CommonVCloudComputeServiceContextModule.java @@ -42,13 +42,13 @@ import com.google.inject.Provides; public abstract class CommonVCloudComputeServiceContextModule extends BaseComputeServiceContextModule { @VisibleForTesting - static final Map vAppStatusToNodeState = ImmutableMap. builder() - .put(Status.OFF, NodeState.SUSPENDED).put(Status.ON, NodeState.RUNNING) - .put(Status.RESOLVED, NodeState.PENDING).put(Status.ERROR, NodeState.ERROR) - .put(Status.UNRECOGNIZED, NodeState.UNRECOGNIZED).put(Status.DEPLOYED, NodeState.PENDING) - .put(Status.INCONSISTENT, NodeState.PENDING).put(Status.UNKNOWN, NodeState.UNRECOGNIZED) - .put(Status.MIXED, NodeState.PENDING).put(Status.WAITING_FOR_INPUT, NodeState.PENDING) - .put(Status.SUSPENDED, NodeState.SUSPENDED).put(Status.UNRESOLVED, NodeState.PENDING).build(); + static final Map vAppStatusToNodeState = ImmutableMap. builder().put( + Status.OFF, NodeState.SUSPENDED).put(Status.ON, NodeState.RUNNING).put(Status.RESOLVED, NodeState.PENDING) + .put(Status.ERROR, NodeState.ERROR).put(Status.UNRECOGNIZED, NodeState.UNRECOGNIZED).put(Status.DEPLOYED, + NodeState.PENDING).put(Status.INCONSISTENT, NodeState.PENDING).put(Status.UNKNOWN, + NodeState.UNRECOGNIZED).put(Status.MIXED, NodeState.PENDING).put(Status.WAITING_FOR_INPUT, + NodeState.PENDING).put(Status.SUSPENDED, NodeState.SUSPENDED).put(Status.UNRESOLVED, + NodeState.PENDING).build(); @Singleton @Provides diff --git a/common/vcloud/src/main/java/org/jclouds/vcloud/compute/suppliers/OrgAndVDCToLocationSupplier.java b/common/vcloud/src/main/java/org/jclouds/vcloud/compute/suppliers/OrgAndVDCToLocationSupplier.java index f6d44f295b..2c94ab32d2 100644 --- a/common/vcloud/src/main/java/org/jclouds/vcloud/compute/suppliers/OrgAndVDCToLocationSupplier.java +++ b/common/vcloud/src/main/java/org/jclouds/vcloud/compute/suppliers/OrgAndVDCToLocationSupplier.java @@ -19,6 +19,9 @@ package org.jclouds.vcloud.compute.suppliers; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; import java.util.Map; import java.util.Set; @@ -26,43 +29,65 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; +import org.jclouds.location.Iso3166; +import org.jclouds.location.Provider; +import org.jclouds.location.suppliers.JustProvider; import org.jclouds.vcloud.domain.Org; import org.jclouds.vcloud.domain.ReferenceType; import com.google.common.base.Supplier; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableSet.Builder; /** * @author Adrian Cole */ @Singleton -public class OrgAndVDCToLocationSupplier implements Supplier> { - private final String providerName; +public class OrgAndVDCToLocationSupplier extends JustProvider { + private final Supplier> orgNameToResource; private final Supplier> orgNameToVDCResource; + private final Map> isoCodesById; @Inject - OrgAndVDCToLocationSupplier(@org.jclouds.location.Provider String providerName, + OrgAndVDCToLocationSupplier(@Iso3166 Set isoCodes, @Provider String providerName, @Provider URI endpoint, @org.jclouds.vcloud.endpoints.Org Supplier> orgNameToResource, - Supplier> orgNameToVDCResource) { - this.providerName = providerName; - this.orgNameToResource = orgNameToResource; - this.orgNameToVDCResource = orgNameToVDCResource; + Supplier> orgNameToVDCResource, @Iso3166 Map> isoCodesById) { + super(isoCodes, providerName, endpoint); + this.orgNameToResource = checkNotNull(orgNameToResource, "orgNameToResource"); + this.orgNameToVDCResource = checkNotNull(orgNameToVDCResource, "orgNameToVDCResource"); + this.isoCodesById = checkNotNull(isoCodesById, "isoCodesById"); } @Override public Set get() { - Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); - Set locations = Sets.newLinkedHashSet(); + return buildJustProviderOrVDCs().build(); + } - for (ReferenceType org : orgNameToResource.get().values()) { - Location orgL = new LocationImpl(LocationScope.REGION, org.getHref().toASCIIString(), org.getName(), provider); - for (ReferenceType vdc : orgNameToVDCResource.get().get(org.getName()).getVDCs().values()) { - locations.add(new LocationImpl(LocationScope.ZONE, vdc.getHref().toASCIIString(), vdc.getName(), orgL)); + protected Builder buildJustProviderOrVDCs() { + Builder locations = ImmutableSet.builder(); + Location provider = Iterables.getOnlyElement(super.get()); + if (orgNameToResource.get().size() == 0) + return locations.add(provider); + else + for (ReferenceType org : orgNameToResource.get().values()) { + LocationBuilder builder = new LocationBuilder().scope(LocationScope.REGION).id( + org.getHref().toASCIIString()).description((org.getName())).parent(provider); + if (isoCodesById.containsKey(org.getHref().toASCIIString())) + builder.iso3166Codes(isoCodesById.get(org.getHref().toASCIIString())); + Location orgL = builder.build(); + for (ReferenceType vdc : orgNameToVDCResource.get().get(org.getName()).getVDCs().values()) { + builder = new LocationBuilder().scope(LocationScope.ZONE).id(vdc.getHref().toASCIIString()).description( + (vdc.getName())).parent(orgL); + if (isoCodesById.containsKey(vdc.getHref().toASCIIString())) + builder.iso3166Codes(isoCodesById.get(vdc.getHref().toASCIIString())); + locations.add(builder.build()); + } } - } return locations; } + } \ No newline at end of file diff --git a/common/vcloud/src/main/java/org/jclouds/vcloud/xml/CatalogHandler.java b/common/vcloud/src/main/java/org/jclouds/vcloud/xml/CatalogHandler.java index aa478c5b73..74541aeb9d 100644 --- a/common/vcloud/src/main/java/org/jclouds/vcloud/xml/CatalogHandler.java +++ b/common/vcloud/src/main/java/org/jclouds/vcloud/xml/CatalogHandler.java @@ -25,7 +25,6 @@ import static org.jclouds.vcloud.util.Utils.putReferenceType; import java.util.List; import java.util.Map; -import java.util.SortedMap; import javax.inject.Inject; @@ -56,7 +55,7 @@ public class CatalogHandler extends ParseSax.HandlerWithResult { private StringBuilder currentText = new StringBuilder(); private ReferenceType catalog; - private SortedMap contents = Maps.newTreeMap(); + private Map contents = Maps.newLinkedHashMap(); protected List tasks = Lists.newArrayList(); private String description; private ReferenceType org; diff --git a/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudLoginAsyncClientTest.java b/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudLoginAsyncClientTest.java index 74dc73a6da..f98431d275 100755 --- a/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudLoginAsyncClientTest.java +++ b/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudLoginAsyncClientTest.java @@ -60,8 +60,7 @@ public class VCloudLoginAsyncClientTest extends RestClientTest createContextSpec() { - return contextSpec("test", "http://localhost:8080/login", "1", "identity", "credential", VCloudLoginClient.class, - VCloudLoginAsyncClient.class); + return contextSpec("test", "http://localhost:8080/login", "1", "", "identity", "credential", + VCloudLoginClient.class, VCloudLoginAsyncClient.class); } } diff --git a/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java b/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java index d7a3e70971..f88ed7cb2c 100644 --- a/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java +++ b/common/vcloud/src/test/java/org/jclouds/vcloud/VCloudVersionsAsyncClientTest.java @@ -39,7 +39,6 @@ import org.testng.annotations.Test; import com.google.inject.TypeLiteral; - /** * Tests behavior of {@code VCloudVersionsAsyncClient} * @@ -83,8 +82,8 @@ public class VCloudVersionsAsyncClientTest extends RestClientTest createContextSpec() { - return contextSpec("test", "http://localhost:8080", "1", "identity", "credential", VCloudVersionsClient.class, - VCloudVersionsAsyncClient.class); + return contextSpec("test", "http://localhost:8080", "1", "", "identity", "credential", + VCloudVersionsClient.class, VCloudVersionsAsyncClient.class); } } diff --git a/compute/pom.xml b/compute/pom.xml index bc5f3e8571..9891b5ac2d 100644 --- a/compute/pom.xml +++ b/compute/pom.xml @@ -66,7 +66,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/compute/src/main/clojure/org/jclouds/compute.clj b/compute/src/main/clojure/org/jclouds/compute.clj index 4ab29ef6ee..691baed096 100644 --- a/compute/src/main/clojure/org/jclouds/compute.clj +++ b/compute/src/main/clojure/org/jclouds/compute.clj @@ -21,12 +21,11 @@ "A clojure binding to the jclouds ComputeService. Current supported providers are: - [ec2, aws-ec2, eucualyptus-partnercloud-ec2, cloudservers, - cloudservers-uk, cloudservers-us, + [aws-ec2, eucualyptus-partnercloud-ec2, elastichosts-lon-b, + cloudservers-uk, cloudservers-us, byon, cloudsigma-zrh, stub, trmk-ecloud, trmk-vcloudexpress, vcloud, bluelock, eucalyptus, slicehost, elastichosts-lon-p, elastichosts-sat-p, elastichosts, - openhosting-east1, serverlove-z1-man, skalicloud-sdg-my, - elastichosts-lon-b, cloudsigma-zrh, vcloudexpress, stub] + openhosting-east1, serverlove-z1-man, skalicloud-sdg-my] Here's an example of getting some compute configuration from rackspace: @@ -47,7 +46,7 @@ Here's an example of getting some compute configuration from rackspace: (pprint (nodes)) (pprint (hardware-profiles))) -Here's an example of creating and running a small linux node with the tag +Here's an example of creating and running a small linux node in the group webserver: ;; create a compute service using ssh and log4j extensions @@ -55,7 +54,7 @@ webserver: (compute-service provider provider-identity provider-credential :ssh :log4j)) - (run-node \"webserver\" compute) + (create-node \"webserver\" compute) See http://code.google.com/p/jclouds for details." (:use org.jclouds.core @@ -82,6 +81,8 @@ See http://code.google.com/p/jclouds for details." :only [wall-hack-field] :rename {wall-hack-field get-field}]))) +(defmacro deprecate-fwd [old-name new-name] `(defn ~old-name {:deprecated "beta-9"} [& args#] (apply ~new-name args#))) + (defn compute-service "Create a logged in context." ([#^String provider #^String provider-identity #^String provider-credential @@ -144,11 +145,13 @@ See http://code.google.com/p/jclouds for details." ([#^ComputeService compute] (seq (.listNodesDetailsMatching compute (NodePredicates/all))))) -(defn nodes-with-tag - "list details of all the nodes with the given tag." - ([tag] (nodes-with-tag tag *compute*)) - ([#^String tag #^ComputeService compute] - (filter #(= (.getTag %) tag) (nodes-with-details compute)))) +(defn nodes-in-group + "list details of all the nodes in the given group." + ([group] (nodes-in-group group *compute*)) + ([#^String group #^ComputeService compute] + (filter #(= (.getTag %) group) (nodes-with-details compute)))) + +(deprecate-fwd nodes-with-tag nodes-in-group) (defn images "Retrieve the available images for the compute context." @@ -171,66 +174,70 @@ See http://code.google.com/p/jclouds for details." (slurp (str (. System getProperty "user.home") "/.ssh/id_rsa.pub")))) build))) -(defn run-nodes +(defn create-nodes "Create the specified number of nodes using the default or specified template. ;; Simplest way to add 2 small linux nodes to the group webserver is to run - (run-nodes \"webserver\" 2 compute) + (create-nodes \"webserver\" 2 compute) - ;; which is the same as wrapping the run-nodes command with an implicit + ;; which is the same as wrapping the create-nodes command with an implicit ;; compute service. ;; Note that this will actually add another 2 nodes to the set called ;; \"webserver\" (with-compute-service [compute] - (run-nodes \"webserver\" 2 )) + (create-nodes \"webserver\" 2 )) ;; which is the same as specifying the default template (with-compute-service [compute] - (run-nodes \"webserver\" 2 (default-template))) + (create-nodes \"webserver\" 2 (default-template))) ;; which, on gogrid, is the same as constructing the smallest centos template ;; that has no layered software (with-compute-service [compute] - (run-nodes \"webserver\" 2 + (create-nodes \"webserver\" 2 (build-template service {:os-family :centos :smallest true :image-name-matches \".*w/ None.*\"})))" - ([tag count] - (run-nodes tag count (default-template *compute*) *compute*)) - ([tag count compute-or-template] + ([group count] + (create-nodes group count (default-template *compute*) *compute*)) + ([group count compute-or-template] (if (compute-service? compute-or-template) - (run-nodes - tag count (default-template compute-or-template) compute-or-template) - (run-nodes tag count compute-or-template *compute*))) - ([tag count template #^ComputeService compute] + (create-nodes + group count (default-template compute-or-template) compute-or-template) + (create-nodes group count compute-or-template *compute*))) + ([group count template #^ComputeService compute] (seq - (.runNodesWithTag compute tag count template)))) + (.createNodesInGroup compute group count template)))) -(defn run-node +(deprecate-fwd run-nodes create-nodes) + +(defn create-node "Create a node using the default or specified template. ;; simplest way to add a small linux node to the group webserver is to run - (run-node \"webserver\" compute) + (create-node \"webserver\" compute) - ;; which is the same as wrapping the run-node command with an implicit compute + ;; which is the same as wrapping the create-node command with an implicit compute ;; service. ;; Note that this will actually add another node to the set called ;; \"webserver\" (with-compute-service [compute] - (run-node \"webserver\" ))" - ([tag] - (first (run-nodes tag 1 (default-template *compute*) *compute*))) - ([tag compute-or-template] + (create-node \"webserver\" ))" + ([group] + (first (create-nodes group 1 (default-template *compute*) *compute*))) + ([group compute-or-template] (if (compute-service? compute-or-template) (first - (run-nodes - tag 1 (default-template compute-or-template) compute-or-template)) - (first (run-nodes tag 1 compute-or-template *compute*)))) - ([tag template compute] - (first (run-nodes tag 1 template compute)))) + (create-nodes + group 1 (default-template compute-or-template) compute-or-template)) + (first (create-nodes group 1 compute-or-template *compute*)))) + ([group template compute] + (first (create-nodes group 1 template compute)))) + +(deprecate-fwd run-node create-node) (defn #^NodeMetadata node-details "Retrieve the node metadata, given its id." @@ -238,11 +245,13 @@ See http://code.google.com/p/jclouds for details." ([id #^ComputeService compute] (.getNodeMetadata compute id))) -(defn suspend-nodes-with-tag - "Reboot all the nodes with the given tag." - ([tag] (suspend-nodes-with-tag tag *compute*)) - ([#^String tag #^ComputeService compute] - (.suspendNodesMatching compute (NodePredicates/withTag tag)))) +(defn suspend-nodes-in-group + "Reboot all the nodes in the given group." + ([group] (suspend-nodes-in-group group *compute*)) + ([#^String group #^ComputeService compute] + (.suspendNodesMatching compute (NodePredicates/inGroup group)))) + +(deprecate-fwd suspend-nodes-with-tag suspend-nodes-in-group) (defn suspend-node "Suspend a node, given its id." @@ -250,11 +259,13 @@ See http://code.google.com/p/jclouds for details." ([id #^ComputeService compute] (.suspendNode compute id))) -(defn resume-nodes-with-tag - "Suspend all the nodes with the given tag." - ([tag] (resume-nodes-with-tag tag *compute*)) - ([#^String tag #^ComputeService compute] - (.resumeNodesMatching compute (NodePredicates/withTag tag)))) +(defn resume-nodes-in-group + "Suspend all the nodes in the given group." + ([group] (resume-nodes-in-group group *compute*)) + ([#^String group #^ComputeService compute] + (.resumeNodesMatching compute (NodePredicates/inGroup group)))) + +(deprecate-fwd resume-nodes-with-tag resume-nodes-in-group) (defn resume-node "Resume a node, given its id." @@ -262,11 +273,13 @@ See http://code.google.com/p/jclouds for details." ([id #^ComputeService compute] (.resumeNode compute id))) -(defn reboot-nodes-with-tag - "Reboot all the nodes with the given tag." - ([tag] (reboot-nodes-with-tag tag *compute*)) - ([#^String tag #^ComputeService compute] - (.rebootNodesMatching compute (NodePredicates/withTag tag)))) +(defn reboot-nodes-in-group + "Reboot all the nodes in the given group." + ([group] (reboot-nodes-in-group group *compute*)) + ([#^String group #^ComputeService compute] + (.rebootNodesMatching compute (NodePredicates/inGroup group)))) + +(deprecate-fwd reboot-nodes-with-tag reboot-nodes-in-group) (defn reboot-node "Reboot a node, given its id." @@ -274,11 +287,13 @@ See http://code.google.com/p/jclouds for details." ([id #^ComputeService compute] (.rebootNode compute id))) -(defn destroy-nodes-with-tag - "Destroy all the nodes with the given tag." - ([tag] (destroy-nodes-with-tag tag *compute*)) - ([#^String tag #^ComputeService compute] - (.destroyNodesMatching compute (NodePredicates/withTag tag)))) +(defn destroy-nodes-in-group + "Destroy all the nodes in the given group." + ([group] (destroy-nodes-in-group group *compute*)) + ([#^String group #^ComputeService compute] + (.destroyNodesMatching compute (NodePredicates/inGroup group)))) + +(deprecate-fwd destroy-nodes-with-tag destroy-nodes-in-group) (defn destroy-node "Destroy a node, given its id." @@ -330,10 +345,12 @@ See http://code.google.com/p/jclouds for details." [#^NodeMetadata node] (.getPrivateAddresses node)) -(defn tag - "Returns a the node's tag" +(defn group + "Returns a the node's group" [#^NodeMetadata node] - (.getTag node)) + (.getGroup node)) + +(deprecate-fwd tag group) (defn hostname "Returns the compute node's name" @@ -353,7 +370,7 @@ See http://code.google.com/p/jclouds for details." (define-accessors Template image hardware location options) (define-accessors Image version os-family os-description architecture) (define-accessors Hardware processors ram volumes) -(define-accessors NodeMetadata "node" credentials hardware state tag) +(define-accessors NodeMetadata "node" credentials hardware state group) (defn builder-options [builder] (or diff --git a/compute/src/main/clojure/org/jclouds/modules.clj b/compute/src/main/clojure/org/jclouds/modules.clj index 53982b606c..2e89d93043 100644 --- a/compute/src/main/clojure/org/jclouds/modules.clj +++ b/compute/src/main/clojure/org/jclouds/modules.clj @@ -40,7 +40,7 @@ (class ComputeService) (defrecord ClojureComputeServiceAdapter [] org.jclouds.compute.JCloudsNativeComputeServiceAdapter - (^NodeMetadata runNodeWithTagAndNameAndStoreCredentials [this ^String tag ^String name ^Template template ^Map credentialStore] + (^NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials [this ^String group ^String name ^Template template ^Map credentialStore] ()) (^Iterable listNodes [this ] ()) @@ -65,7 +65,7 @@ (.createContext (ComputeServiceContextFactory.) spec)) (^RestContextSpec defn context-spec [^StandaloneComputeServiceContextModule module] - (StandaloneComputeServiceContextSpec. "servermanager", "http://host", "1", "identity", "credential", module, (ImmutableSet/of))) + (StandaloneComputeServiceContextSpec. "servermanager", "http://host", "1", "", "identity", "credential", module, (ImmutableSet/of))) (defrecord NodeListComputeService [node-list] diff --git a/compute/src/main/java/org/jclouds/compute/ComputeService.java b/compute/src/main/java/org/jclouds/compute/ComputeService.java index fc6a92b615..12c0ac4b44 100755 --- a/compute/src/main/java/org/jclouds/compute/ComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeService.java @@ -20,6 +20,7 @@ package org.jclouds.compute; import java.util.Map; +import java.util.NoSuchElementException; import java.util.Set; import org.jclouds.compute.domain.ComputeMetadata; @@ -98,8 +99,8 @@ public interface ComputeService { /** * - * The compute api treats nodes as a group based on a tag you specify. Using this tag, you can - * choose to operate one or many nodes as a logical unit without regard to the implementation + * The compute api treats nodes as a group based on the name you specify. Using this group, you + * can choose to operate one or many nodes as a logical unit without regard to the implementation * details of the cloud. *

* @@ -119,7 +120,7 @@ public interface ComputeService { * If resources such as security groups are needed, they will be reused or created for you. * Inbound port 22 will always be opened up. * - * @param tag + * @param group * - common identifier to group nodes by, cannot contain hyphens * @param count * - how many to fire up. @@ -131,19 +132,38 @@ public interface ComputeService { * when there's a problem applying options to nodes. Note that successful and failed * nodes are a part of this exception, so be sure to inspect this carefully. */ + Set createNodesInGroup(String group, int count, Template template) throws RunNodesException; + + /** + * Like {@link ComputeService#createNodesInGroup(String,int,Template)}, except that the template + * is default, equivalent to {@code templateBuilder().any().options(templateOptions)}. + */ + Set createNodesInGroup(String group, int count, TemplateOptions templateOptions) + throws RunNodesException; + + /** + * Like {@link ComputeService#createNodesInGroup(String,int,TemplateOptions)}, except that the + * options are default, as specified in {@link ComputeService#templateOptions}. + */ + Set createNodesInGroup(String group, int count) throws RunNodesException; + + /** + * @see #createNodesInGroup(String , int , Template ) + */ + @Deprecated Set runNodesWithTag(String tag, int count, Template template) throws RunNodesException; /** - * Like {@link ComputeService#runNodesWithTag(String,int,Template)}, except that the template is - * default, equivalent to {@code templateBuilder().any().options(templateOptions)}. + * @see #createNodesInGroup(String , int , TemplateOptions ) */ + @Deprecated Set runNodesWithTag(String tag, int count, TemplateOptions templateOptions) throws RunNodesException; /** - * Like {@link ComputeService#runNodesWithTag(String,int,TemplateOptions)}, except that the - * options are default, as specified in {@link ComputeService#templateOptions}. + * @see #createNodesInGroup(String , int ) */ + @Deprecated Set runNodesWithTag(String tag, int count) throws RunNodesException; /** @@ -272,6 +292,13 @@ public interface ComputeService { Map runScriptOnNodesMatching(Predicate filter, Statement runScript) throws RunScriptOnNodesException; + /** + * + * @see ComputeService#runScriptOnNodesMatching(Predicate, Statement, RunScriptOptions) + */ + Map runScriptOnNodesMatching(Predicate filter, String runScript, + RunScriptOptions options) throws RunScriptOnNodesException; + /** * Run the script on all nodes with the specific predicate. * diff --git a/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java index 55ec6ad6b1..06f086b1dc 100644 --- a/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java @@ -60,7 +60,7 @@ public interface ComputeServiceAdapter { * @see ComputeService#runNodesWithTag(String, int, Template) * @see ComputeServiceContext#getCredentialStore */ - N runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, + N createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, Map credentialStore); /** diff --git a/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java index dfa70466ab..b39b19b5e8 100644 --- a/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/JCloudsNativeComputeServiceAdapter.java @@ -40,7 +40,7 @@ public interface JCloudsNativeComputeServiceAdapter extends * {@inheritDoc} */ @Override - NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, + NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, Map credentialStore); /** diff --git a/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java b/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java index 9d0ab8c5f4..7af4076318 100644 --- a/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java +++ b/compute/src/main/java/org/jclouds/compute/StandaloneComputeServiceContextSpec.java @@ -29,25 +29,26 @@ import com.google.inject.Module; * @author Adrian Cole */ public class StandaloneComputeServiceContextSpec extends RestContextSpec { - public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String identity, - String credential, Class driverClass, - Class> contextBuilderClass) { - this(provider, endpoint, apiVersion, identity, credential, driverClass, contextBuilderClass, ImmutableSet - . of()); + public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes, + String identity, String credential, Class driverClass, + Class> contextBuilderClass) { + this(provider, endpoint, apiVersion, iso3166Codes, identity, credential, driverClass, contextBuilderClass, + ImmutableSet. of()); } - public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String identity, - String credential, Class driverClass, - Class> contextBuilderClass, Iterable modules) { - this(provider, endpoint, apiVersion, identity, credential, driverClass, PropertiesBuilder.class, - contextBuilderClass, modules); + public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes, + String identity, String credential, Class driverClass, + Class> contextBuilderClass, Iterable modules) { + this(provider, endpoint, apiVersion, iso3166Codes, identity, credential, driverClass, PropertiesBuilder.class, + contextBuilderClass, modules); } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String identity, - String credential, Class driverClass, Class propertiesBuilderClass, - Class> contextBuilderClass, Iterable modules) { - super(provider, endpoint, apiVersion, identity, credential, driverClass, driverClass, - (Class) propertiesBuilderClass, (Class) contextBuilderClass, modules); + @SuppressWarnings( { "unchecked", "rawtypes" }) + public StandaloneComputeServiceContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes, + String identity, String credential, Class driverClass, + Class propertiesBuilderClass, + Class> contextBuilderClass, Iterable modules) { + super(provider, endpoint, apiVersion, iso3166Codes, identity, credential, driverClass, driverClass, + (Class) propertiesBuilderClass, (Class) contextBuilderClass, modules); } } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java index 3d2c4f0033..078766af95 100644 --- a/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/BaseComputeServiceContextModule.java @@ -49,8 +49,8 @@ import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; -import org.jclouds.domain.Location; import org.jclouds.json.Json; +import org.jclouds.location.config.LocationModule; import org.jclouds.rest.AuthorizationException; import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier; import org.jclouds.scriptbuilder.domain.Statement; @@ -76,6 +76,7 @@ import com.google.inject.name.Names; public abstract class BaseComputeServiceContextModule extends AbstractModule { @Override protected void configure() { + install(new LocationModule(authException)); install(new ComputeServiceTimeoutsModule()); bind(new TypeLiteral>() { }).to(CreateSshClientOncePortIsListeningOnNode.class); @@ -127,9 +128,9 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { checkNotNull(node, "node"); checkNotNull(runScript, "runScript"); checkNotNull(options, "options"); - return !options.shouldWrapInInitScript() ? factory.exec(node, runScript, options) - : (options.shouldBlockOnComplete() ? factory.backgroundAndBlockOnComplete(node, runScript, options) - : factory.background(node, runScript, options)); + return !options.shouldWrapInInitScript() ? factory.exec(node, runScript, options) : (options + .shouldBlockOnComplete() ? factory.backgroundAndBlockOnComplete(node, runScript, options) : factory + .background(node, runScript, options)); } @Override @@ -206,41 +207,6 @@ public abstract class BaseComputeServiceContextModule extends AbstractModule { }); } - @Provides - @Singleton - protected Supplier> provideLocationMap( - @Memoized Supplier> locations) { - return Suppliers.compose(new Function, Map>() { - - @Override - public Map apply(Set from) { - return Maps.uniqueIndex(from, new Function() { - - @Override - public String apply(Location from) { - return from.getId(); - } - - }); - } - - }, locations); - } - - @Provides - @Singleton - @Memoized - protected Supplier> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, - final Supplier> locationSupplier) { - return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, seconds, - new Supplier>() { - @Override - public Set get() { - return locationSupplier.get(); - } - }); - } - @Provides @Singleton protected Supplier> provideSizeMap(@Memoized Supplier> sizes) { diff --git a/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java b/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java index 0e3264fa39..647d47273f 100644 --- a/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java +++ b/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java @@ -19,15 +19,15 @@ package org.jclouds.compute.config; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; import com.google.inject.AbstractModule; import com.google.inject.Scopes; @@ -49,15 +49,15 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule { bindDestroyNodeStrategy(defineDestroyNodeStrategy()); } - protected void bindRunNodesAndAddToSetStrategy(Class clazz) { - bind(RunNodesAndAddToSetStrategy.class).to(clazz).in(Scopes.SINGLETON); + protected void bindRunNodesAndAddToSetStrategy(Class clazz) { + bind(CreateNodesInGroupThenAddToSet.class).to(clazz).in(Scopes.SINGLETON); } /** - * needed, if {@link RunNodesAndAddToSetStrategy} requires it + * needed, if {@link CreateNodesInGroupThenAddToSet} requires it */ - protected void bindAddNodeWithTagStrategy(Class clazz) { - bind(AddNodeWithTagStrategy.class).to(clazz).in(Scopes.SINGLETON); + protected void bindAddNodeWithTagStrategy(Class clazz) { + bind(CreateNodeWithGroupEncodedIntoName.class).to(clazz).in(Scopes.SINGLETON); } protected void bindDestroyNodeStrategy(Class clazz) { @@ -84,14 +84,14 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule { bind(ListNodesStrategy.class).to(clazz).in(Scopes.SINGLETON); } - protected Class defineRunNodesAndAddToSetStrategy() { - return EncodeTagIntoNameRunNodesAndAddToSetStrategy.class; + protected Class defineRunNodesAndAddToSetStrategy() { + return CreateNodesWithGroupEncodedIntoNameThenAddToSet.class; } /** - * needed, if {@link RunNodesAndAddToSetStrategy} requires it + * needed, if {@link CreateNodesInGroupThenAddToSet} requires it */ - protected abstract Class defineAddNodeWithTagStrategy(); + protected abstract Class defineAddNodeWithTagStrategy(); protected abstract Class defineDestroyNodeStrategy(); diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java index 5b203278a4..9d568e2efa 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java @@ -19,20 +19,17 @@ package org.jclouds.compute.config; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.collect.Iterables.transform; -import static com.google.common.collect.Sets.newHashSet; - import java.util.Set; import javax.inject.Singleton; +import org.jclouds.collect.TransformingSetSupplier; import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.internal.ComputeServiceContextImpl; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; @@ -41,7 +38,6 @@ import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.compute.strategy.impl.AdaptingComputeServiceStrategies; import org.jclouds.domain.Location; -import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; import com.google.common.base.Function; import com.google.common.base.Supplier; @@ -64,36 +60,34 @@ public class ComputeServiceAdapterContextModule extends BaseCo this.asyncClientType = asyncClientType; } - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked", "rawtypes" }) @Override protected void configure() { super.configure(); - bindDefaultLocation(); bind(new TypeLiteral() { - }).to((TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class, syncClientType, - asyncClientType))).in(Scopes.SINGLETON); + }).to( + (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(ComputeServiceContextImpl.class, + syncClientType, asyncClientType))).in(Scopes.SINGLETON); } - public class TransformingSetSupplier implements Supplier> { - private final Supplier> backingSupplier; - private final Function converter; + @Provides + @Singleton + protected Supplier> provideLocations(final ComputeServiceAdapter adapter, + Function transformer) { + return new TransformingSetSupplier(new Supplier>() { - public TransformingSetSupplier(Supplier> backingSupplier, Function converter) { - this.backingSupplier = checkNotNull(backingSupplier, "backingSupplier"); - this.converter = checkNotNull(converter, "converter"); - } - - @Override - public Set get() { - return newHashSet(transform(backingSupplier.get(), converter)); - } + @Override + public Iterable get() { + return adapter.listLocations(); + } + }, transformer); } @Provides @Singleton protected Supplier> provideHardware(final ComputeServiceAdapter adapter, - Function transformer) { + Function transformer) { return new TransformingSetSupplier(new Supplier>() { @Override @@ -107,7 +101,7 @@ public class ComputeServiceAdapterContextModule extends BaseCo @Provides @Singleton protected Supplier> provideImages(final ComputeServiceAdapter adapter, - Function transformer) { + Function transformer) { return new TransformingSetSupplier(new Supplier>() { @Override @@ -118,28 +112,9 @@ public class ComputeServiceAdapterContextModule extends BaseCo }, transformer); } - protected void bindDefaultLocation() { - bind(new TypeLiteral>() { - }).to(OnlyLocationOrFirstZone.class); - } - @Provides @Singleton - protected Supplier> provideLocations(final ComputeServiceAdapter adapter, - Function transformer) { - return new TransformingSetSupplier(new Supplier>() { - - @Override - public Iterable get() { - return adapter.listLocations(); - } - - }, transformer); - } - - @Provides - @Singleton - protected AddNodeWithTagStrategy defineAddNodeWithTagStrategy(AdaptingComputeServiceStrategies in) { + protected CreateNodeWithGroupEncodedIntoName defineAddNodeWithTagStrategy(AdaptingComputeServiceStrategies in) { return in; } diff --git a/compute/src/main/java/org/jclouds/compute/domain/NodeMetadata.java b/compute/src/main/java/org/jclouds/compute/domain/NodeMetadata.java index 7607904935..1ff3894820 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/NodeMetadata.java +++ b/compute/src/main/java/org/jclouds/compute/domain/NodeMetadata.java @@ -37,11 +37,17 @@ public interface NodeMetadata extends ComputeMetadata { /** * Tag used for all resources that belong to the same logical group. run, destroy commands are - * scoped to tag. + * scoped to group. * - * @return tag for this node, or null, if not a part of a group + * @return group for this node, or null, if not a part of a group * */ + String getGroup(); + + /** + * @see #getGroup + */ + @Deprecated String getTag(); /** diff --git a/compute/src/main/java/org/jclouds/compute/domain/NodeMetadataBuilder.java b/compute/src/main/java/org/jclouds/compute/domain/NodeMetadataBuilder.java index 0cb46e7d6a..a3a5efff55 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/NodeMetadataBuilder.java +++ b/compute/src/main/java/org/jclouds/compute/domain/NodeMetadataBuilder.java @@ -46,7 +46,7 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder { @Nullable private Credentials credentials; @Nullable - private String tag; + private String group; private int loginPort = 22; @Nullable private String imageId; @@ -89,8 +89,8 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder { return this; } - public NodeMetadataBuilder tag(@Nullable String tag) { - this.tag = tag; + public NodeMetadataBuilder group(@Nullable String group) { + this.group = group; return this; } @@ -146,13 +146,13 @@ public class NodeMetadataBuilder extends ComputeMetadataBuilder { @Override public NodeMetadata build() { - return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, tag, hardware, imageId, os, state, + return new NodeMetadataImpl(providerId, name, id, location, uri, userMetadata, group, hardware, imageId, os, state, loginPort, publicAddresses, privateAddresses, adminPassword, credentials); } public static NodeMetadataBuilder fromNodeMetadata(NodeMetadata node) { return new NodeMetadataBuilder().providerId(node.getProviderId()).name(node.getName()).id(node.getId()).location( - node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).tag(node.getTag()).hardware( + node.getLocation()).uri(node.getUri()).userMetadata(node.getUserMetadata()).group(node.getGroup()).hardware( node.getHardware()).imageId(node.getImageId()).operatingSystem(node.getOperatingSystem()).state( node.getState()).loginPort(node.getLoginPort()).publicAddresses(node.getPublicAddresses()) .privateAddresses(node.getPrivateAddresses()).adminPassword(node.getAdminPassword()).credentials( diff --git a/compute/src/main/java/org/jclouds/compute/domain/TemplateBuilder.java b/compute/src/main/java/org/jclouds/compute/domain/TemplateBuilder.java index b8f07f9e3f..34ba375446 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/TemplateBuilder.java +++ b/compute/src/main/java/org/jclouds/compute/domain/TemplateBuilder.java @@ -155,4 +155,5 @@ public interface TemplateBuilder { * options such as inbound ports and run scripts. */ TemplateBuilder options(TemplateOptions options); + } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/NodeMetadataImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/NodeMetadataImpl.java index ad92ebda1f..e7f14b4f6b 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/NodeMetadataImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/NodeMetadataImpl.java @@ -55,7 +55,7 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat @Nullable private final Credentials credentials; @Nullable - private final String tag; + private final String group; @Nullable private final String imageId; @Nullable @@ -64,12 +64,12 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat private final OperatingSystem os; public NodeMetadataImpl(String providerId, String name, String id, Location location, URI uri, - Map userMetadata, @Nullable String tag, @Nullable Hardware hardware, + Map userMetadata, @Nullable String group, @Nullable Hardware hardware, @Nullable String imageId, @Nullable OperatingSystem os, NodeState state, int loginPort, Iterable publicAddresses, Iterable privateAddresses, @Nullable String adminPassword, @Nullable Credentials credentials) { super(ComputeType.NODE, providerId, name, id, location, uri, userMetadata); - this.tag = tag; + this.group = group; this.hardware = hardware; this.imageId = imageId; this.os = os; @@ -86,7 +86,15 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat */ @Override public String getTag() { - return tag; + return getGroup(); + } + + /** + * {@inheritDoc} + */ + @Override + public String getGroup() { + return group; } /** @@ -163,7 +171,7 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat @Override public String toString() { - return "[id=" + getId() + ", providerId=" + getProviderId() + ", tag=" + getTag() + ", name=" + getName() + return "[id=" + getId() + ", providerId=" + getProviderId() + ", group=" + getTag() + ", name=" + getName() + ", location=" + getLocation() + ", uri=" + getUri() + ", imageId=" + getImageId() + ", os=" + getOperatingSystem() + ", state=" + getState() + ", loginPort=" + getLoginPort() + ", privateAddresses=" + privateAddresses + ", publicAddresses=" + publicAddresses + ", hardware=" @@ -178,7 +186,7 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat result = prime * result + loginPort; result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode()); result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode()); - result = prime * result + ((tag == null) ? 0 : tag.hashCode()); + result = prime * result + ((group == null) ? 0 : group.hashCode()); result = prime * result + ((imageId == null) ? 0 : imageId.hashCode()); result = prime * result + ((hardware == null) ? 0 : hardware.hashCode()); result = prime * result + ((os == null) ? 0 : os.hashCode()); @@ -208,10 +216,10 @@ public class NodeMetadataImpl extends ComputeMetadataImpl implements NodeMetadat return false; } else if (!publicAddresses.equals(other.publicAddresses)) return false; - if (tag == null) { - if (other.tag != null) + if (group == null) { + if (other.group != null) return false; - } else if (!tag.equals(other.tag)) + } else if (!group.equals(other.group)) return false; if (imageId == null) { if (other.imageId != null) diff --git a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java index f51537a688..6204a3c089 100644 --- a/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java +++ b/compute/src/main/java/org/jclouds/compute/domain/internal/TemplateBuilderImpl.java @@ -140,7 +140,8 @@ public class TemplateBuilderImpl implements TemplateBuilder { boolean returnVal = true; if (location != null && input.getLocation() != null) returnVal = location.equals(input.getLocation()) || location.getParent() != null - && location.getParent().equals(input.getLocation()); + && location.getParent().equals(input.getLocation()) || location.getParent().getParent() != null + && location.getParent().getParent().equals(input.getLocation()); return returnVal; } @@ -497,19 +498,24 @@ public class TemplateBuilderImpl implements TemplateBuilder { */ @Override public TemplateBuilder locationId(final String locationId) { - this.location = Iterables.find(locations.get(), new Predicate() { + Set locations = this.locations.get(); + try { + this.location = Iterables.find(locations, new Predicate() { - @Override - public boolean apply(Location input) { - return input.getId().equals(locationId); - } + @Override + public boolean apply(Location input) { + return input.getId().equals(locationId); + } - @Override - public String toString() { - return "locationId(" + locationId + ")"; - } + @Override + public String toString() { + return "locationId(" + locationId + ")"; + } - }); + }); + } catch (NoSuchElementException e) { + throw new NoSuchElementException(String.format("location id %s not found in: %s", locationId, locations)); + } return this; } diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java index 4104e6821c..33be65a04c 100755 --- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java @@ -76,7 +76,7 @@ import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.RunScriptOnNodeAndAddToGoodMapOrPutExceptionIntoBadMap; import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.domain.Credentials; @@ -116,7 +116,7 @@ public class BaseComputeService implements ComputeService { private final Supplier> locations; private final ListNodesStrategy listNodesStrategy; private final GetNodeMetadataStrategy getNodeMetadataStrategy; - private final RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy; + private final CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy; private final RebootNodeStrategy rebootNodeStrategy; private final DestroyNodeStrategy destroyNodeStrategy; private final ResumeNodeStrategy resumeNodeStrategy; @@ -135,7 +135,7 @@ public class BaseComputeService implements ComputeService { @Memoized Supplier> images, @Memoized Supplier> hardwareProfiles, @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, RunNodesAndAddToSetStrategy runNodesAndAddToSetStrategy, + GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy, Provider templateBuilderProvider, Provider templateOptionsProvider, @@ -178,45 +178,63 @@ public class BaseComputeService implements ComputeService { * {@inheritDoc} */ @Override - public Set runNodesWithTag(String tag, int count, Template template) + public Set runNodesWithTag(String group, int count, Template template) throws RunNodesException { - checkNotNull(tag, "tag cannot be null"); + return createNodesInGroup(group, count, template); + } + + /** + * {@inheritDoc} + */ + @Override + public Set runNodesWithTag(String group, int count, TemplateOptions templateOptions) + throws RunNodesException { + return createNodesInGroup(group, count, templateBuilder().any().options(templateOptions).build()); + } + + /** + * {@inheritDoc} + */ + @Override + public Set runNodesWithTag(String group, int count) throws RunNodesException { + return createNodesInGroup(group, count, templateOptions()); + } + + @Override + public Set createNodesInGroup(String group, int count, Template template) + throws RunNodesException { + checkNotNull(group, "group cannot be null"); checkNotNull(template.getLocation(), "location"); - 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 + logger.debug(">> running %d node%s group(%s) location(%s) image(%s) hardwareProfile(%s) options(%s)", count, + count > 1 ? "s" : "", group, template.getLocation().getId(), template.getImage().getId(), template .getHardware().getId(), template.getOptions()); Set goodNodes = newLinkedHashSet(); Map badNodes = newLinkedHashMap(); Multimap customizationResponses = LinkedHashMultimap.create(); - Map> responses = runNodesAndAddToSetStrategy.execute(tag, count, template, goodNodes, badNodes, + Map> responses = runNodesAndAddToSetStrategy.execute(group, count, template, goodNodes, badNodes, customizationResponses); Map executionExceptions = awaitCompletion(responses, executor, null, logger, "runNodesWithTag(" - + tag + ")"); + + group + ")"); for (NodeMetadata node : concat(goodNodes, badNodes.keySet())) if (node.getCredentials() != null) credentialStore.put("node#" + node.getId(), node.getCredentials()); if (executionExceptions.size() > 0 || badNodes.size() > 0) { - throw new RunNodesException(tag, count, template, goodNodes, executionExceptions, badNodes); + throw new RunNodesException(group, count, template, goodNodes, executionExceptions, badNodes); } return goodNodes; } - /** - * {@inheritDoc} - */ @Override - public Set runNodesWithTag(String tag, int count, TemplateOptions templateOptions) + public Set createNodesInGroup(String group, int count, TemplateOptions templateOptions) throws RunNodesException { - return runNodesWithTag(tag, count, templateBuilder().any().options(templateOptions).build()); + return createNodesInGroup(group, count, templateBuilder().any().options(templateOptions).build()); + } - /** - * {@inheritDoc} - */ @Override - public Set runNodesWithTag(String tag, int count) throws RunNodesException { - return runNodesWithTag(tag, count, templateOptions()); + public Set createNodesInGroup(String group, int count) throws RunNodesException { + return createNodesInGroup(group, count, templateOptions()); } /** @@ -492,6 +510,13 @@ public class BaseComputeService implements ComputeService { return runScriptOnNodesMatching(filter, runScript, RunScriptOptions.NONE); } + @Override + public Map runScriptOnNodesMatching(Predicate filter, + String runScript, RunScriptOptions options) throws RunScriptOnNodesException { + return runScriptOnNodesMatching(filter, Statements.exec(checkNotNull(runScript, "runScript")), + RunScriptOptions.NONE); + } + /** * {@inheritDoc} */ @@ -562,4 +587,5 @@ public class BaseComputeService implements ComputeService { return executor.submit(initScriptRunnerFactory.create(node, script, options, badNodes)); } } + } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java b/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java index 4b503c854c..6be88dc194 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java +++ b/compute/src/main/java/org/jclouds/compute/internal/ComputeServiceContextImpl.java @@ -42,11 +42,10 @@ public class ComputeServiceContextImpl implements ComputeServiceContext { private final Utils utils; private final Map credentialStore; - @SuppressWarnings({ "unchecked" }) + @SuppressWarnings( { "unchecked" }) @Inject public ComputeServiceContextImpl(ComputeService computeService, Map credentialStore, - Utils utils, - @SuppressWarnings("rawtypes") RestContext providerSpecificContext) { + Utils utils, @SuppressWarnings("rawtypes") RestContext providerSpecificContext) { this.credentialStore = credentialStore; this.utils = utils; this.providerSpecificContext = providerSpecificContext; @@ -57,7 +56,7 @@ public class ComputeServiceContextImpl implements ComputeServiceContext { return computeService; } - @SuppressWarnings({ "unchecked", "hiding" }) + @SuppressWarnings( { "unchecked", "hiding" }) @Override public RestContext getProviderSpecificContext() { return (RestContext) providerSpecificContext; @@ -67,7 +66,7 @@ public class ComputeServiceContextImpl implements ComputeServiceContext { public void close() { providerSpecificContext.close(); } - + @Override public Utils getUtils() { return utils(); diff --git a/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java b/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java index e13fba7fc0..05bcaf1029 100644 --- a/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java +++ b/compute/src/main/java/org/jclouds/compute/predicates/NodePredicates.java @@ -42,8 +42,7 @@ import com.google.common.collect.Sets; */ public class NodePredicates { - private static class ParentLocationId implements - Predicate { + private static class ParentLocationId implements Predicate { private final String id; private ParentLocationId(String id) { @@ -156,8 +155,7 @@ public class NodePredicates { } /** - * Return nodes with the specific ids Note: returns all nodes, regardless of - * the state. + * Return nodes with the specific ids Note: returns all nodes, regardless of the state. * * @param ids * ids of the resources @@ -187,51 +185,67 @@ public class NodePredicates { } /** - * Return nodes with specified tag. Note: returns all nodes, regardless of - * the state. + * Return nodes in the specified group. Note: returns all nodes, regardless of the state. * - * @param tag - * tag to match the items + * @param group + * group to match the items * @return predicate */ - public static Predicate withTag(final String tag) { - Preconditions2.checkNotEmpty(tag, "Tag must be defined"); + public static Predicate inGroup(final String group) { + Preconditions2.checkNotEmpty(group, "group must be defined"); return new Predicate() { @Override public boolean apply(NodeMetadata nodeMetadata) { - return tag.equals(nodeMetadata.getTag()); + return group.equals(nodeMetadata.getGroup()); } @Override public String toString() { - return "withTag(" + tag + ")"; + return "inGroup(" + group + ")"; } }; } /** - * Return nodes with specified tag that are in the NODE_RUNNING state. * - * @param tag - * tag to match the items + * @see #inGroup(String) + */ + @Deprecated + public static Predicate withTag(final String tag) { + return inGroup(tag); + } + + /** + * Return nodes with specified group that are in the NODE_RUNNING state. + * + * @param group + * group to match the items * @return predicate */ - public static Predicate runningWithTag(final String tag) { - Preconditions2.checkNotEmpty(tag, "Tag must be defined"); + public static Predicate runningInGroup(final String group) { + Preconditions2.checkNotEmpty(group, "Tag must be defined"); return new Predicate() { @Override public boolean apply(NodeMetadata nodeMetadata) { - return tag.equals(nodeMetadata.getTag()) - && nodeMetadata.getState() == NodeState.RUNNING; + return group.equals(nodeMetadata.getGroup()) && nodeMetadata.getState() == NodeState.RUNNING; } @Override public String toString() { - return "runningWithTag(" + tag + ")"; + return "runningInGroup(" + group + ")"; } }; } + /** + * + * @see #inGroup(String) + */ + @Deprecated + public static Predicate runningWithTag(final String tag) { + return runningInGroup(tag); + } + /** * Match nodes with State == RUNNING */ diff --git a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java index 18c983fbee..65f5c4dfe3 100644 --- a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java +++ b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java @@ -58,7 +58,7 @@ public interface ComputeServiceConstants { 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\"}}"; + public String osVersionMapJson = "{\"centos\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"rhel\":{\"\":\"\",\"5\":\"5.0\",\"5.2\":\"5.2\",\"5.3\":\"5.3\",\"5.4\":\"5.4\",\"5.5\":\"5.5\"},\"solaris\":{\"\":\"\",\"10\":\"10\"},\"ubuntu\":{\"\":\"\",\"hardy\":\"8.04\",\"karmic\":\"9.10\",\"lucid\":\"10.04\",\"maverick\":\"10.10\",\"natty\":\"11.04\"},\"windows\":{\"\":\"\",\"2003\":\"2003\",\"2003 Standard\":\"2003\",\"2003 R2\":\"2003 R2\",\"2008\":\"2008\",\"2008 Web\":\"2008\",\"2008 Server\":\"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 diff --git a/compute/src/main/java/org/jclouds/compute/strategy/AddNodeWithTagStrategy.java b/compute/src/main/java/org/jclouds/compute/strategy/CreateNodeWithGroupEncodedIntoName.java similarity index 80% rename from compute/src/main/java/org/jclouds/compute/strategy/AddNodeWithTagStrategy.java rename to compute/src/main/java/org/jclouds/compute/strategy/CreateNodeWithGroupEncodedIntoName.java index d4904ccf54..6d91e532cf 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/AddNodeWithTagStrategy.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/CreateNodeWithGroupEncodedIntoName.java @@ -27,21 +27,21 @@ import org.jclouds.compute.domain.Template; * * @author Adrian Cole */ -public interface AddNodeWithTagStrategy { +public interface CreateNodeWithGroupEncodedIntoName { /** * create a node given the name and template parameters such as imageid, hardwareid, and * locationid. * - * @param tag - * tag supplied by the user + * @param group + * group name supplied by the user * @param name - * supplied by {@link RunNodesAndAddToSetStrategy } and must have the tag encoded into + * supplied by {@link CreateNodesInGroupThenAddToSet } and must have the tag encoded into * it. * @param template * supplied by the user * @return NodeMetadata from the new object, most likely in some pending state. */ - NodeMetadata addNodeWithTag(String tag, String name, Template template); + NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template); } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/strategy/RunNodesAndAddToSetStrategy.java b/compute/src/main/java/org/jclouds/compute/strategy/CreateNodesInGroupThenAddToSet.java similarity index 79% rename from compute/src/main/java/org/jclouds/compute/strategy/RunNodesAndAddToSetStrategy.java rename to compute/src/main/java/org/jclouds/compute/strategy/CreateNodesInGroupThenAddToSet.java index bfdcb17b83..0b89940ea0 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/RunNodesAndAddToSetStrategy.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/CreateNodesInGroupThenAddToSet.java @@ -26,19 +26,18 @@ import java.util.concurrent.Future; import org.jclouds.compute.config.CustomizationResponse; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; -import org.jclouds.compute.strategy.impl.EncodeTagIntoNameRunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet; import com.google.common.collect.Multimap; import com.google.inject.ImplementedBy; /** - * creates futures that correlate to * * @author Adrian Cole */ -@ImplementedBy(EncodeTagIntoNameRunNodesAndAddToSetStrategy.class) -public interface RunNodesAndAddToSetStrategy { +@ImplementedBy(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class) +public interface CreateNodesInGroupThenAddToSet { - Map> execute(String tag, int count, Template template, Set goodNodes, + Map> execute(String group, int count, Template template, Set goodNodes, Map badNodes, Multimap customizationResponses); } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java index fcb601adce..6ec428006d 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java @@ -36,7 +36,7 @@ import org.jclouds.compute.domain.NodeState; import org.jclouds.compute.domain.Template; import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; @@ -55,7 +55,7 @@ import com.google.common.collect.Iterables; * */ @Singleton -public class AdaptingComputeServiceStrategies implements AddNodeWithTagStrategy, DestroyNodeStrategy, +public class AdaptingComputeServiceStrategies implements CreateNodeWithGroupEncodedIntoName, DestroyNodeStrategy, GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy, SuspendNodeStrategy { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) @@ -129,12 +129,12 @@ public class AdaptingComputeServiceStrategies implements AddNodeWith * {@inheritDoc} */ @Override - public NodeMetadata addNodeWithTag(String tag, String name, Template template) { - checkState(tag != null, "tag (that which groups identical nodes together) must be specified"); - checkState(name != null && name.indexOf(tag) != -1, "name should have %s encoded into it", tag); + public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { + checkState(group != null, "group (that which groups identical nodes together) must be specified"); + checkState(name != null && name.indexOf(group) != -1, "name should have %s encoded into it", group); checkState(template != null, "template must be specified"); - N from = client.runNodeWithTagAndNameAndStoreCredentials(tag, name, template, credentialStore); + N from = client.createNodeWithGroupEncodedIntoNameThenStoreCredentials(group, name, template, credentialStore); NodeMetadata node = nodeMetadataAdapter.apply(from); return node; } diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/EncodeTagIntoNameRunNodesAndAddToSetStrategy.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java similarity index 92% rename from compute/src/main/java/org/jclouds/compute/strategy/impl/EncodeTagIntoNameRunNodesAndAddToSetStrategy.java rename to compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java index aaadaab3a3..939bbeda00 100755 --- a/compute/src/main/java/org/jclouds/compute/strategy/impl/EncodeTagIntoNameRunNodesAndAddToSetStrategy.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java @@ -44,10 +44,10 @@ import org.jclouds.compute.domain.ComputeMetadata; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; -import org.jclouds.compute.strategy.RunNodesAndAddToSetStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.logging.Logger; import com.google.common.base.Predicate; @@ -59,7 +59,7 @@ import com.google.common.collect.Multimap; * @author Adrian Cole */ @Singleton -public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAndAddToSetStrategy { +public class CreateNodesWithGroupEncodedIntoNameThenAddToSet implements CreateNodesInGroupThenAddToSet { private class AddNode implements Callable { private final String name; @@ -78,7 +78,7 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd logger.debug(">> adding node location(%s) name(%s) image(%s) hardware(%s)", template.getLocation().getId(), name, template.getImage().getProviderId(), template.getHardware() .getProviderId()); - node = addNodeWithTagStrategy.addNodeWithTag(tag, name, template); + node = addNodeWithTagStrategy.createNodeWithGroupEncodedIntoName(tag, name, template); logger.debug("<< %s node(%s)", node.getState(), node.getId()); return node; } @@ -92,15 +92,15 @@ public class EncodeTagIntoNameRunNodesAndAddToSetStrategy implements RunNodesAnd @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; - protected final AddNodeWithTagStrategy addNodeWithTagStrategy; + protected final CreateNodeWithGroupEncodedIntoName addNodeWithTagStrategy; protected final ListNodesStrategy listNodesStrategy; protected final String nodeNamingConvention; protected final ExecutorService executor; protected final CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory; @Inject - protected EncodeTagIntoNameRunNodesAndAddToSetStrategy( - AddNodeWithTagStrategy addNodeWithTagStrategy, + protected CreateNodesWithGroupEncodedIntoNameThenAddToSet( + CreateNodeWithGroupEncodedIntoName addNodeWithTagStrategy, ListNodesStrategy listNodesStrategy, @Named("NAMING_CONVENTION") String nodeNamingConvention, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java index ce5db29dba..6b85faf226 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java @@ -20,8 +20,8 @@ package org.jclouds.compute.stub.config; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentMap; import javax.inject.Inject; @@ -41,8 +41,7 @@ import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; +import org.jclouds.location.suppliers.JustProvider; import org.jclouds.rest.ResourceNotFoundException; import com.google.common.base.Supplier; @@ -62,32 +61,32 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda private final String publicIpPrefix; private final String privateIpPrefix; private final String passwordPrefix; - private final String providerName; + private final Supplier> locationSupplier; private final Map> osToVersionMap; @Inject public StubComputeServiceAdapter(ConcurrentMap nodes, Supplier location, - @Named("NODE_ID") Provider idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix, - @Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix, - @org.jclouds.location.Provider String providerName, Map> osToVersionMap) { + @Named("NODE_ID") Provider idProvider, @Named("PUBLIC_IP_PREFIX") String publicIpPrefix, + @Named("PRIVATE_IP_PREFIX") String privateIpPrefix, @Named("PASSWORD_PREFIX") String passwordPrefix, + JustProvider locationSupplier, Map> osToVersionMap) { this.nodes = nodes; this.location = location; this.idProvider = idProvider; this.publicIpPrefix = publicIpPrefix; this.privateIpPrefix = privateIpPrefix; this.passwordPrefix = passwordPrefix; - this.providerName = providerName; + this.locationSupplier = locationSupplier; this.osToVersionMap = osToVersionMap; } @Override - public NodeMetadata runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public NodeMetadata createNodeWithGroupEncodedIntoNameThenStoreCredentials(String group, String name, Template template, + Map credentialStore) { NodeMetadataBuilder builder = new NodeMetadataBuilder(); String id = idProvider.get() + ""; builder.ids(id); builder.name(name); - builder.tag(tag); + builder.group(group); builder.location(location.get()); builder.imageId(template.getImage().getId()); builder.operatingSystem(template.getImage().getOperatingSystem()); @@ -105,25 +104,22 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda @Override public Iterable listHardwareProfiles() { return ImmutableSet. of(StubComputeServiceDependenciesModule.stub("small", 1, 1740, 160), - StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), - StubComputeServiceDependenciesModule.stub("large", 8, 15360, 1690)); + StubComputeServiceDependenciesModule.stub("medium", 4, 7680, 850), StubComputeServiceDependenciesModule + .stub("large", 8, 15360, 1690)); } @Override public Iterable listImages() { - Location zone = location.get().getParent(); - String parentId = zone.getId(); Credentials defaultCredentials = new Credentials("root", null); Set images = Sets.newLinkedHashSet(); int id = 1; for (boolean is64Bit : new boolean[] { true, false }) for (Entry> osVersions : this.osToVersionMap.entrySet()) { - for (String version : Sets.newHashSet(osVersions.getValue().values())) { + for (String version : Sets.newLinkedHashSet(osVersions.getValue().values())) { String desc = String.format("stub %s %s", osVersions.getKey(), is64Bit); - images.add(new ImageBuilder().providerId(id + "").name(osVersions.getKey().name()) - .id(parentId + "/" + id++).location(zone) - .operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit)) - .description(desc).defaultCredentials(defaultCredentials).build()); + images.add(new ImageBuilder().ids(id++ + "").name(osVersions.getKey().name()).location(location.get()) + .operatingSystem(new OperatingSystem(osVersions.getKey(), desc, version, null, desc, is64Bit)) + .description(desc).defaultCredentials(defaultCredentials).build()); } } return images; @@ -134,13 +130,10 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda return nodes.values(); } + @SuppressWarnings("unchecked") @Override public Iterable listLocations() { - Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); - Location region = new LocationImpl(LocationScope.REGION, providerName + "region", providerName + "region", - provider); - return ImmutableSet. of(new LocationImpl(LocationScope.ZONE, providerName + "zone", providerName - + "zone", region)); + return (Iterable) locationSupplier.get(); } @Override diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java index a9547a6192..e2fe0210a5 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceContextModule.java @@ -26,8 +26,12 @@ import javax.inject.Singleton; import org.jclouds.compute.config.JCloudsNativeComputeServiceAdapterContextModule; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.concurrent.SingleThreaded; +import org.jclouds.domain.Location; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; +import com.google.common.base.Supplier; import com.google.inject.Provides; +import com.google.inject.TypeLiteral; /** * @@ -36,7 +40,7 @@ import com.google.inject.Provides; @SuppressWarnings("rawtypes") @SingleThreaded public class StubComputeServiceContextModule extends - JCloudsNativeComputeServiceAdapterContextModule { + JCloudsNativeComputeServiceAdapterContextModule { public StubComputeServiceContextModule() { super(ConcurrentMap.class, ConcurrentMap.class, StubComputeServiceAdapter.class); @@ -51,6 +55,8 @@ public class StubComputeServiceContextModule extends @Override protected void configure() { install(new StubComputeServiceDependenciesModule()); + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZone.class); super.configure(); } } diff --git a/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java b/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java index 90cd456c49..86007ddb5b 100644 --- a/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java +++ b/compute/src/main/java/org/jclouds/compute/util/ComputeServiceUtils.java @@ -103,12 +103,11 @@ public class ComputeServiceUtils { /** * - * - * @return NOTAG#+from if tag cannot be parsed + * @return null if group cannot be parsed */ - public static String parseTagFromName(String from) { + public static String parseGroupFromName(String from) { Matcher matcher = DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from); - return matcher.find() ? matcher.group(1) : "NOTAG#" + from; + return matcher.find() ? matcher.group(1) : null; } public static double getCores(Hardware input) { @@ -132,17 +131,14 @@ public class ComputeServiceUtils { return total; } - public static org.jclouds.compute.domain.OsFamily parseOsFamilyOrUnrecognized(String provider, String in) { + public static org.jclouds.compute.domain.OsFamily parseOsFamilyOrUnrecognized(String in) { org.jclouds.compute.domain.OsFamily myOs = null; for (org.jclouds.compute.domain.OsFamily os : org.jclouds.compute.domain.OsFamily.values()) { if (in.toLowerCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) { myOs = os; } } - if (myOs == null && provider.indexOf("nebula") != -1) { - myOs = OsFamily.UBUNTU; - } - return OsFamily.UNRECOGNIZED; + return myOs != null ? myOs : OsFamily.UNRECOGNIZED; } public static String createExecutionErrorMessage(Map executionExceptions) { @@ -204,11 +200,13 @@ public class ComputeServiceUtils { "node does not have IP addresses configured: " + node); } - public static String parseVersionOrReturnEmptyString(org.jclouds.compute.domain.OsFamily family, final String in, + public static String parseVersionOrReturnEmptyString(org.jclouds.compute.domain.OsFamily family, String in, Map> osVersionMap) { if (osVersionMap.containsKey(family)) { if (osVersionMap.get(family).containsKey(in)) return osVersionMap.get(family).get(in); + if (osVersionMap.get(family).containsValue(in)) + return in; CONTAINS_SUBSTRING contains = new CONTAINS_SUBSTRING(in.replace('-', '.')); try { String key = Iterables.find(osVersionMap.get(family).keySet(), contains); diff --git a/compute/src/test/clojure/org/jclouds/compute_test.clj b/compute/src/test/clojure/org/jclouds/compute_test.clj index 2fbe44b68d..382a1f81db 100644 --- a/compute/src/test/clojure/org/jclouds/compute_test.clj +++ b/compute/src/test/clojure/org/jclouds/compute_test.clj @@ -53,6 +53,44 @@ list, Alan Dipert and MeikelBrandmeyer." (is (compute-service? (as-compute-service *compute*))) (is (compute-service? (as-compute-service (compute-context *compute*))))) +(deftest nodes-test + (is (empty? (nodes))) + (is (create-node "fred" (build-template + *compute* {} ))) + (is (= 1 (count (nodes)))) + (is (= 1 (count (nodes-in-group "fred")))) + (suspend-nodes-in-group "fred") + (is (suspended? (first (nodes-in-group "fred")))) + (resume-nodes-in-group "fred") + (is (running? (first (nodes-in-group "fred")))) + (reboot-nodes-in-group "fred") + (is (running? (first (nodes-in-group "fred")))) + (is (create-nodes "fred" 2 (build-template + *compute* {} ))) + (is (= 3 (count (nodes-in-group "fred")))) + (is (= "fred" (group (first (nodes))))) + (destroy-nodes-in-group "fred") + (is (terminated? (first (nodes-in-group "fred"))))) + +(deftest nodes-test-deprecated + (is (empty? (nodes))) + (is (run-node "deprecated" (build-template + *compute* {} ))) + (is (= 1 (count (nodes)))) + (is (= 1 (count (nodes-with-tag "deprecated")))) + (suspend-nodes-with-tag "deprecated") + (is (suspended? (first (nodes-with-tag "deprecated")))) + (resume-nodes-with-tag "deprecated") + (is (running? (first (nodes-with-tag "deprecated")))) + (reboot-nodes-with-tag "deprecated") + (is (running? (first (nodes-with-tag "deprecated")))) + (is (run-nodes "deprecated" 2 (build-template + *compute* {} ))) + (is (= 3 (count (nodes-with-tag "deprecated")))) + (is (= "deprecated" (tag (first (nodes))))) + (destroy-nodes-with-tag "deprecated") + (is (terminated? (first (nodes-with-tag "deprecated"))))) + (deftest build-template-test (let [service (compute-service "stub" "user" "password")] (testing "nullary" diff --git a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java index 843123647f..7b37036fb1 100755 --- a/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseComputeServiceLiveTest.java @@ -99,7 +99,7 @@ import com.google.inject.Module; @Test(groups = { "integration", "live" }, sequential = true) public abstract class BaseComputeServiceLiveTest { - protected String tag; + protected String group; protected RetryablePredicate socketTester; protected SortedSet nodes; @@ -132,10 +132,10 @@ public abstract class BaseComputeServiceLiveTest { @BeforeGroups(groups = { "integration", "live" }) public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { setServiceDefaults(); - if (tag == null) - tag = checkNotNull(provider, "provider"); - if (tag.indexOf('-') == -1) - tag = tag + "-"; + if (group == null) + group = checkNotNull(provider, "provider"); + if (group.indexOf('-') == -1) + group = group + "-"; setupCredentials(); setupKeyPairForTest(); initializeContextAndClient(); @@ -215,7 +215,7 @@ public abstract class BaseComputeServiceLiveTest { // starting this one alphabetically before create2nodes.. @Test(enabled = true, dependsOnMethods = { "testCompareSizes" }) public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception { - String tag = this.tag + "r"; + String tag = this.group + "r"; try { client.destroyNodesMatching(withTag(tag)); } catch (Exception e) { @@ -267,19 +267,19 @@ public abstract class BaseComputeServiceLiveTest { @Test(enabled = true, dependsOnMethods = "testCompareSizes") public void testCreateTwoNodesWithRunScript() throws Exception { try { - client.destroyNodesMatching(withTag(tag)); + client.destroyNodesMatching(withTag(group)); } catch (NoSuchElementException e) { } refreshTemplate(); try { - nodes = newTreeSet(client.runNodesWithTag(tag, 2, template)); + nodes = newTreeSet(client.runNodesWithTag(group, 2, template)); } catch (RunNodesException e) { nodes = newTreeSet(concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet())); throw e; } assertEquals(nodes.size(), 2); - checkNodes(nodes, tag); + checkNodes(nodes, group); NodeMetadata node1 = nodes.first(); NodeMetadata node2 = nodes.last(); // credentials aren't always the same @@ -324,8 +324,8 @@ public abstract class BaseComputeServiceLiveTest { public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception { initializeContextAndClient(); refreshTemplate(); - TreeSet nodes = newTreeSet(client.runNodesWithTag(tag, 1, template)); - checkNodes(nodes, tag); + TreeSet nodes = newTreeSet(client.runNodesWithTag(group, 1, template)); + checkNodes(nodes, group); NodeMetadata node = nodes.first(); this.nodes.add(node); assertEquals(nodes.size(), 1); @@ -375,7 +375,7 @@ public abstract class BaseComputeServiceLiveTest { @Test(enabled = true, dependsOnMethods = "testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired") public void testGet() throws Exception { Map metadataMap = newLinkedHashMap(uniqueIndex(filter(client - .listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))), + .listNodesDetailsMatching(all()), and(withTag(group), not(TERMINATED))), new Function() { @Override @@ -407,14 +407,14 @@ public abstract class BaseComputeServiceLiveTest { @Test(enabled = true, dependsOnMethods = "testGet") public void testReboot() throws Exception { - client.rebootNodesMatching(withTag(tag));// TODO test + client.rebootNodesMatching(withTag(group));// TODO test // validation testGet(); } @Test(enabled = true, dependsOnMethods = "testReboot") public void testSuspendResume() throws Exception { - client.suspendNodesMatching(withTag(tag)); + client.suspendNodesMatching(withTag(group)); Set stoppedNodes = refreshNodes(); @@ -430,7 +430,7 @@ public abstract class BaseComputeServiceLiveTest { }) : stoppedNodes; - client.resumeNodesMatching(withTag(tag)); + client.resumeNodesMatching(withTag(group)); testGet(); } @@ -467,22 +467,22 @@ public abstract class BaseComputeServiceLiveTest { @Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" }) public void testDestroyNodes() { int toDestroy = refreshNodes().size(); - Set destroyed = client.destroyNodesMatching(withTag(tag)); + Set destroyed = client.destroyNodesMatching(withTag(group)); assertEquals(toDestroy, destroyed.size()); - for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(tag))) { + for (NodeMetadata node : filter(client.listNodesDetailsMatching(all()), withTag(group))) { assert node.getState() == NodeState.TERMINATED : node; assertEquals(context.getCredentialStore().get("node#" + node.getId()), null); } } private Set refreshNodes() { - return filter(client.listNodesDetailsMatching(all()), and(withTag(tag), not(TERMINATED))); + return filter(client.listNodesDetailsMatching(all()), and(withTag(group), not(TERMINATED))); } @Test(enabled = true) public void testCreateAndRunAService() throws Exception { - String tag = this.tag + "s"; + String tag = this.group + "s"; try { client.destroyNodesMatching(withTag(tag)); } catch (Exception e) { @@ -554,7 +554,7 @@ public abstract class BaseComputeServiceLiveTest { } public void testOptionToNotBlock() throws Exception { - String tag = this.tag + "block"; + String tag = this.group + "block"; try { client.destroyNodesMatching(withTag(tag)); } catch (Exception e) { diff --git a/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java b/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java index 3da0c3d7ed..9fc48f5276 100644 --- a/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/BaseTemplateBuilderLiveTest.java @@ -25,10 +25,10 @@ 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.Map.Entry; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -36,8 +36,11 @@ 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.domain.TemplateBuilder; import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationScope; import org.jclouds.json.Json; import org.jclouds.json.config.GsonModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule; @@ -91,14 +94,14 @@ public abstract class BaseTemplateBuilderLiveTest { @BeforeClass public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { setupCredentials(); - context = new ComputeServiceContextFactory().createContext(provider, - ImmutableSet. of(new Log4JLoggingModule()), setupProperties()); + context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet + . of(new Log4JLoggingModule()), setupProperties()); } @DataProvider(name = "osSupported") public Object[][] osSupported() { - return convertToArray(Sets.filter(provideAllOperatingSystems(), - Predicates.not(defineUnsupportedOperatingSystems()))); + return convertToArray(Sets.filter(provideAllOperatingSystems(), Predicates + .not(defineUnsupportedOperatingSystems()))); } protected Object[][] convertToArray(Set supportedOperatingSystems) { @@ -121,7 +124,7 @@ public abstract class BaseTemplateBuilderLiveTest { protected Set provideAllOperatingSystems() { Map> map = new BaseComputeServiceContextModule() { }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule()) - .getInstance(Json.class)); + .getInstance(Json.class)); Set supportedOperatingSystems = Sets.newHashSet(); for (Entry> osVersions : map.entrySet()) { @@ -135,17 +138,24 @@ public abstract class BaseTemplateBuilderLiveTest { @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); + TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family).os64Bit( + matrix.is64Bit); + if (!matrix.version.equals("")) + builder.osVersionMatches("^" + matrix.version + "$"); + Template template = builder.build(); + if (!matrix.version.equals("")) + 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(); + TemplateBuilder builder = context.getComputeService().templateBuilder().osFamily(matrix.family).os64Bit( + matrix.is64Bit); + if (!matrix.version.equals("")) + builder.osVersionMatches("^" + matrix.version + "$"); + builder.build(); } @Test @@ -153,7 +163,7 @@ public abstract class BaseTemplateBuilderLiveTest { Template defaultTemplate = context.getComputeService().templateBuilder().build(); Template template = context.getComputeService().templateBuilder().imageId(defaultTemplate.getImage().getId()) - .build(); + .build(); assertEquals(template.getImage(), defaultTemplate.getImage()); } @@ -166,6 +176,53 @@ public abstract class BaseTemplateBuilderLiveTest { assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + protected abstract Set getIso3166Codes(); + + @Test(groups = { "integration", "live" }) + public void testGetAssignableLocations() throws Exception { + assertProvider(context.getProviderSpecificContext()); + for (Location location : context.getComputeService().listAssignableLocations()) { + System.err.printf("location %s%n", location); + assert location.getId() != null : location; + assert location != location.getParent() : location; + assert location.getScope() != null : location; + switch (location.getScope()) { + case PROVIDER: + assertProvider(location); + break; + case REGION: + assertProvider(location.getParent()); + assert location.getIso3166Codes().size() == 0 + || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + + " ||" + location.getParent(); + break; + case ZONE: + Location provider = location.getParent().getParent(); + // zone can be a direct descendant of provider + if (provider == null) + provider = location.getParent(); + assertProvider(provider); + assert location.getIso3166Codes().size() == 0 + || location.getParent().getIso3166Codes().containsAll(location.getIso3166Codes()) : location + + " ||" + location.getParent(); + break; + case HOST: + Location provider2 = location.getParent().getParent().getParent(); + // zone can be a direct descendant of provider + if (provider2 == null) + provider2 = location.getParent().getParent(); + assertProvider(provider2); + break; + } + } + } + + void assertProvider(Location provider) { + assertEquals(provider.getScope(), LocationScope.PROVIDER); + assertEquals(provider.getParent(), null); + assertEquals(provider.getIso3166Codes(), getIso3166Codes()); + } + @AfterTest protected void cleanup() throws InterruptedException, ExecutionException, TimeoutException { context.close(); diff --git a/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java b/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java index a13843e384..16473f4e11 100644 --- a/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java +++ b/compute/src/test/java/org/jclouds/compute/ComputeServiceContextFactoryTest.java @@ -43,9 +43,9 @@ public class ComputeServiceContextFactoryTest { public void testStandalone() { @SuppressWarnings("rawtypes") ComputeServiceContext context = new ComputeServiceContextFactory() - .createContext(new StandaloneComputeServiceContextSpec( - "stub", "stub", "1", "identity", "credential", ConcurrentMap.class, - StubComputeServiceContextBuilder.class, ImmutableSet. of())); + .createContext(new StandaloneComputeServiceContextSpec( + "stub", "stub", "1", "", "identity", "credential", ConcurrentMap.class, + StubComputeServiceContextBuilder.class, ImmutableSet. of())); context.getComputeService().listNodes(); } diff --git a/compute/src/test/java/org/jclouds/compute/StubTemplateBuilderIntegrationTest.java b/compute/src/test/java/org/jclouds/compute/StubTemplateBuilderIntegrationTest.java index 2ae0e58692..64d7f2cd4b 100644 --- a/compute/src/test/java/org/jclouds/compute/StubTemplateBuilderIntegrationTest.java +++ b/compute/src/test/java/org/jclouds/compute/StubTemplateBuilderIntegrationTest.java @@ -19,8 +19,12 @@ package org.jclouds.compute; +import java.util.Set; + import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * * @@ -38,4 +42,9 @@ public class StubTemplateBuilderIntegrationTest extends BaseTemplateBuilderLiveT identity = "stub"; credential = "stub"; } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of(); + } } \ No newline at end of file diff --git a/compute/src/test/java/org/jclouds/compute/util/ComputeServiceUtilsTest.java b/compute/src/test/java/org/jclouds/compute/util/ComputeServiceUtilsTest.java index cc008f9aae..89c2912b07 100644 --- a/compute/src/test/java/org/jclouds/compute/util/ComputeServiceUtilsTest.java +++ b/compute/src/test/java/org/jclouds/compute/util/ComputeServiceUtilsTest.java @@ -19,7 +19,7 @@ package org.jclouds.compute.util; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import static org.testng.Assert.assertEquals; import java.net.URI; @@ -41,7 +41,7 @@ public class ComputeServiceUtilsTest { @Test public void testParseTagFromName() { - assertEquals(parseTagFromName("gogrid--849"), "gogrid-"); + assertEquals(parseGroupFromName("gogrid--849"), "gogrid-"); } @Test diff --git a/core/pom.xml b/core/pom.xml index d2bc1f2f7b..aa32086788 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -95,7 +95,7 @@ com.google.guava guava - r07 + r08 com.google.code.findbugs @@ -112,7 +112,7 @@ maven-assembly-plugin - + jar-with-dependencies package @@ -121,7 +121,7 @@ - core-jar-with-dependencies-descriptor.xml + jar-with-dependencies-descriptor.xml diff --git a/core/src/main/java/org/jclouds/Constants.java b/core/src/main/java/org/jclouds/Constants.java index fd7dff67bb..fae9afb416 100644 --- a/core/src/main/java/org/jclouds/Constants.java +++ b/core/src/main/java/org/jclouds/Constants.java @@ -19,6 +19,9 @@ package org.jclouds; +import org.jclouds.domain.Location; +import org.jclouds.location.reference.LocationConstants; + /** * Constants used in jclouds services. * @@ -194,6 +197,7 @@ public interface Constants { * api. */ public static final String PROPERTY_ENDPOINT = "jclouds.endpoint"; + /** * String property. *

@@ -201,6 +205,15 @@ public interface Constants { */ public static final String PROPERTY_IDENTITY = "jclouds.identity"; + /** + * String property. default("") + *

+ * comma-delimited iso 3166 codes; ex. US-CA,US + * + * @see Location#getIso3166Codes + */ + public static final String PROPERTY_ISO3166_CODES = "jclouds." + LocationConstants.ISO3166_CODES; + /** * String property. *

diff --git a/core/src/main/java/org/jclouds/PropertiesBuilder.java b/core/src/main/java/org/jclouds/PropertiesBuilder.java index 21a312ca19..a543ff91b1 100755 --- a/core/src/main/java/org/jclouds/PropertiesBuilder.java +++ b/core/src/main/java/org/jclouds/PropertiesBuilder.java @@ -25,6 +25,7 @@ import static org.jclouds.Constants.PROPERTY_CREDENTIAL; import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_IDENTITY; import static org.jclouds.Constants.PROPERTY_IO_WORKER_THREADS; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_CONTEXT; import static org.jclouds.Constants.PROPERTY_MAX_CONNECTIONS_PER_HOST; import static org.jclouds.Constants.PROPERTY_MAX_CONNECTION_REUSE; @@ -48,6 +49,7 @@ import java.util.Properties; import javax.annotation.Nullable; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Joiner; /** * Builds properties used in Http engines @@ -201,6 +203,7 @@ public class PropertiesBuilder { protected Properties defaultProperties() { Properties props = new Properties(); + props.setProperty(PROPERTY_ISO3166_CODES, ""); props.setProperty(PROPERTY_MAX_CONNECTIONS_PER_CONTEXT, 20 + ""); props.setProperty(PROPERTY_MAX_CONNECTIONS_PER_HOST, 0 + ""); props.setProperty(PROPERTY_SO_TIMEOUT, 60000 + ""); @@ -228,6 +231,11 @@ public class PropertiesBuilder { return this; } + public PropertiesBuilder iso3166Codes(Iterable codes) { + properties.setProperty(PROPERTY_ISO3166_CODES, Joiner.on(',').join(codes)); + return this; + } + public PropertiesBuilder apiVersion(String apiVersion) { properties.setProperty(PROPERTY_API_VERSION, apiVersion); return this; diff --git a/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java b/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java index f7fc29acb0..1d69a2b2d0 100644 --- a/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java +++ b/core/src/main/java/org/jclouds/collect/TransformingSetSupplier.java @@ -21,7 +21,7 @@ package org.jclouds.collect; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.transform; -import static com.google.common.collect.Sets.newHashSet; +import static com.google.common.collect.Sets.newLinkedHashSet; import java.util.Set; @@ -43,7 +43,7 @@ public class TransformingSetSupplier implements Supplier> @Override public Set get() { - return newHashSet(transform(backingSupplier.get(), converter)); + return newLinkedHashSet(transform(backingSupplier.get(), converter)); } } diff --git a/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java b/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java index aba0e8533d..7a41397e50 100755 --- a/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java +++ b/core/src/main/java/org/jclouds/date/internal/SimpleDateFormatDateService.java @@ -142,7 +142,7 @@ public class SimpleDateFormatDateService implements DateService { public static final Pattern NANOS_TO_MILLIS_PATTERN = Pattern .compile(".*[0-9][0-9][0-9][0-9][0-9][0-9]"); - public static final Pattern TZ_PATTERN = Pattern.compile(".*[+-][0-9][0-9]:[0-9][0-9]"); + public static final Pattern TZ_PATTERN = Pattern.compile(".*[+-][0-9][0-9]:?[0-9][0-9]"); private String trimNanosToMillis(String toParse) { if (NANOS_TO_MILLIS_PATTERN.matcher(toParse).matches()) diff --git a/core/src/main/java/org/jclouds/domain/Location.java b/core/src/main/java/org/jclouds/domain/Location.java index f9b9aed0cd..15918552cd 100644 --- a/core/src/main/java/org/jclouds/domain/Location.java +++ b/core/src/main/java/org/jclouds/domain/Location.java @@ -19,15 +19,18 @@ package org.jclouds.domain; +import java.util.Map; +import java.util.Set; + /** - * Running Operating system + * Description of where a resource is running. Note this can be physical or virtual. * * @author Adrian Cole */ public interface Location { /** - * Scope of the location, ex. region, datacenter + * Scope of the location, ex. region, zone, host * */ LocationScope getScope(); @@ -48,4 +51,16 @@ public interface Location { */ Location getParent(); + /** + * @return immutable set of metadata relating to this location + */ + Map getMetadata(); + + /** + * @return if known, the IS0 3166 or 3166-2 divisions where this service may run. ex. a set of + * strings like "US" or "US-CA"; otherwise returns an empty list. + * @see 3166 + */ + Set getIso3166Codes(); } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/domain/LocationBuilder.java b/core/src/main/java/org/jclouds/domain/LocationBuilder.java new file mode 100644 index 0000000000..4a7207b8cc --- /dev/null +++ b/core/src/main/java/org/jclouds/domain/LocationBuilder.java @@ -0,0 +1,77 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Map; +import java.util.Set; + +import org.jclouds.domain.internal.LocationImpl; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +public class LocationBuilder { + protected LocationScope scope; + protected String id; + protected String description; + protected Location parent; + protected Set iso3166Codes = ImmutableSet.of(); + protected Map metadata = ImmutableMap.of(); + + public LocationBuilder scope(LocationScope scope) { + this.scope = scope; + return this; + } + + public LocationBuilder id(String id) { + this.id = id; + return this; + } + + public LocationBuilder description(String description) { + this.description = description; + return this; + } + + public LocationBuilder parent(Location parent) { + this.parent = parent; + return this; + } + + public LocationBuilder iso3166Codes(Iterable iso3166Codes) { + this.iso3166Codes = ImmutableSet.copyOf(checkNotNull(iso3166Codes, "iso3166Codes")); + return this; + } + + public LocationBuilder metadata(Map metadata) { + this.metadata = ImmutableMap.copyOf(checkNotNull(metadata, "metadata")); + return this; + } + + public Location build() { + return new LocationImpl(scope, id, description, parent, iso3166Codes, metadata); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/domain/internal/LocationImpl.java b/core/src/main/java/org/jclouds/domain/internal/LocationImpl.java index d955704d21..a1e28fac1b 100644 --- a/core/src/main/java/org/jclouds/domain/internal/LocationImpl.java +++ b/core/src/main/java/org/jclouds/domain/internal/LocationImpl.java @@ -22,19 +22,22 @@ package org.jclouds.domain.internal; import static com.google.common.base.Preconditions.checkNotNull; import java.io.Serializable; +import java.util.Map; +import java.util.Set; import javax.annotation.Nullable; import org.jclouds.domain.Location; import org.jclouds.domain.LocationScope; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + /** - * Idpayload of the object * * @author Adrian Cole */ public class LocationImpl implements Location, Serializable { - /** The serialVersionUID */ private static final long serialVersionUID = -280558162576368264L; @@ -42,36 +45,75 @@ public class LocationImpl implements Location, Serializable { private final String id; private final String description; private final Location parent; + private final Set iso3166Codes; + private final Map metadata; - public LocationImpl(LocationScope scope, String id, String description, @Nullable Location parent) { + public LocationImpl(LocationScope scope, String id, String description, @Nullable Location parent, + Iterable iso3166Codes, Map metadata) { this.scope = checkNotNull(scope, "scope"); this.id = checkNotNull(id, "id"); this.description = checkNotNull(description, "description"); + this.metadata = ImmutableMap.copyOf(checkNotNull(metadata, "metadata")); + this.iso3166Codes = ImmutableSet.copyOf(checkNotNull(iso3166Codes, "iso3166Codes")); this.parent = parent; } + /** + * {@inheritDoc} + */ + @Override public LocationScope getScope() { return scope; } + /** + * {@inheritDoc} + */ + @Override public String getId() { return id; } + /** + * {@inheritDoc} + */ + @Override public String getDescription() { return description; } + /** + * {@inheritDoc} + */ + @Override public Location getParent() { return parent; } + /** + * {@inheritDoc} + */ + @Override + public Set getIso3166Codes() { + return iso3166Codes; + } + + /** + * {@inheritDoc} + */ + @Override + public Map getMetadata() { + return metadata; + } + @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((iso3166Codes == null) ? 0 : iso3166Codes.hashCode()); + result = prime * result + ((metadata == null) ? 0 : metadata.hashCode()); result = prime * result + ((parent == null) ? 0 : parent.hashCode()); result = prime * result + ((scope == null) ? 0 : scope.hashCode()); return result; @@ -96,6 +138,16 @@ public class LocationImpl implements Location, Serializable { return false; } else if (!id.equals(other.id)) return false; + if (iso3166Codes == null) { + if (other.iso3166Codes != null) + return false; + } else if (!iso3166Codes.equals(other.iso3166Codes)) + return false; + if (metadata == null) { + if (other.metadata != null) + return false; + } else if (!metadata.equals(other.metadata)) + return false; if (parent == null) { if (other.parent != null) return false; @@ -112,7 +164,8 @@ public class LocationImpl implements Location, Serializable { @Override public String toString() { return "[id=" + id + ", scope=" + scope + ", description=" + description + ", parent=" - + ((parent == null) ? null : parent.getId()) + "]"; + + ((parent == null) ? null : parent.getId()) + ", iso3166Codes=" + iso3166Codes + ", metadata=" + + metadata + "]"; } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/domain/internal/MutableResourceMetadataImpl.java b/core/src/main/java/org/jclouds/domain/internal/MutableResourceMetadataImpl.java index 544fc5785b..6dc5116413 100644 --- a/core/src/main/java/org/jclouds/domain/internal/MutableResourceMetadataImpl.java +++ b/core/src/main/java/org/jclouds/domain/internal/MutableResourceMetadataImpl.java @@ -48,7 +48,7 @@ public class MutableResourceMetadataImpl> implements MutableRe private Map userMetadata; public MutableResourceMetadataImpl() { - userMetadata = Maps.newHashMap(); + userMetadata = Maps.newLinkedHashMap(); } public MutableResourceMetadataImpl(ResourceMetadata from) { diff --git a/core/src/main/java/org/jclouds/http/functions/UnwrapOnlyNestedJsonValue.java b/core/src/main/java/org/jclouds/http/functions/UnwrapOnlyNestedJsonValue.java new file mode 100644 index 0000000000..adef09ad0b --- /dev/null +++ b/core/src/main/java/org/jclouds/http/functions/UnwrapOnlyNestedJsonValue.java @@ -0,0 +1,71 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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 java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.http.HttpResponse; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.inject.TypeLiteral; + +/** + * @author Adrian Cole + */ +@Singleton +public class UnwrapOnlyNestedJsonValue implements Function { + + private final ParseJson>> json; + private final TypeLiteral type; + + @Inject + UnwrapOnlyNestedJsonValue(ParseJson>> json, TypeLiteral type) { + this.json = json; + this.type = type; + } + + @SuppressWarnings("unchecked") + @Override + public T apply(HttpResponse arg0) { + Map> map = json.apply(arg0); + if (map == null || map.size() == 0) + return null; + Map map1 = Iterables.getOnlyElement(map.values()); + if (map1 == null || map1.size() == 0) { + if (type.getRawType().isAssignableFrom(Set.class)) + return (T) ImmutableSet.of(); + else if (type.getRawType().isAssignableFrom(List.class)) + return (T) ImmutableList.of(); + else if (type.getRawType().isAssignableFrom(Map.class)) + return (T) ImmutableMap.of(); + return null; + } + return Iterables.getOnlyElement(map1.values()); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/config/ProvideRegionsViaProperties.java b/core/src/main/java/org/jclouds/http/functions/UnwrapOnlyNestedJsonValueInSet.java similarity index 60% rename from core/src/main/java/org/jclouds/location/config/ProvideRegionsViaProperties.java rename to core/src/main/java/org/jclouds/http/functions/UnwrapOnlyNestedJsonValueInSet.java index 534951e85c..5119797240 100644 --- a/core/src/main/java/org/jclouds/location/config/ProvideRegionsViaProperties.java +++ b/core/src/main/java/org/jclouds/http/functions/UnwrapOnlyNestedJsonValueInSet.java @@ -17,40 +17,36 @@ * ==================================================================== */ -package org.jclouds.location.config; - -import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; +package org.jclouds.http.functions; import java.util.Set; import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.location.Region; +import org.jclouds.http.HttpResponse; -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableSet; +import com.google.common.base.Function; +import com.google.common.collect.Iterables; /** - * * @author Adrian Cole */ @Singleton -public class ProvideRegionsViaProperties implements javax.inject.Provider> { +public class UnwrapOnlyNestedJsonValueInSet implements Function { - private final Set regions; + private final UnwrapOnlyNestedJsonValue> json; @Inject - ProvideRegionsViaProperties(@Named(PROPERTY_REGIONS) String regions) { - this.regions = ImmutableSet.copyOf(Splitter.on(',').split(regions)); + UnwrapOnlyNestedJsonValueInSet(UnwrapOnlyNestedJsonValue> json) { + this.json = json; } - @Singleton - @Region @Override - public Set get() { - return regions; + public T apply(HttpResponse arg0) { + Set set = json.apply(arg0); + if (set == null || set.size() == 0) + return null; + return Iterables.getOnlyElement(set); } - } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/io/Payloads.java b/core/src/main/java/org/jclouds/io/Payloads.java index 55f3b87ffd..e143183ceb 100644 --- a/core/src/main/java/org/jclouds/io/Payloads.java +++ b/core/src/main/java/org/jclouds/io/Payloads.java @@ -89,7 +89,7 @@ public class Payloads { } public static UrlEncodedFormPayload newUrlEncodedFormPayload(Multimap formParams, - @Nullable Comparator> sorter, char... skips) { + @Nullable Comparator> sorter, char... skips) { return new UrlEncodedFormPayload(formParams, sorter, skips); } @@ -109,14 +109,16 @@ public class Payloads { public static Payload calculateMD5(Payload payload, MessageDigest md5) throws IOException { checkNotNull(payload, "payload"); if (!payload.isRepeatable()) { - String oldContentType = payload.getContentMetadata().getContentType(); + MutableContentMetadata oldContentMetadata = payload.getContentMetadata(); Payload oldPayload = payload; try { payload = newByteArrayPayload(toByteArray(payload)); } finally { oldPayload.release(); } - payload.getContentMetadata().setContentType(oldContentType); + oldContentMetadata.setContentLength(payload.getContentMetadata().getContentLength()); + oldContentMetadata.setContentMD5(payload.getContentMetadata().getContentMD5()); + payload.setContentMetadata(oldContentMetadata); } payload.getContentMetadata().setContentMD5(CryptoStreams.digest(payload, md5)); return payload; diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindRevertResizeToJsonPayload.java b/core/src/main/java/org/jclouds/location/Iso3166.java similarity index 66% rename from apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindRevertResizeToJsonPayload.java rename to core/src/main/java/org/jclouds/location/Iso3166.java index 86dd21172e..4e59544fb0 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindRevertResizeToJsonPayload.java +++ b/core/src/main/java/org/jclouds/location/Iso3166.java @@ -17,23 +17,24 @@ * ==================================================================== */ -package org.jclouds.cloudservers.binders; +package org.jclouds.location; -import javax.inject.Singleton; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.Binder; +import javax.inject.Qualifier; /** + * Related to a Iso3166 code * * @author Adrian Cole * */ -@Singleton -public class BindRevertResizeToJsonPayload implements Binder { - @Override - public R bindToRequest(R request, Object toBind) { - request.setPayload("{\"revertResize\":null}"); - return request; - } -} +@Retention(value = RetentionPolicy.RUNTIME) +@Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) +@Qualifier +public @interface Iso3166 { + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/config/JustProviderLocationModule.java b/core/src/main/java/org/jclouds/location/config/JustProviderLocationModule.java new file mode 100644 index 0000000000..bda125d1fa --- /dev/null +++ b/core/src/main/java/org/jclouds/location/config/JustProviderLocationModule.java @@ -0,0 +1,56 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.location.config; + +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import org.jclouds.domain.Location; +import org.jclouds.location.suppliers.JustProvider; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; +import org.jclouds.rest.AuthorizationException; + +import com.google.common.base.Supplier; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + * + */ +public class JustProviderLocationModule extends LocationModule { + public JustProviderLocationModule() { + super(); + } + + public JustProviderLocationModule(AtomicReference authException) { + super(authException); + } + + @Override + protected void configure() { + bind(new TypeLiteral>>() { + }).to(JustProvider.class); + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZone.class); + super.configure(); + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/config/LocationModule.java b/core/src/main/java/org/jclouds/location/config/LocationModule.java new file mode 100644 index 0000000000..22bf018804 --- /dev/null +++ b/core/src/main/java/org/jclouds/location/config/LocationModule.java @@ -0,0 +1,96 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.location.config; + +import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.collect.Memoized; +import org.jclouds.domain.Location; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.suppliers.RetryOnTimeOutButNotOnAuthorizationExceptionSupplier; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.Maps; +import com.google.inject.AbstractModule; +import com.google.inject.Provides; + +/** + * + * @author Adrian Cole + */ +public class LocationModule extends AbstractModule { + protected final AtomicReference authException; + + public LocationModule() { + this(new AtomicReference()); + } + + public LocationModule(AtomicReference authException) { + this.authException = authException; + } + + @Provides + @Singleton + protected Supplier> provideLocationMap( + @Memoized Supplier> locations) { + return Suppliers.compose(new Function, Map>() { + + @Override + public Map apply(Set from) { + return Maps.uniqueIndex(from, new Function() { + + @Override + public String apply(Location from) { + return from.getId(); + } + + }); + } + + }, locations); + } + + @Provides + @Singleton + @Memoized + protected Supplier> supplyLocationCache(@Named(PROPERTY_SESSION_INTERVAL) long seconds, + final Supplier> locationSupplier) { + return new RetryOnTimeOutButNotOnAuthorizationExceptionSupplier>(authException, seconds, + new Supplier>() { + @Override + public Set get() { + return locationSupplier.get(); + } + }); + } + + @Override + protected void configure() { + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaProperties.java b/core/src/main/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaProperties.java new file mode 100644 index 0000000000..33f27623ad --- /dev/null +++ b/core/src/main/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaProperties.java @@ -0,0 +1,86 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.location.config; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.inject.name.Names.named; +import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONE; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.location.Iso3166; + +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableMap.Builder; +import com.google.inject.ConfigurationException; +import com.google.inject.Injector; +import com.google.inject.Key; + +/** + * + * looks for properties bound to the naming conventions jclouds.region.{@code regionId} + * .iso3166-codes and jclouds.zone.{@code zoneId}.iso3166-codes + * + * @author Adrian Cole + */ +@Singleton +public class ProvideIso3166CodesByLocationIdViaProperties implements javax.inject.Provider>> { + + private final Injector injector; + + @Inject + ProvideIso3166CodesByLocationIdViaProperties(Injector injector) { + this.injector = checkNotNull(injector, "injector"); + } + + @Singleton + @Iso3166 + @Override + public Map> get() { + Builder> codes = ImmutableMap.> builder(); + for (String key : ImmutableSet.of(PROPERTY_REGION, PROPERTY_ZONE)) + try { + String regionString = injector.getInstance(Key.get(String.class, named(key + "s"))); + for (String region : Splitter.on(',').split(regionString)) { + try { + codes.put(region, ImmutableSet.copyOf(Splitter.on(',') + .split( + injector.getInstance(Key.get(String.class, named(key + "." + region + "." + + ISO3166_CODES)))))); + } catch (ConfigurationException e) { + // this happens if regions property isn't set + // services not run by AWS may not have regions, so this is ok. + } + } + } catch (ConfigurationException e) { + // this happens if regions property isn't set + // services not run by AWS may not have regions, so this is ok. + } + return codes.build(); + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java b/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java index 3c5efaf94e..13bb1c1a11 100644 --- a/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java +++ b/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java @@ -19,6 +19,7 @@ package org.jclouds.location.config; +import static org.jclouds.location.reference.LocationConstants.ENDPOINT; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; @@ -28,7 +29,6 @@ import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; -import org.jclouds.location.Provider; import org.jclouds.location.Region; import com.google.common.base.Splitter; @@ -41,7 +41,7 @@ import com.google.inject.name.Names; /** * - * looks for properties bound to the naming convention jclouds.location.region.{@code regionId}.endpoint + * looks for properties bound to the naming convention jclouds.region.{@code regionId}.endpoint * * @author Adrian Cole */ @@ -63,17 +63,14 @@ public class ProvideRegionToURIViaProperties implements javax.inject.Provider regions = ImmutableMap. builder(); for (String region : Splitter.on(',').split(regionString)) { - regions.put( - region, - URI.create(injector.getInstance(Key.get(String.class, - Names.named(PROPERTY_REGION + "." + region + ".endpoint"))))); + regions.put(region, URI.create(injector.getInstance(Key.get(String.class, Names.named(PROPERTY_REGION + "." + + region + "." + ENDPOINT))))); } return regions.build(); } catch (ConfigurationException e) { // this happens if regions property isn't set // services not run by AWS may not have regions, so this is ok. - return ImmutableMap.of(injector.getInstance(Key.get(String.class, Provider.class)), - injector.getInstance(Key.get(URI.class, Provider.class))); + return ImmutableMap.of(); } } diff --git a/sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/blobstore/config/ScaleUpStorageBlobStoreContextModule.java b/core/src/main/java/org/jclouds/location/config/RegionsLocationModule.java similarity index 58% rename from sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/blobstore/config/ScaleUpStorageBlobStoreContextModule.java rename to core/src/main/java/org/jclouds/location/config/RegionsLocationModule.java index dc5c4dba85..b23b28cbb5 100644 --- a/sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/blobstore/config/ScaleUpStorageBlobStoreContextModule.java +++ b/core/src/main/java/org/jclouds/location/config/RegionsLocationModule.java @@ -17,26 +17,31 @@ * ==================================================================== */ -package org.jclouds.scaleup.storage.blobstore.config; +package org.jclouds.location.config; + +import java.util.Set; -import org.jclouds.s3.blobstore.config.S3BlobStoreContextModule; -import org.jclouds.s3.domain.BucketMetadata; import org.jclouds.domain.Location; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZoneOrRegionMatchingRegionId; +import org.jclouds.location.suppliers.RegionToProviderOrJustProvider; -import com.google.common.base.Function; -import com.google.common.base.Functions; +import com.google.common.base.Supplier; import com.google.inject.TypeLiteral; /** * * @author Adrian Cole + * */ -public class ScaleUpStorageBlobStoreContextModule extends S3BlobStoreContextModule { - // TODO: this is really a scality concern that is coupled to all installations of theirs - @SuppressWarnings({ "rawtypes", "unchecked" }) +public class RegionsLocationModule extends LocationModule { + @Override - protected void bindBucketLocationStrategy() { - bind(new TypeLiteral>() { - }).toInstance((Function) Functions.constant(null)); + protected void configure() { + bind(new TypeLiteral>>() { + }).to(RegionToProviderOrJustProvider.class); + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZoneOrRegionMatchingRegionId.class); + super.configure(); } -} + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/functions/ZoneToEndpoint.java b/core/src/main/java/org/jclouds/location/functions/ZoneToEndpoint.java index e8e76b6ef9..71cef367f0 100644 --- a/core/src/main/java/org/jclouds/location/functions/ZoneToEndpoint.java +++ b/core/src/main/java/org/jclouds/location/functions/ZoneToEndpoint.java @@ -19,9 +19,12 @@ package org.jclouds.location.functions; +import static com.google.common.base.Preconditions.checkArgument; + import java.net.URI; import java.util.Map; +import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; @@ -35,6 +38,7 @@ import com.google.common.base.Function; */ @Singleton public class ZoneToEndpoint implements Function { + private final Map zoneToEndpoint; @Inject @@ -42,8 +46,9 @@ public class ZoneToEndpoint implements Function { this.zoneToEndpoint = zoneToEndpoint; } - public URI apply(Object from) { + @Override + public URI apply(@Nullable Object from) { + checkArgument(from != null, "you must specify a zone"); return zoneToEndpoint.get(from); } - } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/reference/LocationConstants.java b/core/src/main/java/org/jclouds/location/reference/LocationConstants.java index 19a6667d31..c023db0954 100644 --- a/core/src/main/java/org/jclouds/location/reference/LocationConstants.java +++ b/core/src/main/java/org/jclouds/location/reference/LocationConstants.java @@ -24,6 +24,10 @@ package org.jclouds.location.reference; * @author Adrian Cole */ public interface LocationConstants { - public static final String PROPERTY_REGIONS = "jclouds.location.regions"; - public static final String PROPERTY_REGION = "jclouds.location.region"; + public static final String ENDPOINT = "endpoint"; + public static final String ISO3166_CODES = "iso3166-codes"; + public static final String PROPERTY_REGIONS = "jclouds.regions"; + public static final String PROPERTY_REGION = "jclouds.region"; + public static final String PROPERTY_ZONES = "jclouds.zones"; + public static final String PROPERTY_ZONE = "jclouds.zone"; } diff --git a/core/src/main/java/org/jclouds/location/suppliers/SupplyPredefinedRegions.java b/core/src/main/java/org/jclouds/location/suppliers/JustProvider.java similarity index 61% rename from core/src/main/java/org/jclouds/location/suppliers/SupplyPredefinedRegions.java rename to core/src/main/java/org/jclouds/location/suppliers/JustProvider.java index 98c50a55be..9699cf99a2 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/SupplyPredefinedRegions.java +++ b/core/src/main/java/org/jclouds/location/suppliers/JustProvider.java @@ -19,6 +19,8 @@ package org.jclouds.location.suppliers; +import static com.google.common.base.Preconditions.checkNotNull; + import java.net.URI; import java.util.Set; @@ -26,39 +28,35 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; +import org.jclouds.location.Iso3166; import org.jclouds.location.Provider; -import org.jclouds.location.Region; import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; /** * * @author Adrian Cole */ @Singleton -public class SupplyPredefinedRegions implements Supplier> { - private final Set regions; +public class JustProvider implements Supplier> { private final String providerName; private final URI endpoint; + private final Set isoCodes; @Inject - SupplyPredefinedRegions(@Region Set regions, @Provider String providerName, @Provider URI endpoint) { - this.regions = regions; - this.providerName = providerName; - this.endpoint = endpoint; + public JustProvider(@Iso3166 Set isoCodes, @Provider String providerName, @Provider URI endpoint) { + this.providerName = checkNotNull(providerName, "providerName"); + this.endpoint = checkNotNull(endpoint, "endpoint"); + this.isoCodes = checkNotNull(isoCodes, "isoCodes"); } @Override public Set get() { - Builder locations = ImmutableSet.builder(); - Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, endpoint.toASCIIString(), null); - for (String zone : regions) { - locations.add(new LocationImpl(LocationScope.REGION, zone.toString(), zone.toString(), provider)); - } - return locations.build(); + return ImmutableSet.of(new LocationBuilder().scope(LocationScope.PROVIDER).id(providerName).description( + endpoint.toASCIIString()).iso3166Codes(isoCodes).build()); } + } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/OnlyLocationOrFirstZoneOrRegionMatchingRegionId.java b/core/src/main/java/org/jclouds/location/suppliers/OnlyLocationOrFirstZoneOrRegionMatchingRegionId.java index 221693b836..65023641a6 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/OnlyLocationOrFirstZoneOrRegionMatchingRegionId.java +++ b/core/src/main/java/org/jclouds/location/suppliers/OnlyLocationOrFirstZoneOrRegionMatchingRegionId.java @@ -36,6 +36,8 @@ import org.jclouds.location.Region; import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.collect.Iterables; +import com.google.inject.Injector; +import com.google.inject.Key; /** * @author Adrian Cole @@ -55,12 +57,12 @@ public class OnlyLocationOrFirstZoneOrRegionMatchingRegionId implements Supplier @Override public boolean apply(Location input) { switch (input.getScope()) { - case ZONE: - return input.getParent().getId().equals(region); - case REGION: - return input.getId().equals(region); - default: - return false; + case ZONE: + return input.getParent().getId().equals(region); + case REGION: + return input.getId().equals(region); + default: + return false; } } @@ -70,13 +72,13 @@ public class OnlyLocationOrFirstZoneOrRegionMatchingRegionId implements Supplier } } - private final IsRegionAndIdEqualsOrIsZoneParentIdEquals matcher; + private final Injector injector; private final Supplier> locationsSupplier; @Inject - OnlyLocationOrFirstZoneOrRegionMatchingRegionId(IsRegionAndIdEqualsOrIsZoneParentIdEquals matcher, - @Memoized Supplier> locationsSupplier) { - this.matcher = checkNotNull(matcher, "matcher"); + OnlyLocationOrFirstZoneOrRegionMatchingRegionId(Injector injector, + @Memoized Supplier> locationsSupplier) { + this.injector = checkNotNull(injector, "injector"); this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplier"); } @@ -86,7 +88,12 @@ public class OnlyLocationOrFirstZoneOrRegionMatchingRegionId implements Supplier Set locations = locationsSupplier.get(); if (locationsSupplier.get().size() == 1) return getOnlyElement(locationsSupplier.get()); + IsRegionAndIdEqualsOrIsZoneParentIdEquals matcher = null; try { + String region = injector.getInstance(Key.get(String.class, Region.class)); + if (region == null) + return Iterables.get(locationsSupplier.get(), 0); + matcher = injector.getInstance(IsRegionAndIdEqualsOrIsZoneParentIdEquals.class); Location toReturn = Iterables.find(locations, matcher); return toReturn.getScope() == LocationScope.REGION ? toReturn : toReturn.getParent(); } catch (NoSuchElementException e) { diff --git a/core/src/main/java/org/jclouds/location/suppliers/RegionToProviderOrJustProvider.java b/core/src/main/java/org/jclouds/location/suppliers/RegionToProviderOrJustProvider.java index f4abd9c546..ee030b6521 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/RegionToProviderOrJustProvider.java +++ b/core/src/main/java/org/jclouds/location/suppliers/RegionToProviderOrJustProvider.java @@ -21,50 +21,60 @@ package org.jclouds.location.suppliers; import static com.google.common.base.Preconditions.checkNotNull; +import java.net.URI; +import java.util.Map; import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; +import org.jclouds.location.Iso3166; import org.jclouds.location.Provider; import org.jclouds.location.Region; -import com.google.common.base.Function; -import com.google.common.base.Supplier; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableSet.Builder; /** * * @author Adrian Cole */ @Singleton -public class RegionToProviderOrJustProvider implements Supplier> { +public class RegionToProviderOrJustProvider extends JustProvider { private final Set regions; - private final String providerName; + private final Map> isoCodesById; @Inject - RegionToProviderOrJustProvider(@Region Set regions, @Provider String providerName) { + public RegionToProviderOrJustProvider(@Iso3166 Set isoCodes, @Provider String providerName, + @Provider URI endpoint, @Region Set regions, @Iso3166 Map> isoCodesById) { + super(isoCodes, providerName, endpoint); this.regions = checkNotNull(regions, "regions"); - this.providerName = checkNotNull(providerName, "providerName"); + this.isoCodesById = checkNotNull(isoCodesById, "isoCodesById"); } @Override public Set get() { - final Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); + return buildJustProviderOrRegions().build(); + } + + protected Builder buildJustProviderOrRegions() { + Builder locations = ImmutableSet.builder(); + Location provider = Iterables.getOnlyElement(super.get()); if (regions.size() == 0) - return ImmutableSet.of(provider); - return ImmutableSet. copyOf(Iterables.transform(regions, new Function() { - - @Override - public Location apply(String input) { - return new LocationImpl(LocationScope.REGION, input, input, provider); + return locations.add(provider); + else + for (String region : regions) { + LocationBuilder builder = new LocationBuilder().scope(LocationScope.REGION).id(region).description(region) + .parent(provider); + if (isoCodesById.containsKey(region)) + builder.iso3166Codes(isoCodesById.get(region)); + locations.add(builder.build()); } - - })); + return locations; } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/ZoneToRegionToProviderOrJustProvider.java b/core/src/main/java/org/jclouds/location/suppliers/ZoneToRegionToProviderOrJustProvider.java index 15dd7f661b..7735fa83f9 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/ZoneToRegionToProviderOrJustProvider.java +++ b/core/src/main/java/org/jclouds/location/suppliers/ZoneToRegionToProviderOrJustProvider.java @@ -21,8 +21,8 @@ package org.jclouds.location.suppliers; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Maps.uniqueIndex; -import static com.google.common.collect.Sets.newLinkedHashSet; +import java.net.URI; import java.util.Map; import java.util.Set; @@ -30,50 +30,61 @@ import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; +import org.jclouds.location.Iso3166; import org.jclouds.location.Provider; import org.jclouds.location.Zone; import com.google.common.base.Function; -import com.google.common.base.Supplier; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; /** * * @author Adrian Cole */ @Singleton -public class ZoneToRegionToProviderOrJustProvider implements Supplier> { +public class ZoneToRegionToProviderOrJustProvider extends RegionToProviderOrJustProvider { private final Map zoneToRegion; - private final String providerName; + private Map> isoCodesById; @Inject - ZoneToRegionToProviderOrJustProvider(@Zone Map zoneToRegion, @Provider String providerName) { - this.zoneToRegion = checkNotNull(zoneToRegion, "zoneToRegion"); - this.providerName = checkNotNull(providerName, "providerName"); + ZoneToRegionToProviderOrJustProvider(@Iso3166 Set isoCodes, @Provider String providerName, + @Provider URI endpoint, @Iso3166 Map> isoCodesById, + @Zone Map zoneToRegion) { + super(isoCodes, providerName, endpoint, ImmutableSet.copyOf(checkNotNull(zoneToRegion, "zoneToRegion").values()), + isoCodesById); + this.zoneToRegion = zoneToRegion; + this.isoCodesById = checkNotNull(isoCodesById, "isoCodesById"); } @Override public Set get() { - Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); - if (zoneToRegion.size() == 0) - return ImmutableSet.of(provider); - Set providers = newLinkedHashSet(); - for (String region : newLinkedHashSet(zoneToRegion.values())) { - providers.add(new LocationImpl(LocationScope.REGION, region, region, provider)); - } - ImmutableMap idToLocation = uniqueIndex(providers, new Function() { + Builder locations = buildJustProviderOrRegions(); + ImmutableMap idToLocation = uniqueIndex(locations.build(), new Function() { @Override public String apply(Location from) { return from.getId(); } }); + if (zoneToRegion.size() == 1) + return locations.build(); for (String zone : zoneToRegion.keySet()) { - providers.add(new LocationImpl(LocationScope.ZONE, zone, zone, idToLocation.get(zoneToRegion.get(zone)))); + Location parent = idToLocation.get(zoneToRegion.get(zone)); + LocationBuilder builder = new LocationBuilder().scope(LocationScope.ZONE).id(zone).description(zone).parent( + parent); + if (isoCodesById.containsKey(zone)) + builder.iso3166Codes(isoCodesById.get(zone)); + // be cautious.. only inherit iso codes if the parent is a region + // regions may be added dynamically, and we prefer to inherit an + // empty set of codes from a region, then a provider, whose code + // are likely hard-coded. + else if (parent.getScope() == LocationScope.REGION) + builder.iso3166Codes(parent.getIso3166Codes()); + locations.add(builder.build()); } - return providers; + return locations.build(); } - } \ No newline at end of file diff --git a/sandbox-apis/libvirt/src/main/java/org/jclouds/libvirt/compute/functions/LibvirtNodeToLocation.java b/core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java similarity index 60% rename from sandbox-apis/libvirt/src/main/java/org/jclouds/libvirt/compute/functions/LibvirtNodeToLocation.java rename to core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java index ac7e71d4f9..32ab424460 100644 --- a/sandbox-apis/libvirt/src/main/java/org/jclouds/libvirt/compute/functions/LibvirtNodeToLocation.java +++ b/core/src/main/java/org/jclouds/rest/InsufficientResourcesException.java @@ -17,26 +17,27 @@ * ==================================================================== */ -package org.jclouds.libvirt.compute.functions; - -import javax.inject.Singleton; - -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.libvirt.Datacenter; - -import com.google.common.base.Function; +package org.jclouds.rest; /** + * Thrown when there is a quota or otherwise limit preventing the operation from occurring. + * * @author Adrian Cole */ -@Singleton -public class LibvirtNodeToLocation implements Function { +public class InsufficientResourcesException extends RuntimeException { - @Override - public Location apply(Datacenter from) { - return new LocationImpl(LocationScope.ZONE, from.id + "", from.name, null); + /** The serialVersionUID */ + private static final long serialVersionUID = -2272965726680821281L; + + public InsufficientResourcesException() { + super(); } + public InsufficientResourcesException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + public InsufficientResourcesException(Throwable arg0) { + super(arg0); + } } diff --git a/core/src/main/java/org/jclouds/rest/MapBinder.java b/core/src/main/java/org/jclouds/rest/MapBinder.java index ee9a507ff2..d809877811 100644 --- a/core/src/main/java/org/jclouds/rest/MapBinder.java +++ b/core/src/main/java/org/jclouds/rest/MapBinder.java @@ -34,7 +34,7 @@ public interface MapBinder extends Binder { /** * creates and binds the POST payload to the request using parameters specified. * - * @see org.jclouds.rest.annotations.MapPayloadParam + * @see org.jclouds.rest.annotations.PayloadParam */ R bindToRequest(R request, Map postParams); } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/RestContext.java b/core/src/main/java/org/jclouds/rest/RestContext.java index 116e2313bd..0aca54a739 100755 --- a/core/src/main/java/org/jclouds/rest/RestContext.java +++ b/core/src/main/java/org/jclouds/rest/RestContext.java @@ -24,6 +24,7 @@ import java.util.Map; import java.util.concurrent.Future; import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; import org.jclouds.rest.internal.RestContextImpl; import com.google.common.annotations.Beta; @@ -40,7 +41,7 @@ import com.google.inject.ImplementedBy; * */ @ImplementedBy(RestContextImpl.class) -public interface RestContext { +public interface RestContext extends Location { /** * low-level api to the cloud. Threadsafe implementations will return a singleton. @@ -59,6 +60,10 @@ public interface RestContext { URI getEndpoint(); + String getApiVersion(); + + String getIdentity(); + /** * retrieves a list of credentials for resources created within this context, keyed on {@code id} * of the resource. We are testing this approach for resources such as compute nodes, where you @@ -71,12 +76,6 @@ public interface RestContext { @Beta Map credentialStore(); - String getIdentity(); - - String getProvider(); - - String getApiVersion(); - Utils getUtils(); /** diff --git a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java index 3a8fe09510..8bfc110009 100755 --- a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java +++ b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java @@ -20,17 +20,30 @@ package org.jclouds.rest; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.equalTo; +import static com.google.common.base.Predicates.instanceOf; +import static com.google.common.base.Predicates.not; +import static com.google.common.base.Splitter.on; +import static com.google.common.collect.Iterables.addAll; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.filter; +import static com.google.inject.Scopes.SINGLETON; +import static com.google.inject.name.Names.bindProperties; +import static com.google.inject.util.Types.newParameterizedType; import static org.jclouds.Constants.PROPERTY_API; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_CREDENTIAL; import static org.jclouds.Constants.PROPERTY_ENDPOINT; import static org.jclouds.Constants.PROPERTY_IDENTITY; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.Constants.PROPERTY_PROVIDER; import java.net.URI; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Properties; +import java.util.Set; import javax.inject.Inject; @@ -41,7 +54,9 @@ import org.jclouds.concurrent.config.ExecutorServiceModule; import org.jclouds.http.RequiresHttp; import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; +import org.jclouds.location.Iso3166; import org.jclouds.location.Provider; +import org.jclouds.location.config.ProvideIso3166CodesByLocationIdViaProperties; import org.jclouds.logging.config.LoggingModule; import org.jclouds.logging.jdk.config.JDKLoggingModule; import org.jclouds.rest.annotations.Api; @@ -55,17 +70,13 @@ import org.jclouds.rest.internal.RestContextImpl; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; -import com.google.inject.Scopes; import com.google.inject.TypeLiteral; -import com.google.inject.name.Names; -import com.google.inject.util.Types; /** * Creates {@link RestContext} or {@link Injector} instances based on the most commonly requested @@ -94,18 +105,25 @@ public class RestContextBuilder { Properties toBind = new Properties(); toBind.putAll(checkNotNull(properties, "properties")); toBind.putAll(System.getProperties()); - Names.bindProperties(binder(), toBind); + bindProperties(binder(), toBind); bind(String.class).annotatedWith(Provider.class).toInstance( - checkNotNull(toBind.getProperty(PROPERTY_PROVIDER), PROPERTY_PROVIDER)); + checkNotNull(toBind.getProperty(PROPERTY_PROVIDER), PROPERTY_PROVIDER)); bind(URI.class).annotatedWith(Provider.class).toInstance( - URI.create(checkNotNull(toBind.getProperty(PROPERTY_ENDPOINT), PROPERTY_ENDPOINT))); + URI.create(checkNotNull(toBind.getProperty(PROPERTY_ENDPOINT), PROPERTY_ENDPOINT))); + bind(new TypeLiteral>() { + }).annotatedWith(Iso3166.class).toInstance( + ImmutableSet.copyOf(filter(on(',').split( + checkNotNull(toBind.getProperty(PROPERTY_ISO3166_CODES), PROPERTY_ISO3166_CODES)), + not(equalTo(""))))); + bind(new TypeLiteral>>() { + }).annotatedWith(Iso3166.class).toProvider(ProvideIso3166CodesByLocationIdViaProperties.class); if (toBind.containsKey(PROPERTY_API)) bind(String.class).annotatedWith(Api.class).toInstance(toBind.getProperty(PROPERTY_API)); if (toBind.containsKey(PROPERTY_API_VERSION)) bind(String.class).annotatedWith(ApiVersion.class).toInstance(toBind.getProperty(PROPERTY_API_VERSION)); if (toBind.containsKey(PROPERTY_IDENTITY)) bind(String.class).annotatedWith(Identity.class).toInstance( - checkNotNull(toBind.getProperty(PROPERTY_IDENTITY), PROPERTY_IDENTITY)); + checkNotNull(toBind.getProperty(PROPERTY_IDENTITY), PROPERTY_IDENTITY)); if (toBind.containsKey(PROPERTY_CREDENTIAL)) bind(String.class).annotatedWith(Credential.class).toInstance(toBind.getProperty(PROPERTY_CREDENTIAL)); } @@ -124,7 +142,7 @@ public class RestContextBuilder { } public RestContextBuilder withModules(Iterable modules) { - Iterables.addAll(this.modules, modules); + addAll(this.modules, modules); return this; } @@ -142,7 +160,7 @@ public class RestContextBuilder { @VisibleForTesting protected void addLoggingModuleIfNotPresent(List modules) { - if (!Iterables.any(modules, Predicates.instanceOf(LoggingModule.class))) + if (!any(modules, instanceOf(LoggingModule.class))) modules.add(new JDKLoggingModule()); } @@ -153,7 +171,7 @@ public class RestContextBuilder { } private boolean nothingConfiguresAnHttpService(List modules) { - return (!Iterables.any(modules, new Predicate() { + return (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresHttpCommandExecutorService.class); } @@ -163,7 +181,7 @@ public class RestContextBuilder { @VisibleForTesting protected void addContextModuleIfNotPresent(List modules) { - if (!Iterables.any(modules, new Predicate() { + if (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresRestContext.class); } @@ -177,20 +195,20 @@ public class RestContextBuilder { protected void addContextModule(List modules) { modules.add(new AbstractModule() { - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked", "rawtypes" }) @Override protected void configure() { bind( - (TypeLiteral) TypeLiteral.get(Types.newParameterizedType(RestContext.class, syncClientType, - asyncClientType))).to( - TypeLiteral.get(Types.newParameterizedType(RestContextImpl.class, syncClientType, asyncClientType))) - .in(Scopes.SINGLETON); + (TypeLiteral) TypeLiteral.get(newParameterizedType(RestContext.class, syncClientType, + asyncClientType))).to( + TypeLiteral.get(newParameterizedType(RestContextImpl.class, syncClientType, asyncClientType))).in( + SINGLETON); } public String toString() { - return String.format("configure rest context %s->%s", syncClientType.getSimpleName(), - asyncClientType.getSimpleName()); + return String.format("configure rest context %s->%s", syncClientType.getSimpleName(), asyncClientType + .getSimpleName()); } }); @@ -208,7 +226,7 @@ public class RestContextBuilder { } private boolean atLeastOneModuleRequiresHttp(List modules) { - return Iterables.any(modules, new Predicate() { + return any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(RequiresHttp.class); } @@ -223,7 +241,7 @@ public class RestContextBuilder { } private boolean restClientModulePresent(List modules) { - return Iterables.any(modules, new Predicate() { + return any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresRestClient.class); } @@ -237,20 +255,20 @@ public class RestContextBuilder { @VisibleForTesting protected void addExecutorServiceIfNotPresent(List modules) { - if (!Iterables.any(modules, new Predicate() { + if (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresExecutorService.class); } } )) { - if (Iterables.any(modules, new Predicate() { + if (any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(SingleThreaded.class); } })) { modules.add(new ExecutorServiceModule(MoreExecutors.sameThreadExecutor(), MoreExecutors - .sameThreadExecutor())); + .sameThreadExecutor())); } else { modules.add(new ExecutorServiceModule()); } @@ -259,7 +277,7 @@ public class RestContextBuilder { @VisibleForTesting protected void addCredentialStoreIfNotPresent(List modules) { - if (!Iterables.any(modules, new Predicate() { + if (!any(modules, new Predicate() { public boolean apply(Module input) { return input.getClass().isAnnotationPresent(ConfiguresCredentialStore.class); } @@ -278,7 +296,7 @@ public class RestContextBuilder { @SuppressWarnings("unchecked") public > T buildContext() { Injector injector = buildInjector(); - return (T) injector.getInstance(Key.get(Types.newParameterizedType(RestContext.class, syncClientType, - asyncClientType))); + return (T) injector + .getInstance(Key.get(newParameterizedType(RestContext.class, syncClientType, asyncClientType))); } } diff --git a/core/src/main/java/org/jclouds/rest/RestContextFactory.java b/core/src/main/java/org/jclouds/rest/RestContextFactory.java index 727bea5e67..d856420d33 100644 --- a/core/src/main/java/org/jclouds/rest/RestContextFactory.java +++ b/core/src/main/java/org/jclouds/rest/RestContextFactory.java @@ -35,12 +35,14 @@ import javax.annotation.Nullable; import javax.inject.Inject; import org.jclouds.PropertiesBuilder; +import org.jclouds.location.reference.LocationConstants; import org.jclouds.util.Modules2; import org.jclouds.util.Strings2; import com.google.common.base.Charsets; import com.google.common.base.Function; import com.google.common.base.Joiner; +import com.google.common.base.Splitter; import com.google.common.collect.ImmutableSet; import com.google.common.io.Files; import com.google.inject.Module; @@ -70,22 +72,23 @@ import com.google.inject.Module; public class RestContextFactory { public static RestContextSpec contextSpec(String provider, String endpoint, String apiVersion, - String identity, String credential, Class sync, Class async, + String iso3166Codes, String identity, String credential, Class sync, Class async, Class propertiesBuilderClass, Class> contextBuilderClass, Iterable modules) { - return new RestContextSpec(provider, endpoint, apiVersion, identity, credential, sync, async, + return new RestContextSpec(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async, propertiesBuilderClass, contextBuilderClass, modules); } public static RestContextSpec contextSpec(String provider, String endpoint, String apiVersion, - String identity, String credential, Class sync, Class async) { - return new RestContextSpec(provider, endpoint, apiVersion, identity, credential, sync, async); + String iso3166Codes, String identity, String credential, Class sync, Class async) { + return new RestContextSpec(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async); } @SuppressWarnings({ "unchecked", "rawtypes" }) public static RestContextSpec contextSpec(String provider, String endpoint, String apiVersion, - String identity, String credential, Class sync, Class async, Iterable modules) { - return new RestContextSpec(provider, endpoint, apiVersion, identity, credential, sync, async, + String iso3166Codes, String identity, String credential, Class sync, Class async, + Iterable modules) { + return new RestContextSpec(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async, PropertiesBuilder.class, (Class) RestContextBuilder.class, modules); } @@ -239,6 +242,7 @@ public class RestContextFactory { props.setProperty(contextSpec.provider + ".endpoint", contextSpec.endpoint); props.setProperty(contextSpec.provider + ".apiversion", contextSpec.apiVersion); + props.setProperty(contextSpec.provider + "." + LocationConstants.ISO3166_CODES, contextSpec.iso3166Codes); props.setProperty(contextSpec.provider + ".identity", contextSpec.identity); if (contextSpec.credential != null) props.setProperty(contextSpec.provider + ".credential", contextSpec.credential); @@ -283,7 +287,8 @@ public class RestContextFactory { props.putAll(this.properties); props.putAll(_overrides); - String endpoint = props.getProperty(providerName + ".endpoint", null); + String endpoint = props.getProperty(providerName + "." + LocationConstants.ENDPOINT, null); + String iso3166Codes = props.getProperty(providerName + "." + LocationConstants.ISO3166_CODES, null); String apiVersion = props.getProperty(providerName + ".apiversion", null); identity = props.getProperty(providerName + ".identity", props.getProperty("jclouds.identity", identity)); credential = loadCredentialOrDefault(props, providerName + ".credential", @@ -301,13 +306,18 @@ public class RestContextFactory { propertiesBuilderClass = Providers.resolvePropertiesBuilderClass(providerName, props); sync = (Class) (syncClassName != null ? Class.forName(syncClassName) : null); async = (Class) (syncClassName != null ? Class.forName(asyncClassName) : null); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + String.format( + "provider %s not configured or supported. consider one of the following, as the provider name may have changed:%n%s%nIf you are sure that provider name is correct, check that the maven dependency org.jclouds.provider/%s is loaded.", + providerName, Providers.getSupportedProviders(), providerName), e); } catch (Exception e) { propagate(e); assert false : "exception should have propogated " + e; return null; } - RestContextSpec contextSpec = new RestContextSpec(providerName, endpoint, apiVersion, identity, - credential, sync, async, propertiesBuilderClass, contextBuilderClass, modules); + RestContextSpec contextSpec = new RestContextSpec(providerName, endpoint, apiVersion, iso3166Codes, + identity, credential, sync, async, propertiesBuilderClass, contextBuilderClass, modules); return contextSpec; } @@ -316,8 +326,8 @@ public class RestContextFactory { return properties.getProperty(property); else if (properties.containsKey(property + ".resource")) try { - return Strings2.toStringAndClose(RestContextFactory.class.getResourceAsStream(properties.getProperty(property - + ".resource"))); + return Strings2.toStringAndClose(RestContextFactory.class.getResourceAsStream(properties + .getProperty(property + ".resource"))); } catch (IOException e) { throw new RuntimeException("error reading resource: " + properties.getProperty(property + ".resource")); } @@ -355,6 +365,8 @@ public class RestContextFactory { builder.provider(contextSpec.provider); if (contextSpec.apiVersion != null) builder.apiVersion(contextSpec.apiVersion); + if (contextSpec.iso3166Codes != null) + builder.iso3166Codes(Splitter.on('.').split(contextSpec.iso3166Codes)); if (contextSpec.identity != null) builder.credentials(contextSpec.identity, contextSpec.credential); if (contextSpec.endpoint != null) diff --git a/core/src/main/java/org/jclouds/rest/RestContextSpec.java b/core/src/main/java/org/jclouds/rest/RestContextSpec.java index 9304443e8a..ad7361d277 100644 --- a/core/src/main/java/org/jclouds/rest/RestContextSpec.java +++ b/core/src/main/java/org/jclouds/rest/RestContextSpec.java @@ -36,6 +36,7 @@ public class RestContextSpec { protected final String provider; protected final String endpoint; protected final String apiVersion; + protected final String iso3166Codes; protected final String identity; protected final String credential; protected final Class sync; @@ -44,30 +45,31 @@ public class RestContextSpec { protected final Class> contextBuilderClass; protected final Iterable modules; - public RestContextSpec(String provider, String endpoint, String apiVersion, String identity, String credential, - Class sync, Class async, Class propertiesBuilderClass, - Class> contextBuilderClass, Iterable modules) { + public RestContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes, String identity, + String credential, Class sync, Class async, Class propertiesBuilderClass, + Class> contextBuilderClass, Iterable modules) { this.provider = checkNotNull(provider, "provider"); this.endpoint = endpoint; this.apiVersion = apiVersion; this.identity = identity; this.credential = credential; + this.iso3166Codes = iso3166Codes; this.sync = sync; this.async = async; checkArgument(RestContextBuilder.class.isAssignableFrom(contextBuilderClass), contextBuilderClass.getName() - + " is not a subclass of " + RestContextBuilder.class.getName()); + + " is not a subclass of " + RestContextBuilder.class.getName()); checkArgument(PropertiesBuilder.class.isAssignableFrom(propertiesBuilderClass), propertiesBuilderClass.getName() - + " is not a subclass of " + PropertiesBuilder.class.getName()); + + " is not a subclass of " + PropertiesBuilder.class.getName()); this.propertiesBuilderClass = propertiesBuilderClass; this.contextBuilderClass = contextBuilderClass; this.modules = ImmutableList.copyOf(modules); } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public RestContextSpec(String provider, String endpoint, String apiVersion, String identity, String credential, - Class sync, Class async) { - this(provider, endpoint, apiVersion, identity, credential, sync, async, PropertiesBuilder.class, - (Class) RestContextBuilder.class, EMPTY_LIST); + @SuppressWarnings( { "unchecked", "rawtypes" }) + public RestContextSpec(String provider, String endpoint, String apiVersion, String iso3166Codes, String identity, + String credential, Class sync, Class async) { + this(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async, PropertiesBuilder.class, + (Class) RestContextBuilder.class, EMPTY_LIST); } /** @@ -76,8 +78,8 @@ public class RestContextSpec { */ @Override public int hashCode() { - return Objects.hashCode(provider, endpoint, apiVersion, identity, credential, sync, async, - propertiesBuilderClass, contextBuilderClass, modules); + return Objects.hashCode(provider, endpoint, apiVersion, iso3166Codes, identity, credential, sync, async, + propertiesBuilderClass, contextBuilderClass, modules); } /** @@ -97,10 +99,10 @@ public class RestContextSpec { */ @Override public String toString() { - return Objects.toStringHelper(this).add("provider", provider).add("endpoint", endpoint) - .add("apiVersion", apiVersion).add("identity", identity).add("sync", sync).add("async", async) - .add("propertiesBuilderClass", propertiesBuilderClass).add("contextBuilderClass", contextBuilderClass) - .add("modules", modules).toString(); + return Objects.toStringHelper(this).add("provider", provider).add("endpoint", endpoint).add("apiVersion", + apiVersion).add("iso3166Codes", iso3166Codes).add("identity", identity).add("sync", sync).add("async", + async).add("propertiesBuilderClass", propertiesBuilderClass).add("contextBuilderClass", + contextBuilderClass).add("modules", modules).toString(); } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/annotations/MapBinder.java b/core/src/main/java/org/jclouds/rest/annotations/MapBinder.java index ed1dc54de7..0a163de0f1 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/MapBinder.java +++ b/core/src/main/java/org/jclouds/rest/annotations/MapBinder.java @@ -35,7 +35,7 @@ import java.lang.annotation.Target; public @interface MapBinder { /** - * How to bind {@link MapPayloadParam} values, if there is no {@link MapBinder} in the method + * How to bind {@link PayloadParam} values, if there is no {@link MapBinder} in the method * definition */ Class value(); diff --git a/core/src/main/java/org/jclouds/rest/annotations/Payload.java b/core/src/main/java/org/jclouds/rest/annotations/Payload.java new file mode 100644 index 0000000000..5edd78ee5c --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/annotations/Payload.java @@ -0,0 +1,46 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.rest.annotations; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import javax.ws.rs.Path; + +/** + * Designates that this parameter will hold the payload for a PUT or POST command. + * + * @author Adrian Cole + */ +@Target(METHOD) +@Retention(RUNTIME) +public @interface Payload { + + /** + * Note that if you'd like curly braces literally in the payload, urlencode them first. + * + * @see Path#value() + * @see PayloadParam + */ + String value(); +} diff --git a/core/src/main/java/org/jclouds/rest/annotations/MapPayloadParam.java b/core/src/main/java/org/jclouds/rest/annotations/PayloadParam.java similarity index 89% rename from core/src/main/java/org/jclouds/rest/annotations/MapPayloadParam.java rename to core/src/main/java/org/jclouds/rest/annotations/PayloadParam.java index be710aa203..51d7c4ba01 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/MapPayloadParam.java +++ b/core/src/main/java/org/jclouds/rest/annotations/PayloadParam.java @@ -32,10 +32,11 @@ import java.lang.annotation.Target; */ @Target(PARAMETER) @Retention(RUNTIME) -public @interface MapPayloadParam { +public @interface PayloadParam { /** - * The key used in a map passed to the {@link MapBinder} associated with the request. + * The key used in a map passed to the {@link MapBinder} or {@link Payload} associated with the + * request. */ String value(); } diff --git a/core/src/main/java/org/jclouds/rest/annotations/MapPayloadParams.java b/core/src/main/java/org/jclouds/rest/annotations/PayloadParams.java similarity index 95% rename from core/src/main/java/org/jclouds/rest/annotations/MapPayloadParams.java rename to core/src/main/java/org/jclouds/rest/annotations/PayloadParams.java index 244908fbfb..f5019ca8f5 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/MapPayloadParams.java +++ b/core/src/main/java/org/jclouds/rest/annotations/PayloadParams.java @@ -32,11 +32,13 @@ import javax.ws.rs.QueryParam; * Designates that default parameters will be added a map that builds the request entity. * * @see QueryParam + * @see Payload + * @see MapBinder * @author Adrian Cole */ @Target( { TYPE, METHOD }) @Retention(RUNTIME) -public @interface MapPayloadParams { +public @interface PayloadParams { public static final String NULL = "MAP_PAYLOAD_NULL"; diff --git a/core/src/main/java/org/jclouds/rest/annotations/Unwrap.java b/core/src/main/java/org/jclouds/rest/annotations/Unwrap.java index 5866f7048e..04bbd1db7e 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/Unwrap.java +++ b/core/src/main/java/org/jclouds/rest/annotations/Unwrap.java @@ -24,9 +24,10 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; +import java.util.Map; /** - * Unwraps the only value in the json reponse + * Unwraps the only value in a nested json reponse * * ex. { "foo" :"bar" } becomes "bar" * @@ -35,4 +36,36 @@ import java.lang.annotation.Target; @Target(METHOD) @Retention(RUNTIME) public @interface Unwrap { + /** + * level to unwrap. + * + * ex. if default (1) + * + * { "foo" :"bar" } becomes "bar" + * + * ex. if (2) + * + * { "foo" : {"bar" : ["baz"]} } becomes ["baz"] + * + * @return nestingLevel + */ + int depth() default 1; + + /** + * final collection type + * + * ex. if depth(2), edgeCollection(Map.class) + * + * { "foo" : {"bar" : ["baz"]} } becomes ["baz"] + * + * ex. if depth(3), edgeCollection(Set.class) + * + * { "foo" : {"bar" : ["baz"]} } becomes "baz" + * + *

Note

only Map and Set are valid + * + * @return + */ + Class edgeCollection() default Map.class; + } diff --git a/core/src/main/java/org/jclouds/rest/binders/BindAsHostPrefix.java b/core/src/main/java/org/jclouds/rest/binders/BindAsHostPrefix.java index ed3d80c1a8..5886a3a929 100644 --- a/core/src/main/java/org/jclouds/rest/binders/BindAsHostPrefix.java +++ b/core/src/main/java/org/jclouds/rest/binders/BindAsHostPrefix.java @@ -21,7 +21,8 @@ package org.jclouds.rest.binders; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.net.InternetDomainName.isValid; +import static com.google.common.net.InternetDomainName.fromLenient; +import static com.google.common.net.InternetDomainName.isValidLenient; import javax.inject.Inject; import javax.inject.Provider; @@ -51,9 +52,9 @@ public class BindAsHostPrefix implements Binder { @SuppressWarnings("unchecked") public R bindToRequest(R request, Object payload) { checkNotNull(payload, "hostprefix"); - checkArgument(isValid(request.getEndpoint().getHost()), "this is only valid for hostnames: " + request); + checkArgument(isValidLenient(request.getEndpoint().getHost()), "this is only valid for hostnames: " + request); UriBuilder builder = uriBuilderProvider.get().uri(request.getEndpoint()); - InternetDomainName name = InternetDomainName.from(request.getEndpoint().getHost()).child(payload.toString()); + InternetDomainName name = fromLenient(request.getEndpoint().getHost()).child(payload.toString()); builder.host(name.name()); return (R) request.toBuilder().endpoint(builder.build()).build(); } diff --git a/core/src/main/java/org/jclouds/rest/binders/BindMapToStringPayload.java b/core/src/main/java/org/jclouds/rest/binders/BindMapToStringPayload.java new file mode 100644 index 0000000000..445dfa2f9a --- /dev/null +++ b/core/src/main/java/org/jclouds/rest/binders/BindMapToStringPayload.java @@ -0,0 +1,69 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.rest.binders; + +import java.net.URI; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.inject.Singleton; +import javax.ws.rs.core.UriBuilder; + +import org.jclouds.http.HttpRequest; +import org.jclouds.io.Payloads; +import org.jclouds.rest.MapBinder; +import org.jclouds.rest.annotations.Payload; +import org.jclouds.rest.internal.GeneratedHttpRequest; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class BindMapToStringPayload implements MapBinder { + protected final Provider uriBuilders; + + @Inject + public BindMapToStringPayload(Provider uriBuilders) { + this.uriBuilders = uriBuilders; + } + + @SuppressWarnings("unchecked") + @Override + public R bindToRequest(R request, Map postParams) { + GeneratedHttpRequest r = GeneratedHttpRequest.class.cast(request); + String payload = r.getJavaMethod().getAnnotation(Payload.class).value(); + if (postParams.size() > 0) { + UriBuilder builder = uriBuilders.get(); + builder.uri(URI.create("http://test/")); + builder.path(payload); + URI fake = builder.buildFromMap(postParams); + payload = fake.getPath().substring(1); + } + return (R) request.toBuilder().payload(Payloads.newStringPayload(payload)).build(); + } + + @Override + public R bindToRequest(R request, Object payload) { + throw new IllegalArgumentException("this is a map binder"); + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/rest/binders/BindToJsonPayload.java b/core/src/main/java/org/jclouds/rest/binders/BindToJsonPayload.java index 0da9af87bc..4f74471fa8 100644 --- a/core/src/main/java/org/jclouds/rest/binders/BindToJsonPayload.java +++ b/core/src/main/java/org/jclouds/rest/binders/BindToJsonPayload.java @@ -34,7 +34,6 @@ import org.jclouds.rest.MapBinder; * Binds the object to the request as a json object. * * @author Adrian Cole - * @since 4.0 */ public class BindToJsonPayload implements MapBinder { diff --git a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java index bac8df9e23..99510d75dd 100755 --- a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java @@ -52,9 +52,9 @@ import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.SortedSet; -import java.util.Map.Entry; import javax.annotation.Nullable; import javax.annotation.Resource; @@ -81,13 +81,15 @@ import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpUtils; import org.jclouds.http.functions.ParseJson; import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseSax.HandlerWithResult; import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x; import org.jclouds.http.functions.ReleasePayloadAndReturn; import org.jclouds.http.functions.ReturnInputStream; import org.jclouds.http.functions.ReturnStringIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.UnwrapOnlyJsonValue; -import org.jclouds.http.functions.ParseSax.HandlerWithResult; +import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue; +import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet; import org.jclouds.http.options.HttpRequestOptions; import org.jclouds.http.utils.ModifyRequest; import org.jclouds.internal.ClassMethodArgs; @@ -110,12 +112,12 @@ import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.Headers; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; -import org.jclouds.rest.annotations.MapPayloadParams; import org.jclouds.rest.annotations.MatrixParams; import org.jclouds.rest.annotations.OverrideRequestFilters; import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.PartParam; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.PayloadParams; import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; @@ -123,6 +125,7 @@ import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.annotations.Unwrap; import org.jclouds.rest.annotations.VirtualHost; import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.binders.BindMapToStringPayload; import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.util.Strings2; @@ -166,13 +169,13 @@ public class RestAnnotationProcessor { static final Map>> methodToIndexOfParamToFormParamAnnotations = createMethodToIndexOfParamToAnnotation(FormParam.class); static final Map>> methodToIndexOfParamToQueryParamAnnotations = createMethodToIndexOfParamToAnnotation(QueryParam.class); static final Map>> methodToIndexOfParamToPathParamAnnotations = createMethodToIndexOfParamToAnnotation(PathParam.class); - static final Map>> methodToIndexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(MapPayloadParam.class); + static final Map>> methodToIndexOfParamToPostParamAnnotations = createMethodToIndexOfParamToAnnotation(PayloadParam.class); static final Map>> methodToIndexOfParamToPartParamAnnotations = createMethodToIndexOfParamToAnnotation(PartParam.class); static final Map>> methodToIndexOfParamToParamParserAnnotations = createMethodToIndexOfParamToAnnotation(ParamParser.class); static final Map delegationMap = newHashMap(); static Map>> createMethodToIndexOfParamToAnnotation( - final Class annotation) { + final Class annotation) { return new MapMaker().makeComputingMap(new Function>>() { public Map> apply(final Method method) { return new MapMaker().makeComputingMap(new GetAnnotationsForMethodParameterIndex(method, annotation)); @@ -206,7 +209,7 @@ public class RestAnnotationProcessor { } private static final Class optionsVarArgsClass = new HttpRequestOptions[] {} - .getClass(); + .getClass(); private static final Function, ? extends Part> ENTRY_TO_PART = new Function, Part>() { @@ -218,17 +221,17 @@ public class RestAnnotationProcessor { }; private final Map> methodToIndexesOfOptions = new MapMaker() - .makeComputingMap(new Function>() { - public Set apply(final Method method) { - Set toReturn = newHashSet(); - for (int index = 0; index < method.getParameterTypes().length; index++) { - Class type = method.getParameterTypes()[index]; - if (HttpRequestOptions.class.isAssignableFrom(type) || optionsVarArgsClass.isAssignableFrom(type)) - toReturn.add(index); - } - return toReturn; + .makeComputingMap(new Function>() { + public Set apply(final Method method) { + Set toReturn = newHashSet(); + for (int index = 0; index < method.getParameterTypes().length; index++) { + Class type = method.getParameterTypes()[index]; + if (HttpRequestOptions.class.isAssignableFrom(type) || optionsVarArgsClass.isAssignableFrom(type)) + toReturn.add(index); } - }); + return toReturn; + } + }); private final ParseSax.Factory parserFactory; private final HttpUtils utils; @@ -247,7 +250,7 @@ public class RestAnnotationProcessor { @VisibleForTesting public static Function createResponseParser(ParseSax.Factory parserFactory, Injector injector, - Method method, HttpRequest request) { + Method method, HttpRequest request) { Function transformer; Class> handler = getSaxResponseParserClassOrNull(method); if (handler != null) { @@ -268,7 +271,7 @@ public class RestAnnotationProcessor { @VisibleForTesting public static Function createExceptionParserOrThrowResourceNotFoundOn404IfNoAnnotation( - Injector injector, Method method) { + Injector injector, Method method) { ExceptionParser annotation = method.getAnnotation(ExceptionParser.class); if (annotation != null) { return injector.getInstance(annotation.value()); @@ -279,7 +282,7 @@ public class RestAnnotationProcessor { @SuppressWarnings("unchecked") @Inject public RestAnnotationProcessor(Injector injector, ParseSax.Factory parserFactory, HttpUtils utils, - TypeLiteral typeLiteral) { + TypeLiteral typeLiteral) { this.declaring = (Class) typeLiteral.getRawType(); this.injector = injector; this.parserFactory = parserFactory; @@ -395,7 +398,7 @@ public class RestAnnotationProcessor { public GeneratedHttpRequest createRequest(Method method, Object... args) { inputParamValidator.validateMethodParametersOrThrow(method, args); ClassMethodArgs cma = logger.isTraceEnabled() ? new ClassMethodArgs(method.getDeclaringClass(), method, args) - : null; + : null; URI endpoint = callerEndpoint; try { @@ -509,8 +512,8 @@ public class RestAnnotationProcessor { org.jclouds.rest.MapBinder mapBinder = getMapPayloadBinderOrNull(method, args); if (mapBinder != null) { Map mapParams = buildPostParams(method, args); - if (method.isAnnotationPresent(MapPayloadParams.class)) { - MapPayloadParams params = method.getAnnotation(MapPayloadParams.class); + if (method.isAnnotationPresent(PayloadParams.class)) { + PayloadParams params = method.getAnnotation(PayloadParams.class); addMapPayload(mapParams, params, headers.entries()); } request = mapBinder.bindToRequest(request, mapParams); @@ -551,14 +554,14 @@ public class RestAnnotationProcessor { } public static URI replaceQuery(Provider uriBuilderProvider, URI in, String newQuery, - @Nullable Comparator> sorter, char... skips) { + @Nullable Comparator> sorter, char... skips) { UriBuilder builder = uriBuilderProvider.get().uri(in); builder.replaceQuery(ModifyRequest.makeQueryLine(ModifyRequest.parseQueryToMap(newQuery), sorter, skips)); return builder.build(); } private Multimap addMatrixParams(Collection> tokenValues, Method method, - Object... args) { + Object... args) { Multimap matrixMap = LinkedListMultimap.create(); if (declaring.isAnnotationPresent(MatrixParams.class)) { MatrixParams matrix = declaring.getAnnotation(MatrixParams.class); @@ -577,7 +580,7 @@ public class RestAnnotationProcessor { } private Multimap addFormParams(Collection> tokenValues, Method method, - Object... args) { + Object... args) { Multimap formMap = LinkedListMultimap.create(); if (declaring.isAnnotationPresent(FormParams.class)) { FormParams form = declaring.getAnnotation(FormParams.class); @@ -596,7 +599,7 @@ public class RestAnnotationProcessor { } private Multimap addQueryParams(Collection> tokenValues, Method method, - Object... args) { + Object... args) { Multimap queryMap = LinkedListMultimap.create(); if (declaring.isAnnotationPresent(QueryParams.class)) { QueryParams query = declaring.getAnnotation(QueryParams.class); @@ -615,7 +618,7 @@ public class RestAnnotationProcessor { } private void addForm(Multimap formParams, FormParams form, - Collection> tokenValues) { + Collection> tokenValues) { for (int i = 0; i < form.keys().length; i++) { if (form.values()[i].equals(FormParams.NULL)) { formParams.removeAll(form.keys()[i]); @@ -627,7 +630,7 @@ public class RestAnnotationProcessor { } private void addQuery(Multimap queryParams, QueryParams query, - Collection> tokenValues) { + Collection> tokenValues) { for (int i = 0; i < query.keys().length; i++) { if (query.values()[i].equals(QueryParams.NULL)) { queryParams.removeAll(query.keys()[i]); @@ -639,7 +642,7 @@ public class RestAnnotationProcessor { } private void addMatrix(Multimap matrixParams, MatrixParams matrix, - Collection> tokenValues) { + Collection> tokenValues) { for (int i = 0; i < matrix.keys().length; i++) { if (matrix.values()[i].equals(MatrixParams.NULL)) { matrixParams.removeAll(matrix.keys()[i]); @@ -650,10 +653,10 @@ public class RestAnnotationProcessor { } } - private void addMapPayload(Map postParams, MapPayloadParams mapDefaults, - Collection> tokenValues) { + private void addMapPayload(Map postParams, PayloadParams mapDefaults, + Collection> tokenValues) { for (int i = 0; i < mapDefaults.keys().length; i++) { - if (mapDefaults.values()[i].equals(MapPayloadParams.NULL)) { + if (mapDefaults.values()[i].equals(PayloadParams.NULL)) { postParams.put(mapDefaults.keys()[i], null); } else { postParams.put(mapDefaults.keys()[i], Strings2.replaceTokens(mapDefaults.values()[i], tokenValues)); @@ -686,7 +689,7 @@ public class RestAnnotationProcessor { @VisibleForTesting public static URI getEndpointInParametersOrNull(Method method, final Object[] args, Injector injector) { Map> map = indexWithAtLeastOneAnnotation(method, - methodToIndexOfParamToEndpointParamAnnotations); + methodToIndexOfParamToEndpointParamAnnotations); if (map.size() >= 1 && args.length > 0) { EndpointParam firstAnnotation = (EndpointParam) get(get(map.values(), 0), 0); Function parser = injector.getInstance(firstAnnotation.parser()); @@ -695,8 +698,8 @@ public class RestAnnotationProcessor { int index = map.keySet().iterator().next(); try { URI returnVal = parser.apply(args[index]); - checkArgument(returnVal != null, String.format("endpoint for [%s] not configured for %s", args[index], - method)); + checkArgument(returnVal != null, + String.format("endpoint for [%s] not configured for %s", args[index], method)); return returnVal; } catch (NullPointerException e) { throw new IllegalArgumentException(String.format("argument at index %d on method %s", index, method), e); @@ -713,12 +716,12 @@ public class RestAnnotationProcessor { }); try { URI returnVal = parser.apply(argsToParse); - checkArgument(returnVal != null, String.format("endpoint for [%s] not configured for %s", argsToParse, - method)); + checkArgument(returnVal != null, + String.format("endpoint for [%s] not configured for %s", argsToParse, method)); return returnVal; } catch (NullPointerException e) { throw new IllegalArgumentException(String.format("argument at indexes %s on method %s", map.keySet(), - method), e); + method), e); } } } @@ -754,21 +757,21 @@ public class RestAnnotationProcessor { public static final TypeLiteral> futureHttpResponseLiteral = new TypeLiteral>() { }; - @SuppressWarnings( { "unchecked", "rawtypes" }) + @SuppressWarnings({ "unchecked", "rawtypes" }) public static Key> getParserOrThrowException(Method method) { ResponseParser annotation = method.getAnnotation(ResponseParser.class); if (annotation == null) { if (method.getReturnType().equals(void.class) - || TypeLiteral.get(method.getGenericReturnType()).equals(futureVoidLiteral)) { + || TypeLiteral.get(method.getGenericReturnType()).equals(futureVoidLiteral)) { return Key.get(ReleasePayloadAndReturn.class); } else if (method.getReturnType().equals(boolean.class) || method.getReturnType().equals(Boolean.class) - || TypeLiteral.get(method.getGenericReturnType()).equals(futureBooleanLiteral)) { + || TypeLiteral.get(method.getGenericReturnType()).equals(futureBooleanLiteral)) { return Key.get(ReturnTrueIf2xx.class); } else if (method.getReturnType().equals(InputStream.class) - || TypeLiteral.get(method.getGenericReturnType()).equals(futureInputStreamLiteral)) { + || TypeLiteral.get(method.getGenericReturnType()).equals(futureInputStreamLiteral)) { return Key.get(ReturnInputStream.class); } else if (method.getReturnType().equals(HttpResponse.class) - || TypeLiteral.get(method.getGenericReturnType()).equals(futureHttpResponseLiteral)) { + || TypeLiteral.get(method.getGenericReturnType()).equals(futureHttpResponseLiteral)) { return Key.get((Class) IdentityFunction.class); } else if (getAcceptHeadersOrNull(method).contains(MediaType.APPLICATION_JSON)) { Type returnVal; @@ -783,16 +786,27 @@ public class RestAnnotationProcessor { returnVal = method.getGenericReturnType(); } ParameterizedType parserType; - if (method.isAnnotationPresent(Unwrap.class)) - parserType = Types.newParameterizedType(UnwrapOnlyJsonValue.class, returnVal); - else + if (method.isAnnotationPresent(Unwrap.class)) { + int depth = method.getAnnotation(Unwrap.class).depth(); + Class edgeCollection = method.getAnnotation(Unwrap.class).edgeCollection(); + if (depth == 1 && edgeCollection == Map.class) + parserType = Types.newParameterizedType(UnwrapOnlyJsonValue.class, returnVal); + else if (depth == 2 && edgeCollection == Map.class) + parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, returnVal); + else if (depth == 3 && edgeCollection == Set.class) + parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValueInSet.class, returnVal); + else + throw new IllegalStateException(String.format( + "depth(%d) edgeCollection(%s) not yet supported for @Unwrap", depth, edgeCollection)); + } else { parserType = Types.newParameterizedType(ParseJson.class, returnVal); + } return (Key>) Key.get(parserType); } else if (method.getReturnType().equals(String.class) - || TypeLiteral.get(method.getGenericReturnType()).equals(futureStringLiteral)) { + || TypeLiteral.get(method.getGenericReturnType()).equals(futureStringLiteral)) { return Key.get(ReturnStringIf2xx.class); } else if (method.getReturnType().equals(URI.class) - || TypeLiteral.get(method.getGenericReturnType()).equals(futureURILiteral)) { + || TypeLiteral.get(method.getGenericReturnType()).equals(futureURILiteral)) { return Key.get(ParseURIFromListOrLocationHeaderIf20x.class); } else { throw new IllegalStateException("You must specify a ResponseParser annotation on: " + method.toString()); @@ -824,7 +838,7 @@ public class RestAnnotationProcessor { } else { if (postBinders[0] instanceof org.jclouds.rest.MapBinder) { throw new IllegalArgumentException("we currently do not support multiple varargs postBinders in: " - + method.getName()); + + method.getName()); } } } else if (arg instanceof org.jclouds.rest.MapBinder) { @@ -834,9 +848,10 @@ public class RestAnnotationProcessor { } } } - MapBinder annotation = method.getAnnotation(MapBinder.class); - if (annotation != null) { - return injector.getInstance(annotation.value()); + if (method.isAnnotationPresent(MapBinder.class)) { + return injector.getInstance(method.getAnnotation(MapBinder.class).value()); + } else if (method.isAnnotationPresent(org.jclouds.rest.annotations.Payload.class)) { + return injector.getInstance(BindMapToStringPayload.class); } return null; } @@ -845,7 +860,7 @@ public class RestAnnotationProcessor { public boolean isHttpMethod(Method method) { return method.isAnnotationPresent(Path.class) || getHttpMethods(method) != null - || Sets.newHashSet(method.getParameterTypes()).contains(HttpRequest.class); + || Sets.newHashSet(method.getParameterTypes()).contains(HttpRequest.class); } public boolean isConstantDeclaration(Method method) { @@ -874,8 +889,8 @@ public class RestAnnotationProcessor { Set requests = getHttpMethods(method); if (requests == null || requests.size() != 1) { throw new IllegalStateException( - "You must use at least one, but no more than one http method or pathparam annotation on: " - + method.toString()); + "You must use at least one, but no more than one http method or pathparam annotation on: " + + method.toString()); } return requests.iterator().next(); } @@ -889,12 +904,12 @@ public class RestAnnotationProcessor { public GeneratedHttpRequest decorateRequest(GeneratedHttpRequest request) { OUTER: for (Entry> entry : filterValues( - methodToIndexOfParamToDecoratorParamAnnotation.get(request.getJavaMethod()), - new Predicate>() { - public boolean apply(Set input) { - return input.size() >= 1; - } - }).entrySet()) { + methodToIndexOfParamToDecoratorParamAnnotation.get(request.getJavaMethod()), + new Predicate>() { + public boolean apply(Set input) { + return input.size() >= 1; + } + }).entrySet()) { boolean shouldBreak = false; BinderParam payloadAnnotation = (BinderParam) entry.getValue().iterator().next(); Binder binder = injector.getInstance(payloadAnnotation.value()); @@ -930,24 +945,24 @@ public class RestAnnotationProcessor { } public static Map> indexWithOnlyOneAnnotation(Method method, String description, - Map>> toRefine) { + Map>> toRefine) { Map> indexToPayloadAnnotation = indexWithAtLeastOneAnnotation(method, toRefine); if (indexToPayloadAnnotation.size() > 1) { throw new IllegalStateException(String.format( - "You must not specify more than one %s annotation on: %s; found %s", description, method.toString(), - indexToPayloadAnnotation)); + "You must not specify more than one %s annotation on: %s; found %s", description, method.toString(), + indexToPayloadAnnotation)); } return indexToPayloadAnnotation; } private static Map> indexWithAtLeastOneAnnotation(Method method, - Map>> toRefine) { + Map>> toRefine) { Map> indexToPayloadAnnotation = filterValues(toRefine.get(method), - new Predicate>() { - public boolean apply(Set input) { - return input.size() == 1; - } - }); + new Predicate>() { + public boolean apply(Set input) { + return input.size() == 1; + } + }); return indexToPayloadAnnotation; } @@ -966,7 +981,7 @@ public class RestAnnotationProcessor { } else { if (options[0] instanceof HttpRequestOptions) { throw new IllegalArgumentException("we currently do not support multiple varargs options in: " - + method.getName()); + + method.getName()); } } } else { @@ -978,7 +993,7 @@ public class RestAnnotationProcessor { } public Multimap buildHeaders(Collection> tokenValues, Method method, - final Object... args) { + final Object... args) { Multimap headers = LinkedHashMultimap.create(); addHeaderIfAnnotationPresentOnMethod(headers, method, tokenValues); Map> indexToHeaderParam = methodToIndexOfParamToHeaderParamAnnotations.get(method); @@ -1025,7 +1040,7 @@ public class RestAnnotationProcessor { } public void addHeaderIfAnnotationPresentOnMethod(Multimap headers, Method method, - Collection> tokenValues) { + Collection> tokenValues) { if (declaring.isAnnotationPresent(Headers.class)) { Headers header = declaring.getAnnotation(Headers.class); addHeader(headers, header, tokenValues); @@ -1037,7 +1052,7 @@ public class RestAnnotationProcessor { } private void addHeader(Multimap headers, Headers header, - Collection> tokenValues) { + Collection> tokenValues) { for (int i = 0; i < header.keys().length; i++) { String value = header.values()[i]; value = Strings2.replaceTokens(value, tokenValues); @@ -1227,7 +1242,7 @@ public class RestAnnotationProcessor { for (Entry> entry : indexToPathParam.entrySet()) { for (Annotation key : entry.getValue()) { Set extractors = indexToParamExtractor.get(entry.getKey()); - String paramKey = ((MapPayloadParam) key).value(); + String paramKey = ((PayloadParam) key).value(); String paramValue; if (extractors != null && extractors.size() > 0) { ParamParser extractor = (ParamParser) extractors.iterator().next(); diff --git a/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java b/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java index 17f3d5c380..d51e4f5db1 100644 --- a/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestContextImpl.java @@ -22,12 +22,16 @@ package org.jclouds.rest.internal; import java.io.IOException; import java.net.URI; import java.util.Map; +import java.util.Set; import javax.annotation.Resource; import javax.inject.Inject; import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationScope; import org.jclouds.lifecycle.Closer; +import org.jclouds.location.Iso3166; import org.jclouds.location.Provider; import org.jclouds.logging.Logger; import org.jclouds.rest.RestContext; @@ -35,6 +39,7 @@ import org.jclouds.rest.Utils; import org.jclouds.rest.annotations.ApiVersion; import org.jclouds.rest.annotations.Identity; +import com.google.common.collect.ImmutableMap; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Singleton; @@ -57,11 +62,12 @@ public class RestContextImpl implements RestContext { private final String apiVersion; private final Utils utils; private final Map credentialStore; + private final Set iso3166Codes; @Inject protected RestContextImpl(Closer closer, Map credentialStore, Utils utils, Injector injector, - TypeLiteral syncApi, TypeLiteral asyncApi, @Provider URI endpoint, @Provider String provider, - @Identity String identity, @ApiVersion String apiVersion) { + TypeLiteral syncApi, TypeLiteral asyncApi, @Provider URI endpoint, @Provider String provider, + @Identity String identity, @ApiVersion String apiVersion, @Iso3166 Set iso3166Codes) { this.credentialStore = credentialStore; this.utils = utils; this.asyncApi = injector.getInstance(Key.get(asyncApi)); @@ -71,6 +77,7 @@ public class RestContextImpl implements RestContext { this.identity = identity; this.provider = provider; this.apiVersion = apiVersion; + this.iso3166Codes = iso3166Codes; } /** @@ -122,11 +129,6 @@ public class RestContextImpl implements RestContext { return apiVersion; } - @Override - public String getProvider() { - return provider; - } - @Override public int hashCode() { final int prime = 31; @@ -172,8 +174,8 @@ public class RestContextImpl implements RestContext { @Override public String toString() { - return " [provider=" + provider + ", endpoint=" + endpoint + ", apiVersion=" + apiVersion + ", identity=" - + identity + "]"; + return " [id=" + provider + ", endpoint=" + endpoint + ", apiVersion=" + apiVersion + ", identity=" + identity + + ", iso3166Codes=" + iso3166Codes + "]"; } @Override @@ -185,4 +187,34 @@ public class RestContextImpl implements RestContext { public Map credentialStore() { return credentialStore; } + + @Override + public String getDescription() { + return null; + } + + @Override + public String getId() { + return provider; + } + + @Override + public Set getIso3166Codes() { + return iso3166Codes; + } + + @Override + public Map getMetadata() { + return ImmutableMap. of("endpoint", endpoint, "apiVersion", apiVersion, "identity", identity); + } + + @Override + public Location getParent() { + return null; + } + + @Override + public LocationScope getScope() { + return LocationScope.PROVIDER; + } } diff --git a/core/src/main/java/org/jclouds/util/Throwables2.java b/core/src/main/java/org/jclouds/util/Throwables2.java index d9cc364bb2..1327234c46 100644 --- a/core/src/main/java/org/jclouds/util/Throwables2.java +++ b/core/src/main/java/org/jclouds/util/Throwables2.java @@ -28,13 +28,13 @@ import java.util.NoSuchElementException; import org.jclouds.http.HttpResponseException; import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.InsufficientResourcesException; import org.jclouds.rest.ResourceNotFoundException; import com.google.common.base.Throwables; import com.google.inject.ProvisionException; import com.google.inject.spi.Message; - /** * General utilities used in jclouds code. * @@ -72,9 +72,9 @@ public class Throwables2 { } // Note this needs to be kept up-to-date with all top-level exceptions jclouds works against - @SuppressWarnings({ "unchecked", "rawtypes" }) + @SuppressWarnings( { "unchecked", "rawtypes" }) public static Exception returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(Class[] exceptionTypes, - Exception exception) throws Exception { + Exception exception) throws Exception { for (Class type : exceptionTypes) { Throwable throwable = getFirstThrowableOfType(exception, type); if (throwable != null) { @@ -82,8 +82,8 @@ public class Throwables2 { } } for (Class propagatableExceptionType : new Class[] { IllegalStateException.class, - UnsupportedOperationException.class, IllegalArgumentException.class, AuthorizationException.class, - ResourceNotFoundException.class, HttpResponseException.class }) { + UnsupportedOperationException.class, IllegalArgumentException.class, AuthorizationException.class, + ResourceNotFoundException.class, InsufficientResourcesException.class, HttpResponseException.class }) { Throwable throwable = getFirstThrowableOfType(exception, propagatableExceptionType); if (throwable != null) { throw (Exception) throwable; @@ -101,7 +101,5 @@ public class Throwables2 { assert false : "exception should have propogated " + e; return null; } - - } diff --git a/core/src/main/resources/rest.properties b/core/src/main/resources/rest.properties index 78c11b841f..54817aa747 100644 --- a/core/src/main/resources/rest.properties +++ b/core/src/main/resources/rest.properties @@ -35,33 +35,18 @@ pcs.apiVersion=unknown sdn.contextbuilder=org.jclouds.nirvanix.sdn.SDNContextBuilder sdn.propertiesbuilder=org.jclouds.nirvanix.sdn.SDNPropertiesBuilder -sqs.contextbuilder=org.jclouds.sqs.SQSContextBuilder -sqs.propertiesbuilder=org.jclouds.sqs.SQSPropertiesBuilder - -simpledb.contextbuilder=org.jclouds.simpledb.SimpleDBContextBuilder -simpledb.propertiesbuilder=org.jclouds.simpledb.SimpleDBPropertiesBuilder - aws-simpledb.contextbuilder=org.jclouds.simpledb.SimpleDBContextBuilder aws-simpledb.propertiesbuilder=org.jclouds.aws.simpledb.SimpleDBPropertiesBuilder -elb.contextbuilder=org.jclouds.elb.ELBContextBuilder -elb.propertiesbuilder=org.jclouds.elb.ELBPropertiesBuilder - aws-elb.contextbuilder=org.jclouds.elb.ELBContextBuilder -aws-elb.propertiesbuilder=org.jclouds.aws.elb.ELBPropertiesBuilder +aws-elb.propertiesbuilder=org.jclouds.aws.elb.AWSELBPropertiesBuilder cloudwatch.contextbuilder=org.jclouds.cloudwatch.CloudWatchContextBuilder cloudwatch.propertiesbuilder=org.jclouds.cloudwatch.CloudWatchPropertiesBuilder -s3.contextbuilder=org.jclouds.s3.S3ContextBuilder -s3.propertiesbuilder=org.jclouds.s3.S3PropertiesBuilder - aws-s3.contextbuilder=org.jclouds.s3.S3ContextBuilder aws-s3.propertiesbuilder=org.jclouds.aws.s3.AWSS3PropertiesBuilder -ec2.contextbuilder=org.jclouds.ec2.EC2ContextBuilder -ec2.propertiesbuilder=org.jclouds.ec2.EC2PropertiesBuilder - aws-ec2.contextbuilder=org.jclouds.aws.ec2.AWSEC2ContextBuilder aws-ec2.propertiesbuilder=org.jclouds.aws.ec2.AWSEC2PropertiesBuilder @@ -89,9 +74,6 @@ opscodeplatform.propertiesbuilder=org.jclouds.opscodeplatform.OpscodePlatformPro vcloud.contextbuilder=org.jclouds.vcloud.VCloudContextBuilder vcloud.propertiesbuilder=org.jclouds.vcloud.VCloudPropertiesBuilder -vcloudexpress.contextbuilder=org.jclouds.vcloud.VCloudExpressContextBuilder -vcloudexpress.propertiesbuilder=org.jclouds.vcloud.VCloudExpressPropertiesBuilder - eucalyptus.contextbuilder=org.jclouds.ec2.EC2ContextBuilder eucalyptus.propertiesbuilder=org.jclouds.eucalyptus.EucalyptusPropertiesBuilder @@ -101,8 +83,6 @@ eucalyptus-partnercloud-ec2.propertiesbuilder=org.jclouds.epc.EucalyptusPartnerC nova-ec2.contextbuilder=org.jclouds.ec2.EC2ContextBuilder nova-ec2.propertiesbuilder=org.jclouds.nova.ec2.NovaEC2PropertiesBuilder -cloudservers.contextbuilder=org.jclouds.cloudservers.CloudServersContextBuilder - cloudservers-uk.contextbuilder=org.jclouds.cloudservers.CloudServersContextBuilder cloudservers-uk.propertiesbuilder=org.jclouds.rackspace.cloudservers.CloudServersUKPropertiesBuilder @@ -165,8 +145,8 @@ cloudonestorage.propertiesbuilder=org.jclouds.cloudonestorage.CloudOneStoragePro swift.contextbuilder=org.jclouds.openstack.swift.SwiftContextBuilder swift.propertiesbuilder=org.jclouds.openstack.swift.SwiftPropertiesBuilder -cloudfiles.contextbuilder=org.jclouds.cloudfiles.CloudFilesContextBuilder -cloudfiles.propertiesbuilder=org.jclouds.cloudfiles.CloudFilesPropertiesBuilder +cloudstack.contextbuilder=org.jclouds.cloudstack.CloudStackContextBuilder +cloudstack.propertiesbuilder=org.jclouds.cloudstack.CloudStackPropertiesBuilder cloudfiles-us.contextbuilder=org.jclouds.cloudfiles.CloudFilesContextBuilder cloudfiles-us.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesUSPropertiesBuilder @@ -174,13 +154,13 @@ cloudfiles-us.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesUSPro cloudfiles-uk.contextbuilder=org.jclouds.cloudfiles.CloudFilesContextBuilder cloudfiles-uk.propertiesbuilder=org.jclouds.rackspace.cloudfiles.CloudFilesUKPropertiesBuilder -walrus.contextbuilder=org.jclouds.s3.S3ContextBuilder +walrus.contextbuilder=org.jclouds.walrus.WalrusContextBuilder walrus.propertiesbuilder=org.jclouds.walrus.WalrusPropertiesBuilder -eucalyptus-partnercloud-s3.contextbuilder=org.jclouds.s3.S3ContextBuilder +eucalyptus-partnercloud-s3.contextbuilder=org.jclouds.walrus.WalrusContextBuilder eucalyptus-partnercloud-s3.propertiesbuilder=org.jclouds.epc.EucalyptusPartnerCloudWalrusPropertiesBuilder -googlestorage.contextbuilder=org.jclouds.s3.S3ContextBuilder +googlestorage.contextbuilder=org.jclouds.googlestorage.GoogleStorageContextBuilder googlestorage.propertiesbuilder=org.jclouds.googlestorage.GoogleStoragePropertiesBuilder scaleup-storage.contextbuilder=org.jclouds.scaleup.storage.ScaleUpStorageContextBuilder diff --git a/core/src/test/java/org/jclouds/http/BaseJettyTest.java b/core/src/test/java/org/jclouds/http/BaseJettyTest.java index 1b7079db08..e5d7eaee08 100644 --- a/core/src/test/java/org/jclouds/http/BaseJettyTest.java +++ b/core/src/test/java/org/jclouds/http/BaseJettyTest.java @@ -266,7 +266,7 @@ public abstract class BaseJettyTest { properties.setProperty(Constants.PROPERTY_TRUST_ALL_CERTS, "true"); properties.setProperty(Constants.PROPERTY_RELAX_HOSTNAME, "true"); RestContextSpec contextSpec = contextSpec("test", - "http://localhost:" + testPort, "1", "identity", null, IntegrationTestClient.class, + "http://localhost:" + testPort, "1", "", "identity", null, IntegrationTestClient.class, IntegrationTestAsyncClient.class, ImmutableSet. copyOf(connectionModules)); return createContextBuilder(contextSpec, properties); } diff --git a/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java b/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java index c80477f8d8..91c8cbda9b 100644 --- a/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java +++ b/core/src/test/java/org/jclouds/http/IntegrationTestAsyncClient.java @@ -42,7 +42,7 @@ import org.jclouds.io.Payload; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; import org.jclouds.rest.annotations.XMLResponseParser; @@ -143,7 +143,7 @@ public interface IntegrationTestAsyncClient { @POST @Path("/objects/{id}") @MapBinder(BindToJsonPayload.class) - ListenableFuture postJson(@PathParam("id") String id, @MapPayloadParam("key") String toPut); + ListenableFuture postJson(@PathParam("id") String id, @PayloadParam("key") String toPut); @POST @Path("/objects/{id}/action/{action}") diff --git a/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java b/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java index 93af2dc92a..6120858a8f 100644 --- a/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java +++ b/core/src/test/java/org/jclouds/rest/InputParamValidatorTest.java @@ -51,12 +51,12 @@ public class InputParamValidatorTest { @SkipEncoding('/') class InputParamValidatorForm { @POST - @ParamValidators( { AllLowerCaseValidator.class }) + @ParamValidators( { AllLowerCaseValidator.class }) public void allParamsValidated(@PathParam("param1") String param1, @PathParam("param2") String param2) { } @POST - public void oneParamValidated(@PathParam("param1") String param1, + public void oneParamValidated(@PathParam("param1") String param1, @ParamValidators( { AllLowerCaseValidator.class }) @PathParam("param2") String param2) { } } @@ -142,7 +142,7 @@ public class InputParamValidatorTest { void setupFactory() { RestContextSpec contextSpec = contextSpec("test", - "http://localhost:9999", "1", "userFoo", null, IntegrationTestClient.class, + "http://localhost:9999", "1", "", "userFoo", null, IntegrationTestClient.class, IntegrationTestAsyncClient.class); injector = createContextBuilder(contextSpec).buildInjector(); diff --git a/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java b/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java index 292377bcb4..4d92265264 100644 --- a/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java +++ b/core/src/test/java/org/jclouds/rest/RestContextFactoryTest.java @@ -54,19 +54,22 @@ public class RestContextFactoryTest { public void testBuilder() { RestContextSpec contextSpec = contextSpec(provider, - "http://localhost", "1", "dummy", null, IntegrationTestClient.class, IntegrationTestAsyncClient.class); + "http://localhost", "1", "", "dummy", null, IntegrationTestClient.class, + IntegrationTestAsyncClient.class); createContextBuilder(contextSpec); } - public void testBuilderProperties() { + public void testBuilderPropertiesWithIso3166() { RestContextSpec contextSpec = contextSpec(provider, - "http://localhost", "1", "dummy", null, IntegrationTestClient.class, IntegrationTestAsyncClient.class); + "http://localhost", "1", "US-CA", "dummy", null, IntegrationTestClient.class, + IntegrationTestAsyncClient.class); Properties props = RestContextFactory.toProperties(contextSpec); assertEquals(props.getProperty("test.endpoint"), "http://localhost"); assertEquals(props.getProperty("test.apiversion"), "1"); assertEquals(props.getProperty("test.identity"), "dummy"); + assertEquals(props.getProperty("test.iso3166-codes"), "US-CA"); assertEquals(props.getProperty("test.credential"), null); assertEquals(props.getProperty("test.sync"), IntegrationTestClient.class.getName()); assertEquals(props.getProperty("test.async"), IntegrationTestAsyncClient.class.getName()); @@ -79,8 +82,8 @@ public class RestContextFactoryTest { public void testBuilderPropertiesWithCredential() { RestContextSpec contextSpec = contextSpec(provider, - "http://localhost", "1", "dummy", "credential", IntegrationTestClient.class, - IntegrationTestAsyncClient.class); + "http://localhost", "1", "", "dummy", "credential", IntegrationTestClient.class, + IntegrationTestAsyncClient.class); Properties props = RestContextFactory.toProperties(contextSpec); assertEquals(props.getProperty("test.endpoint"), "http://localhost"); @@ -100,8 +103,8 @@ public class RestContextFactoryTest { public void testBuilderPropertiesWithContextBuilder() { @SuppressWarnings("rawtypes") RestContextSpec contextSpec = contextSpec(provider, - "http://localhost", "1", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class, - (Class) IntegrationTestContextBuilder.class, Collections.EMPTY_LIST); + "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class, + (Class) IntegrationTestContextBuilder.class, Collections.EMPTY_LIST); Properties props = RestContextFactory.toProperties(contextSpec); assertEquals(props.getProperty("test.endpoint"), "http://localhost"); @@ -121,8 +124,8 @@ public class RestContextFactoryTest { public void testBuilderPropertiesWithModule() { @SuppressWarnings("rawtypes") RestContextSpec contextSpec = contextSpec(provider, - "http://localhost", "1", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class, - (Class) IntegrationTestContextBuilder.class, Collections. singleton(new A())); + "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class, + (Class) IntegrationTestContextBuilder.class, Collections. singleton(new A())); Properties props = RestContextFactory.toProperties(contextSpec); assertEquals(props.getProperty("test.endpoint"), "http://localhost"); @@ -142,8 +145,8 @@ public class RestContextFactoryTest { public void testBuilderPropertiesWithModules() { @SuppressWarnings("rawtypes") RestContextSpec contextSpec = contextSpec(provider, - "http://localhost", "1", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class, - (Class) IntegrationTestContextBuilder.class, Arrays. asList(new A(), new B())); + "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null, PropertiesBuilder.class, + (Class) IntegrationTestContextBuilder.class, Arrays. asList(new A(), new B())); Properties props = RestContextFactory.toProperties(contextSpec); assertEquals(props.getProperty("test.endpoint"), "http://localhost"); @@ -155,7 +158,7 @@ public class RestContextFactoryTest { assertEquals(props.getProperty("test.propertiesbuilder"), PropertiesBuilder.class.getName()); assertEquals(props.getProperty("test.contextbuilder"), IntegrationTestContextBuilder.class.getName()); assertEquals(props.getProperty("test.modules"), - "org.jclouds.rest.RestContextFactoryTest$A,org.jclouds.rest.RestContextFactoryTest$B"); + "org.jclouds.rest.RestContextFactoryTest$A,org.jclouds.rest.RestContextFactoryTest$B"); new RestContextFactory().createContext(provider, props); } @@ -164,21 +167,24 @@ public class RestContextFactoryTest { Properties props = new Properties(); props.setProperty("test.endpoint", "http://localhost"); props.setProperty("test.apiversion", "1"); + props.setProperty("test.iso3166-codes", "US"); props.setProperty("jclouds.identity", "foo"); props.setProperty("jclouds.credential", "bar"); props.setProperty("test.propertiesbuilder", PropertiesBuilder.class.getName()); props.setProperty("test.contextbuilder", IntegrationTestContextBuilder.class.getName()); props.setProperty("jclouds.modules", - "org.jclouds.rest.RestContextFactoryTest$A,org.jclouds.rest.RestContextFactoryTest$B"); + "org.jclouds.rest.RestContextFactoryTest$A,org.jclouds.rest.RestContextFactoryTest$B"); new RestContextFactory() { @SuppressWarnings("hiding") @Override public RestContextSpec createContextSpec(String providerName, String identity, String credential, - Iterable wiring, Properties _overrides) { - RestContextSpec spec = super.createContextSpec(providerName, identity, credential, wiring, _overrides); + Iterable wiring, Properties _overrides) { + RestContextSpec spec = super + .createContextSpec(providerName, identity, credential, wiring, _overrides); + assertEquals(spec.iso3166Codes, "US"); assertEquals(spec.identity, "foo"); assertEquals(spec.credential, "bar"); assertEquals(Iterables.size(spec.modules), 2); @@ -189,28 +195,31 @@ public class RestContextFactoryTest { } public void testBuilderPropertiesJCloudsScopeWithProviderIdentityAndFileCredential() throws IOException { - + File file = File.createTempFile("foo", "bar"); file.deleteOnExit(); Files.write("bar", file, Charsets.UTF_8); Properties props = new Properties(); props.setProperty("test.endpoint", "http://localhost"); props.setProperty("test.apiversion", "1"); + props.setProperty("test.iso3166-codes", "US"); props.setProperty("test.identity", "foo"); props.setProperty("test.credential.file", file.getAbsolutePath()); props.setProperty("test.propertiesbuilder", PropertiesBuilder.class.getName()); props.setProperty("test.contextbuilder", IntegrationTestContextBuilder.class.getName()); props.setProperty("jclouds.modules", - "org.jclouds.rest.RestContextFactoryTest$A,org.jclouds.rest.RestContextFactoryTest$B"); + "org.jclouds.rest.RestContextFactoryTest$A,org.jclouds.rest.RestContextFactoryTest$B"); new RestContextFactory() { @SuppressWarnings("hiding") @Override public RestContextSpec createContextSpec(String providerName, String identity, String credential, - Iterable wiring, Properties _overrides) { - RestContextSpec spec = super.createContextSpec(providerName, identity, credential, wiring, _overrides); + Iterable wiring, Properties _overrides) { + RestContextSpec spec = super + .createContextSpec(providerName, identity, credential, wiring, _overrides); + assertEquals(spec.iso3166Codes, "US"); assertEquals(spec.identity, "foo"); assertEquals(spec.credential, "bar"); assertEquals(Iterables.size(spec.modules), 2); @@ -241,16 +250,16 @@ public class RestContextFactoryTest { @SuppressWarnings("unchecked") @Test(expectedExceptions = IllegalArgumentException.class) public void testBuilderPropertiesWithWrongConfig() { - @SuppressWarnings({ "unused", "rawtypes" }) + @SuppressWarnings( { "unused", "rawtypes" }) RestContextSpec contextSpec = contextSpec(provider, - "http://localhost", "1", "dummy", null, (Class) null, (Class) null, - (Class) IntegrationTestContextBuilder.class, (Class) PropertiesBuilder.class, Collections.EMPTY_LIST); + "http://localhost", "1", "", "dummy", null, (Class) null, (Class) null, + (Class) IntegrationTestContextBuilder.class, (Class) PropertiesBuilder.class, Collections.EMPTY_LIST); } @RequiresHttp @ConfiguresRestClient public static class IntegrationTestRestClientModule extends - RestClientModule { + RestClientModule { public IntegrationTestRestClientModule() { super(IntegrationTestClient.class, IntegrationTestAsyncClient.class); @@ -259,7 +268,7 @@ public class RestContextFactoryTest { } public static class IntegrationTestContextBuilder extends - RestContextBuilder { + RestContextBuilder { public IntegrationTestContextBuilder(Properties props) { super(IntegrationTestClient.class, IntegrationTestAsyncClient.class, props); diff --git a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java index 450bf9c9b5..74f23105ab 100755 --- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java @@ -97,6 +97,8 @@ import org.jclouds.http.functions.ReturnInputStream; import org.jclouds.http.functions.ReturnStringIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.UnwrapOnlyJsonValue; +import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue; +import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet; import org.jclouds.http.internal.PayloadEnclosingImpl; import org.jclouds.http.options.BaseHttpRequestOptions; import org.jclouds.http.options.GetOptions; @@ -116,12 +118,12 @@ import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.FormParams; import org.jclouds.rest.annotations.Headers; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; -import org.jclouds.rest.annotations.MapPayloadParams; import org.jclouds.rest.annotations.MatrixParams; import org.jclouds.rest.annotations.OverrideRequestFilters; import org.jclouds.rest.annotations.ParamParser; import org.jclouds.rest.annotations.PartParam; +import org.jclouds.rest.annotations.PayloadParam; +import org.jclouds.rest.annotations.PayloadParams; import org.jclouds.rest.annotations.QueryParams; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; @@ -210,7 +212,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @SuppressWarnings("unchecked") public void testDelegateAsyncIncludesVersion() throws SecurityException, NoSuchMethodException, - InterruptedException, ExecutionException { + InterruptedException, ExecutionException { Injector child = injectorForClient(); TransformingHttpCommandExecutorService mock = child.getInstance(TransformingHttpCommandExecutorService.class); @@ -225,7 +227,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { AsyncCaller caller = child.getInstance(AsyncCaller.class); expect(mock.submit(requestLineEquals("GET http://localhost:9999/client/1/foo HTTP/1.1"), eq(function))) - .andReturn(createNiceMock(ListenableFuture.class)).atLeastOnce(); + .andReturn(createNiceMock(ListenableFuture.class)).atLeastOnce(); replay(mock); caller.getCallee().onePath("foo"); @@ -254,7 +256,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { } public void testDelegateWithOverridingEndpoint() throws SecurityException, NoSuchMethodException, - InterruptedException, ExecutionException { + InterruptedException, ExecutionException { Injector child = injectorForClient(); TransformingHttpCommandExecutorService mock = child.getInstance(TransformingHttpCommandExecutorService.class); @@ -269,7 +271,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { Caller caller = child.getInstance(Caller.class); expect(mock.submit(requestLineEquals("GET http://localhost:1111/client/1/foo HTTP/1.1"), eq(function))) - .andReturn(Futures. immediateFuture(null)).atLeastOnce(); + .andReturn(Futures. immediateFuture(null)).atLeastOnce(); replay(mock); caller.getCallee().onePath("foo"); @@ -280,9 +282,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { private Injector injectorForClient() { - RestContextSpec contextSpec = contextSpec("test", "http://localhost:9999", "1", "userfoo", - null, Caller.class, AsyncCaller.class, ImmutableSet. of(new MockModule(), - new NullLoggingModule(), new CallerCalleeModule())); + RestContextSpec contextSpec = contextSpec("test", "http://localhost:9999", "1", "", + "userfoo", null, Caller.class, AsyncCaller.class, + ImmutableSet. of(new MockModule(), new NullLoggingModule(), new CallerCalleeModule())); return createContextBuilder(contextSpec).buildInjector(); @@ -297,7 +299,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { }; - @Target( { ElementType.METHOD }) + @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @javax.ws.rs.HttpMethod("FOO") public @interface FOO { @@ -332,10 +334,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testUnEncodeQuery() { URI expects = URI - .create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-compute.testObjectOperations&metadata=chef:sushi&metadata=foo:bar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436"); + .create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-compute.testObjectOperations&metadata=chef:sushi&metadata=foo:bar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436"); URI start = URI - .create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-compute.testObjectOperations&metadata=chef%3Asushi&metadata=foo%3Abar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436"); + .create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-compute.testObjectOperations&metadata=chef%3Asushi&metadata=foo%3Abar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436"); URI value = RestAnnotationProcessor.replaceQuery(uriBuilderProvider, start, start.getQuery(), null, '/', ':'); assertEquals(value, expects); } @@ -406,7 +408,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testPayloadParamVarargs() throws SecurityException, NoSuchMethodException, IOException { Method method = TestPayloadParamVarargs.class.getMethod("varargs", Array.newInstance(HttpRequestOptions.class, 0) - .getClass()); + .getClass()); verifyTestPostOptions(method); } @@ -499,7 +501,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testOverriddenEndpointParameter() throws SecurityException, NoSuchMethodException { Method method = TestOverriddenEndpoint.class.getMethod("foo", URI.class); HttpRequest request = factory(TestOverriddenEndpoint.class).createRequest(method, - new Object[] { URI.create("http://wowsa:8001") }); + new Object[] { URI.create("http://wowsa:8001") }); assertEquals(request.getEndpoint().getHost(), "wowsa"); assertEquals(request.getEndpoint().getPort(), 8001); assertEquals(request.getEndpoint().getPath(), ""); @@ -515,18 +517,25 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @POST @Path("/{foo}") - public void postWithPath(@PathParam("foo") @MapPayloadParam("fooble") String path, MapBinder content); + public void postWithPath(@PathParam("foo") @PayloadParam("fooble") String path, MapBinder content); @POST @Path("/{foo}") @MapBinder(BindToJsonPayload.class) - public void postWithMethodBinder(@PathParam("foo") @MapPayloadParam("fooble") String path); + public void postWithMethodBinder(@PathParam("foo") @PayloadParam("fooble") String path); @POST @Path("/{foo}") - @MapPayloadParams(keys = "rat", values = "atat") + @PayloadParams(keys = "rat", values = "atat") @MapBinder(BindToJsonPayload.class) - public void postWithMethodBinderAndDefaults(@PathParam("foo") @MapPayloadParam("fooble") String path); + public void postWithMethodBinderAndDefaults(@PathParam("foo") @PayloadParam("fooble") String path); + + @POST + @Path("/{foo}") + @PayloadParams(keys = "rat", values = "atat") + @org.jclouds.rest.annotations.Payload("name {fooble}") + @Produces(MediaType.TEXT_PLAIN) + public void testPayload(@PathParam("foo") @PayloadParam("fooble") String path); } public void testCreatePostRequest() throws SecurityException, NoSuchMethodException, IOException { @@ -592,6 +601,15 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { assertPayloadEquals(request, "{\"fooble\":\"data\",\"rat\":\"atat\"}", "application/json", false); } + public void testCreatePostWithPayload() throws SecurityException, NoSuchMethodException, IOException { + Method method = TestPost.class.getMethod("testPayload", String.class); + HttpRequest request = factory(TestPost.class).createRequest(method, "data"); + + assertRequestLineEquals(request, "POST http://localhost:9999/data HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, "name data", "text/plain", false); + } + static interface TestMultipartForm { @POST void withStringPart(@PartParam(name = "fooble") String path); @@ -604,44 +622,44 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @POST void withParamFileBinaryPart(@FormParam("name") String name, - @PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM) File path); + @PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM) File path); @POST void withParamByteArrayBinaryPart( - @FormParam("name") String name, - @PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM, filename = "{name}.tar.gz") byte[] content); + @FormParam("name") String name, + @PartParam(name = "file", contentType = MediaType.APPLICATION_OCTET_STREAM, filename = "{name}.tar.gz") byte[] content); } public void testMultipartWithStringPart() throws SecurityException, NoSuchMethodException, IOException { Method method = TestMultipartForm.class.getMethod("withStringPart", String.class); GeneratedHttpRequest httpRequest = factory(TestMultipartForm.class).createRequest(method, - "foobledata"); + "foobledata"); assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, ""); assertPayloadEquals(httpRequest,// - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"fooble\"\r\n" + // - "\r\n" + // - "foobledata\r\n" + // - "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"fooble\"\r\n" + // + "\r\n" + // + "foobledata\r\n" + // + "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); } public void testMultipartWithParamStringPart() throws SecurityException, NoSuchMethodException, IOException { Method method = TestMultipartForm.class.getMethod("withParamStringPart", String.class, String.class); GeneratedHttpRequest httpRequest = factory(TestMultipartForm.class).createRequest(method, - "name", "foobledata"); + "name", "foobledata"); assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, ""); assertPayloadEquals(httpRequest,// - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"name\"\r\n" + // - "\r\n" + // - "name\r\n" + // / - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"file\"\r\n" + // - "\r\n" + // - "foobledata\r\n" + // - "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"name\"\r\n" + // + "\r\n" + // + "name\r\n" + // / + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"file\"\r\n" + // + "\r\n" + // + "foobledata\r\n" + // + "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); } public void testMultipartWithParamFilePart() throws SecurityException, NoSuchMethodException, IOException { @@ -651,38 +669,38 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { file.deleteOnExit(); GeneratedHttpRequest httpRequest = factory(TestMultipartForm.class).createRequest(method, - "name", file); + "name", file); assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, ""); assertPayloadEquals(httpRequest,// - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"name\"\r\n" + // - "\r\n" + // - "name\r\n" + // / - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n" + // - "\r\n" + // - "foobledata\r\n" + // - "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"name\"\r\n" + // + "\r\n" + // + "name\r\n" + // / + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n" + // + "\r\n" + // + "foobledata\r\n" + // + "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); } public void testMultipartWithParamByteArrayPart() throws SecurityException, NoSuchMethodException, IOException { Method method = TestMultipartForm.class.getMethod("withParamByteArrayBinaryPart", String.class, byte[].class); GeneratedHttpRequest httpRequest = factory(TestMultipartForm.class).createRequest(method, - "name", "goo".getBytes()); + "name", "goo".getBytes()); assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, ""); assertPayloadEquals(httpRequest,// - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"name\"\r\n" + // - "\r\n" + // - "name\r\n" + // / - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"file\"; filename=\"name.tar.gz\"\r\n" + // - "Content-Type: application/octet-stream\r\n" + // - "\r\n" + // - "goo\r\n" + // - "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"name\"\r\n" + // + "\r\n" + // + "name\r\n" + // / + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"file\"; filename=\"name.tar.gz\"\r\n" + // + "Content-Type: application/octet-stream\r\n" + // + "\r\n" + // + "goo\r\n" + // + "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); }; public void testMultipartWithParamFileBinaryPart() throws SecurityException, NoSuchMethodException, IOException { @@ -692,27 +710,27 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { file.deleteOnExit(); GeneratedHttpRequest httpRequest = factory(TestMultipartForm.class).createRequest(method, - "name", file); + "name", file); assertRequestLineEquals(httpRequest, "POST http://localhost:9999 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, ""); assertPayloadEquals(httpRequest,// - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"name\"\r\n" + // - "\r\n" + // - "name\r\n" + // / - "----JCLOUDS--\r\n" + // - "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n" + // - "Content-Type: application/octet-stream\r\n" + // - "\r\n" + // - "'(2\r\n" + // - "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"name\"\r\n" + // + "\r\n" + // + "name\r\n" + // / + "----JCLOUDS--\r\n" + // + "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n" + // + "Content-Type: application/octet-stream\r\n" + // + "\r\n" + // + "'(2\r\n" + // + "----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false); } public interface TestPut { @PUT @Path("/{foo}") @MapBinder(BindToJsonPayload.class) - void putWithMethodBinder(@PathParam("foo") @MapPayloadParam("fooble") String path); + void putWithMethodBinder(@PathParam("foo") @PayloadParam("fooble") String path); @PUT @Path("/{foo}") @@ -723,7 +741,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Path("/{foo}") @MapBinder(BindToJsonPayload.class) @Consumes(MediaType.APPLICATION_JSON) - Wrapper putWithMethodBinderConsumes(@PathParam("foo") @MapPayloadParam("fooble") String path); + Wrapper putWithMethodBinderConsumes(@PathParam("foo") @PayloadParam("fooble") String path); @GET @Path("/") @@ -764,7 +782,25 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Consumes(MediaType.APPLICATION_JSON) ListenableFuture> testUnwrap4(); - @Target( { ElementType.METHOD }) + @GET + @Path("/") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture> testUnwrapDepth2(); + + @GET + @Path("/") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture testUnwrapDepth2Long(); + + @GET + @Path("/") + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture testUnwrapDepth3(); + + @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @HttpMethod("ROWDY") public @interface ROWDY { @@ -819,7 +855,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function parser = (Function) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))).foo, "bar"); @@ -834,10 +870,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function> parser = (Function>) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), ImmutableMap.of( - "foo", "bar")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), + ImmutableMap.of("foo", "bar")); } @@ -850,10 +886,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function> parser = (Function>) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), ImmutableMap.of( - "foo", "bar")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), + ImmutableMap.of("foo", "bar")); } @@ -866,10 +902,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function> parser = (Function>) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); - assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), ImmutableMap.of( - "foo", "bar")); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), + ImmutableMap.of("foo", "bar")); } @@ -882,7 +918,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function> parser = (Function>) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), "bar"); @@ -897,7 +933,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function> parser = (Function>) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{ foo:\"bar\"}"))), "bar"); @@ -912,10 +948,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function> parser = (Function>) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":[\"0.7.0\",\"0.7.1\"]}"))), - ImmutableSet.of("0.7.0", "0.7.1")); + ImmutableSet.of("0.7.0", "0.7.1")); } @SuppressWarnings("unchecked") @@ -927,10 +963,89 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { // now test that it works! Function> parser = (Function>) RestAnnotationProcessor - .createResponseParser(parserFactory, injector, method, request); + .createResponseParser(parserFactory, injector, method, request); assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":[\"0.7.0\",\"0.7.1\"]}"))), - ImmutableSet.of("0.7.0", "0.7.1")); + ImmutableSet.of("0.7.0", "0.7.1")); + } + + @SuppressWarnings("unchecked") + public void testUnwrapDepth2() throws SecurityException, NoSuchMethodException, IOException { + Method method = TestPut.class.getMethod("testUnwrapDepth2"); + HttpRequest request = factory(TestPut.class).createRequest(method); + + assertResponseParserClassEquals(method, request, UnwrapOnlyNestedJsonValue.class); + // now test that it works! + + Function> parser = (Function>) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + assertEquals(parser.apply(new HttpResponse(200, "ok", + newStringPayload("{\"runit\":{\"runit\":[\"0.7.0\",\"0.7.1\"]}}"))), ImmutableSet.of("0.7.0", "0.7.1")); + + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":{}}"))), + ImmutableSet. of()); + } + + @SuppressWarnings("unchecked") + public void testUnwrapDepth2Long() throws SecurityException, NoSuchMethodException, IOException { + Method method = TestPut.class.getMethod("testUnwrapDepth2Long"); + HttpRequest request = factory(TestPut.class).createRequest(method); + + assertResponseParserClassEquals(method, request, UnwrapOnlyNestedJsonValue.class); + // now test that it works! + + Function> parser = (Function>) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + assertEquals(parser.apply(new HttpResponse(200, "ok", + newStringPayload("{ \"destroyvirtualmachineresponse\" : {\"jobid\":4} }"))), new Long(4)); + } + + @SuppressWarnings("unchecked") + public void testUnwrapDepth3() throws SecurityException, NoSuchMethodException, IOException { + Method method = TestPut.class.getMethod("testUnwrapDepth3"); + HttpRequest request = factory(TestPut.class).createRequest(method); + + assertResponseParserClassEquals(method, request, UnwrapOnlyNestedJsonValueInSet.class); + // now test that it works! + + Function> parser = (Function>) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":{\"runit\":[\"0.7.0\"]}}"))), + "0.7.0"); + } + + @SuppressWarnings("unchecked") + public void testUnwrapDepth3None() throws SecurityException, NoSuchMethodException, IOException { + Method method = TestPut.class.getMethod("testUnwrapDepth3"); + HttpRequest request = factory(TestPut.class).createRequest(method); + + assertResponseParserClassEquals(method, request, UnwrapOnlyNestedJsonValueInSet.class); + // now test that it works! + + Function> parser = (Function>) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":{\"runit\":[]}}"))), null); + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":{}}"))), null); + + } + + @SuppressWarnings("unchecked") + @Test(expectedExceptions = IllegalArgumentException.class) + public void testUnwrapDepth3TooMany() throws SecurityException, NoSuchMethodException, IOException { + Method method = TestPut.class.getMethod("testUnwrapDepth3"); + HttpRequest request = factory(TestPut.class).createRequest(method); + + assertResponseParserClassEquals(method, request, UnwrapOnlyNestedJsonValueInSet.class); + // now test that it works! + + Function> parser = (Function>) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":{\"runit\":[\"0.7.0\",\"0.7.1\"]}}"))); } static class TestRequestFilter1 implements HttpRequestFilter { @@ -980,9 +1095,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testRequestFilterOverrideOnRequest() throws SecurityException, NoSuchMethodException { Method method = TestRequestFilter.class.getMethod("getOverride", HttpRequest.class); HttpRequest request = factory(TestRequestFilter.class).createRequest( - method, - HttpRequest.builder().method("GET").endpoint(URI.create("http://localhost")).headers( - ImmutableMultimap.of("foo", "bar")).build()); + method, + HttpRequest.builder().method("GET").endpoint(URI.create("http://localhost")) + .headers(ImmutableMultimap.of("foo", "bar")).build()); assertEquals(request.getFilters().size(), 1); assertEquals(request.getHeaders().size(), 1); assertEquals(request.getFilters().get(0).getClass(), TestRequestFilter2.class); @@ -1030,7 +1145,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testConstantPathParam() throws SecurityException, NoSuchMethodException, IOException { Method method = TestConstantPathParam.class.getMethod("twoPaths", String.class, String.class); HttpRequest request = factory(TestConstantPathParam.class).createRequest(method, - new Object[] { "1", "localhost" }); + new Object[] { "1", "localhost" }); assertRequestLineEquals(request, "GET http://localhost:9999/v1/ralphie/1/localhost HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, null, null, false); @@ -1167,7 +1282,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildTwoHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestHeader.class.getMethod("twoHeader", String.class); Multimap headers = factory(TestHeader.class).createRequest(oneHeader, new Object[] { "robot" }) - .getHeaders(); + .getHeaders(); assertEquals(headers.size(), 2); assertEquals(headers.get("slash"), Collections.singletonList("/robot")); assertEquals(headers.get("hyphen"), Collections.singletonList("-robot")); @@ -1185,7 +1300,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildOneClassHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestClassHeader.class.getMethod("oneHeader", String.class); Multimap headers = factory(TestClassHeader.class).createRequest(oneHeader, - new Object[] { "robot" }).getHeaders(); + new Object[] { "robot" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot")); } @@ -1194,7 +1309,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildOneHeader() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneHeader = TestHeader.class.getMethod("oneHeader", String.class); Multimap headers = factory(TestHeader.class).createRequest(oneHeader, new Object[] { "robot" }) - .getHeaders(); + .getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot")); } @@ -1203,17 +1318,17 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildTwoHeaders() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoHeaders = TestHeader.class.getMethod("twoHeaders", String.class, String.class); Multimap headers = factory(TestHeader.class).createRequest(twoHeaders, - new Object[] { "robot", "eggs" }).getHeaders(); + new Object[] { "robot", "eggs" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/robot/eggs")); } @Test public void testBuildTwoHeadersOutOfOrder() throws SecurityException, NoSuchMethodException, - UnsupportedEncodingException { + UnsupportedEncodingException { Method twoHeadersOutOfOrder = TestHeader.class.getMethod("twoHeadersOutOfOrder", String.class, String.class); Multimap headers = factory(TestHeader.class).createRequest(twoHeadersOutOfOrder, - new Object[] { "robot", "eggs" }).getHeaders(); + new Object[] { "robot", "eggs" }).getHeaders(); assertEquals(headers.size(), 1); assertEquals(headers.get("x-amz-copy-source"), Collections.singletonList("/eggs/robot")); } @@ -1227,8 +1342,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Test public void testQueryInOptions() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestQueryReplace.class.getMethod("queryInOptions", String.class, TestReplaceQueryOptions.class); - String query = factory(TestQueryReplace.class).createRequest(oneQuery, - new Object[] { "robot", new TestReplaceQueryOptions() }).getEndpoint().getQuery(); + String query = factory(TestQueryReplace.class) + .createRequest(oneQuery, new Object[] { "robot", new TestReplaceQueryOptions() }).getEndpoint().getQuery(); assertEquals(query, "x-amz-copy-source=/robot"); } @@ -1236,13 +1351,13 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @POST @Path("/objects/{id}/action/{action}") ListenableFuture action(@PathParam("id") String id, @PathParam("action") String action, - @BinderParam(BindMapToMatrixParams.class) Map options); + @BinderParam(BindMapToMatrixParams.class) Map options); } public void testTestMapMatrixParams() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method method = TestMapMatrixParams.class.getMethod("action", String.class, String.class, Map.class); HttpRequest request = factory(TestMapMatrixParams.class).createRequest(method, - new Object[] { "robot", "kill", ImmutableMap.of("death", "slow") }); + new Object[] { "robot", "kill", ImmutableMap.of("death", "slow") }); assertRequestLineEquals(request, "POST http://localhost:9999/objects/robot/action/kill;death=slow HTTP/1.1"); assertEquals(request.getHeaders().size(), 0); } @@ -1284,7 +1399,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildTwoQuery() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestQueryReplace.class.getMethod("twoQuery", String.class); String query = factory(TestQueryReplace.class).createRequest(oneQuery, new Object[] { "robot" }).getEndpoint() - .getQuery(); + .getQuery(); assertEquals(query, "slash=/robot&hyphen=-robot"); } @@ -1300,7 +1415,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildOneClassQuery() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestClassQuery.class.getMethod("oneQuery", String.class); String query = factory(TestClassQuery.class).createRequest(oneQuery, new Object[] { "robot" }).getEndpoint() - .getQuery(); + .getQuery(); assertEquals(query, "x-amz-copy-source=/robot"); } @@ -1308,7 +1423,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildOneQuery() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneQuery = TestQueryReplace.class.getMethod("oneQuery", String.class); String query = factory(TestQueryReplace.class).createRequest(oneQuery, new Object[] { "robot" }).getEndpoint() - .getQuery(); + .getQuery(); assertEquals(query, "x-amz-copy-source=/robot"); } @@ -1316,16 +1431,16 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildTwoQuerys() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoQuerys = TestQueryReplace.class.getMethod("twoQuerys", String.class, String.class); String query = factory(TestQueryReplace.class).createRequest(twoQuerys, new Object[] { "robot", "eggs" }) - .getEndpoint().getQuery(); + .getEndpoint().getQuery(); assertEquals(query, "x-amz-copy-source=/robot/eggs"); } @Test public void testBuildTwoQuerysOutOfOrder() throws SecurityException, NoSuchMethodException, - UnsupportedEncodingException { + UnsupportedEncodingException { Method twoQuerysOutOfOrder = TestQueryReplace.class.getMethod("twoQuerysOutOfOrder", String.class, String.class); - String query = factory(TestQueryReplace.class).createRequest(twoQuerysOutOfOrder, - new Object[] { "robot", "eggs" }).getEndpoint().getQuery(); + String query = factory(TestQueryReplace.class) + .createRequest(twoQuerysOutOfOrder, new Object[] { "robot", "eggs" }).getEndpoint().getQuery(); assertEquals(query, "x-amz-copy-source=/eggs/robot"); } @@ -1338,9 +1453,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Test public void testMatrixInOptions() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestMatrixReplace.class.getMethod("matrixInOptions", String.class, - TestReplaceMatrixOptions.class); - String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, - new Object[] { "robot", new TestReplaceMatrixOptions() }).getEndpoint().getPath(); + TestReplaceMatrixOptions.class); + String path = factory(TestMatrixReplace.class) + .createRequest(oneMatrix, new Object[] { "robot", new TestReplaceMatrixOptions() }).getEndpoint().getPath(); assertEquals(path, "/;x-amz-copy-source=/robot"); } @@ -1381,7 +1496,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildTwoMatrix() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestMatrixReplace.class.getMethod("twoMatrix", String.class); String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, new Object[] { "robot" }).getEndpoint() - .getPath(); + .getPath(); assertEquals(path, "/;slash=/robot;hyphen=-robot"); } @@ -1398,7 +1513,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildOneClassMatrix() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestClassMatrix.class.getMethod("oneMatrix", String.class); String path = factory(TestClassMatrix.class).createRequest(oneMatrix, new Object[] { "robot" }).getEndpoint() - .getPath(); + .getPath(); assertEquals(path, "/;x-amz-copy-source=/robot"); } @@ -1406,7 +1521,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildOneMatrix() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method oneMatrix = TestMatrixReplace.class.getMethod("oneMatrix", String.class); String path = factory(TestMatrixReplace.class).createRequest(oneMatrix, new Object[] { "robot" }).getEndpoint() - .getPath(); + .getPath(); assertEquals(path, "/;x-amz-copy-source=/robot"); } @@ -1414,17 +1529,17 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildTwoMatrixs() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoMatrixs = TestMatrixReplace.class.getMethod("twoMatrixs", String.class, String.class); String path = factory(TestMatrixReplace.class).createRequest(twoMatrixs, new Object[] { "robot", "eggs" }) - .getEndpoint().getPath(); + .getEndpoint().getPath(); assertEquals(path, "/;x-amz-copy-source=/robot/eggs"); } @Test public void testBuildTwoMatrixsOutOfOrder() throws SecurityException, NoSuchMethodException, - UnsupportedEncodingException { + UnsupportedEncodingException { Method twoMatrixsOutOfOrder = TestMatrixReplace.class.getMethod("twoMatrixsOutOfOrder", String.class, - String.class); - String path = factory(TestMatrixReplace.class).createRequest(twoMatrixsOutOfOrder, - new Object[] { "robot", "eggs" }).getEndpoint().getPath(); + String.class); + String path = factory(TestMatrixReplace.class) + .createRequest(twoMatrixsOutOfOrder, new Object[] { "robot", "eggs" }).getEndpoint().getPath(); assertEquals(path, "/;x-amz-copy-source=/eggs/robot"); } @@ -1466,7 +1581,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testPutPayloadEnclosing() throws SecurityException, NoSuchMethodException, IOException { Method method = TestTransformers.class.getMethod("put", PayloadEnclosing.class); HttpRequest request = factory(TestQuery.class).createRequest(method, - new PayloadEnclosingImpl(newStringPayload("whoops"))); + new PayloadEnclosingImpl(newStringPayload("whoops"))); assertRequestLineEquals(request, "PUT http://localhost:9999?x-ms-version=2009-07-17 HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, "whoops", "application/unknown", false); @@ -1484,10 +1599,10 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { } public void testPutInputStreamPayloadEnclosingGenerateMD5() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Method method = TestTransformers.class.getMethod("put", PayloadEnclosing.class); - PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl(newInputStreamPayload(Strings2 - .toInputStream("whoops"))); + PayloadEnclosing payloadEnclosing = new PayloadEnclosingImpl( + newInputStreamPayload(Strings2.toInputStream("whoops"))); calculateMD5(payloadEnclosing, crypto.md5()); HttpRequest request = factory(TestQuery.class).createRequest(method, payloadEnclosing); @@ -1544,7 +1659,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { } public void testPutPayloadWithGeneratedMD5AndNoContentType() throws SecurityException, NoSuchMethodException, - IOException { + IOException { Payload payload = newStringPayload("whoops"); calculateMD5(payload, crypto.md5()); Method method = TestTransformers.class.getMethod("put", Payload.class); @@ -1565,7 +1680,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { } public void testPutInputStreamPayloadWithMD5() throws NoSuchAlgorithmException, IOException, SecurityException, - NoSuchMethodException { + NoSuchMethodException { Payload payload = newStringPayload("whoops"); calculateMD5(payload, crypto.md5()); Method method = TestTransformers.class.getMethod("put", Payload.class); @@ -1589,9 +1704,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @SuppressWarnings("unchecked") public static Class> unwrap(RestAnnotationProcessor processor, - Method method) { + Method method) { return (Class>) RestAnnotationProcessor.getParserOrThrowException(method) - .getTypeLiteral().getRawType(); + .getTypeLiteral().getRawType(); } public void testURI() throws SecurityException, NoSuchMethodException { @@ -1607,7 +1722,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { } public static class ReturnStringIf200Context extends ReturnStringIf2xx implements - InvocationContext { + InvocationContext { public HttpRequest request; @@ -1629,8 +1744,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { RestAnnotationProcessor processor = factory(TestTransformers.class); Method method = TestTransformers.class.getMethod("oneTransformerWithContext"); GeneratedHttpRequest request = GeneratedHttpRequest. builder().method("GET") - .endpoint(URI.create("http://localhost")).declaring(TestTransformers.class).javaMethod(method).args( - new Object[] {}).build(); + .endpoint(URI.create("http://localhost")).declaring(TestTransformers.class).javaMethod(method) + .args(new Object[] {}).build(); Function transformer = processor.createResponseParser(method, request); assertEquals(transformer.getClass(), ReturnStringIf200Context.class); assertEquals(((ReturnStringIf200Context) transformer).request, request); @@ -1671,7 +1786,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @PUT @Path("/{id}") ListenableFuture put(@PathParam("id") @ParamParser(FirstCharacter.class) String id, - @BinderParam(BindToStringPayload.class) String payload); + @BinderParam(BindToStringPayload.class) String payload); @PUT @Path("/{id}") @@ -1683,7 +1798,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Headers(keys = "foo", values = "--{id}--") @ResponseParser(ReturnTrueIf2xx.class) ListenableFuture putHeader(@PathParam("id") String id, - @BinderParam(BindToStringPayload.class) String payload); + @BinderParam(BindToStringPayload.class) String payload); } public void testCreateGetVarArgOptionsThatProducesHeaders() throws SecurityException, NoSuchMethodException { @@ -1697,8 +1812,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { assertEquals(request.getMethod(), HttpMethod.GET); assertEquals(request.getHeaders().size(), 2); assertEquals(request.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); - assertEquals(request.getHeaders().get(HttpHeaders.IF_MODIFIED_SINCE), Collections.singletonList(dateService - .rfc822DateFormat(date))); + assertEquals(request.getHeaders().get(HttpHeaders.IF_MODIFIED_SINCE), + Collections.singletonList(dateService.rfc822DateFormat(date))); } public void testCreateGetOptionsThatProducesHeaders() throws SecurityException, NoSuchMethodException { @@ -1711,8 +1826,8 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { assertEquals(request.getMethod(), HttpMethod.GET); assertEquals(request.getHeaders().size(), 2); assertEquals(request.getHeaders().get(HttpHeaders.HOST), Collections.singletonList("localhost")); - assertEquals(request.getHeaders().get(HttpHeaders.IF_MODIFIED_SINCE), Collections.singletonList(dateService - .rfc822DateFormat(date))); + assertEquals(request.getHeaders().get(HttpHeaders.IF_MODIFIED_SINCE), + Collections.singletonList(dateService.rfc822DateFormat(date))); } public class PrefixOptions extends BaseHttpRequestOptions { @@ -1775,7 +1890,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Test(dataProvider = "strings") public void testCreateGetRequest(String key) throws SecurityException, NoSuchMethodException, - UnsupportedEncodingException { + UnsupportedEncodingException { Method method = TestRequest.class.getMethod("get", String.class, String.class); HttpRequest request = factory(TestRequest.class).createRequest(method, new Object[] { key, "localhost" }); assertEquals(request.getEndpoint().getHost(), "localhost"); @@ -1818,7 +1933,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testVirtualHostMethod() throws SecurityException, NoSuchMethodException { Method method = TestVirtualHostMethod.class.getMethod("get", String.class, String.class); HttpRequest request = factory(TestVirtualHostMethod.class).createRequest(method, - new Object[] { "1", "localhost" }); + new Object[] { "1", "localhost" }); assertEquals(request.getEndpoint().getHost(), "localhost"); assertEquals(request.getEndpoint().getPath(), "/1"); assertEquals(request.getMethod(), HttpMethod.GET); @@ -1883,7 +1998,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testOneHeader() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("oneHeader", String.class); Multimap headers = factory(TestHeaders.class).buildHeaders( - ImmutableMultimap. of().entries(), method, "robot"); + ImmutableMultimap. of().entries(), method, "robot"); assertEquals(headers.size(), 1); assertEquals(headers.get("header"), Collections.singletonList("robot")); } @@ -1892,7 +2007,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testOneIntHeader() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("oneIntHeader", int.class); Multimap headers = factory(TestHeaders.class).buildHeaders( - ImmutableMultimap. of().entries(), method, 1); + ImmutableMultimap. of().entries(), method, 1); assertEquals(headers.size(), 1); assertEquals(headers.get("header"), Collections.singletonList("1")); } @@ -1901,7 +2016,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testTwoDifferentHeaders() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("twoDifferentHeaders", String.class, String.class); Multimap headers = factory(TestHeaders.class).buildHeaders( - ImmutableMultimap. of().entries(), method, "robot", "egg"); + ImmutableMultimap. of().entries(), method, "robot", "egg"); assertEquals(headers.size(), 2); assertEquals(headers.get("header1"), Collections.singletonList("robot")); assertEquals(headers.get("header2"), Collections.singletonList("egg")); @@ -1911,7 +2026,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testTwoSameHeaders() throws SecurityException, NoSuchMethodException { Method method = TestHeaders.class.getMethod("twoSameHeaders", String.class, String.class); Multimap headers = factory(TestHeaders.class).buildHeaders( - ImmutableMultimap. of().entries(), method, "robot", "egg"); + ImmutableMultimap. of().entries(), method, "robot", "egg"); assertEquals(headers.size(), 2); Collection values = headers.get("header"); assert values.contains("robot"); @@ -1934,7 +2049,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @GET void twoEndpointParams(@EndpointParam(parser = ConvertTwoToURI.class) String EndpointParam1, - @EndpointParam(parser = ConvertTwoToURI.class) String EndpointParam2); + @EndpointParam(parser = ConvertTwoToURI.class) String EndpointParam2); @Singleton public static class ConvertTwoToURI implements Function { @@ -1954,7 +2069,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testOneEndpointParam() throws SecurityException, NoSuchMethodException { Method method = TestEndpointParams.class.getMethod("oneEndpointParam", String.class); URI uri = factory(TestEndpointParams.class).getEndpointInParametersOrNull(method, new Object[] { "robot" }, - injector); + injector); assertEquals(uri, URI.create("robot")); } @@ -1964,7 +2079,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testTwoDifferentEndpointParams() throws SecurityException, NoSuchMethodException { Method method = TestEndpointParams.class.getMethod("twoEndpointParams", String.class, String.class); URI uri = factory(TestEndpointParams.class).getEndpointInParametersOrNull(method, - new Object[] { "robot", "egg" }, injector); + new Object[] { "robot", "egg" }, injector); assertEquals(uri, URI.create("robot/egg")); } @@ -1975,11 +2090,11 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @PUT @Path("/{foo}") public ListenableFuture putWithPath(@PathParam("foo") String path, - @BinderParam(BindToStringPayload.class) String content); + @BinderParam(BindToStringPayload.class) String content); @PUT public void twoEntities(@BinderParam(BindToStringPayload.class) String payload1, - @BinderParam(BindToStringPayload.class) String payload2); + @BinderParam(BindToStringPayload.class) String payload2); } @Test @@ -2077,40 +2192,39 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { public void testBuildTwoForms() throws SecurityException, NoSuchMethodException, UnsupportedEncodingException { Method twoForms = TestFormReplace.class.getMethod("twoForms", String.class, String.class); Object form = factory(TestFormReplace.class).createRequest(twoForms, "robot", "eggs").getPayload() - .getRawContent(); + .getRawContent(); assertEquals(form, "x-amz-copy-source=/robot/eggs"); } @Test public void testBuildTwoFormsOutOfOrder() throws SecurityException, NoSuchMethodException, - UnsupportedEncodingException { + UnsupportedEncodingException { Method twoFormsOutOfOrder = TestFormReplace.class.getMethod("twoFormsOutOfOrder", String.class, String.class); Object form = factory(TestFormReplace.class).createRequest(twoFormsOutOfOrder, "robot", "eggs").getPayload() - .getRawContent(); + .getRawContent(); assertEquals(form, "x-amz-copy-source=/eggs/robot"); } @SuppressWarnings("unchecked") private RestAnnotationProcessor factory(Class clazz) { return ((RestAnnotationProcessor) injector.getInstance(Key.get(newParameterizedType( - RestAnnotationProcessor.class, clazz)))); + RestAnnotationProcessor.class, clazz)))); } DateService dateService = new SimpleDateFormatDateService(); @BeforeClass void setupFactory() { - RestContextSpec contextSpec = contextSpec("test", "http://localhost:9999", "1", "userfoo", null, - String.class, Integer.class, ImmutableSet. of(new MockModule(), new NullLoggingModule(), - new AbstractModule() { + RestContextSpec contextSpec = contextSpec("test", "http://localhost:9999", "1", "", "userfoo", + null, String.class, Integer.class, + ImmutableSet. of(new MockModule(), new NullLoggingModule(), new AbstractModule() { - @Override - protected void configure() { - bind(URI.class).annotatedWith(Localhost2.class).toInstance( - URI.create("http://localhost:1111")); - } + @Override + protected void configure() { + bind(URI.class).annotatedWith(Localhost2.class).toInstance(URI.create("http://localhost:1111")); + } - })); + })); injector = createContextBuilder(contextSpec).buildInjector(); parserFactory = injector.getInstance(ParseSax.Factory.class); diff --git a/core/src/test/java/org/jclouds/util/Throwables2Test.java b/core/src/test/java/org/jclouds/util/Throwables2Test.java index ab54c99202..8a8e2992ed 100644 --- a/core/src/test/java/org/jclouds/util/Throwables2Test.java +++ b/core/src/test/java/org/jclouds/util/Throwables2Test.java @@ -30,6 +30,7 @@ import java.util.concurrent.TimeoutException; import org.jclouds.http.HttpCommand; import org.jclouds.http.HttpResponseException; import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.InsufficientResourcesException; import org.jclouds.rest.ResourceNotFoundException; import org.testng.annotations.Test; @@ -115,7 +116,13 @@ public class Throwables2Test { Exception e = new AuthorizationException(); returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e)); } - + + @Test(expectedExceptions = InsufficientResourcesException.class) + public void testPropagateStandardExceptionInsufficientResourcesException() throws Exception { + Exception e = new InsufficientResourcesException(); + returnFirstExceptionIfInListOrThrowStandardExceptionOrCause(new Class[] {}, new RuntimeException(e)); + } + @Test(expectedExceptions = ResourceNotFoundException.class) public void testPropagateStandardExceptionResourceNotFoundException() throws Exception { Exception e = new ResourceNotFoundException(); diff --git a/demos/antjruby/build.xml b/demos/antjruby/build.xml index fbf89a88a1..41e329ece4 100644 --- a/demos/antjruby/build.xml +++ b/demos/antjruby/build.xml @@ -60,8 +60,8 @@ /> diff --git a/demos/createandlistbuckets/pom.xml b/demos/createandlistbuckets/pom.xml deleted file mode 100644 index cfc4f6b7ff..0000000000 --- a/demos/createandlistbuckets/pom.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - 4.0.0 - - org.jclouds - demos-project - 1.0-SNAPSHOT - - createandlistbuckets - jclouds S3 sample that creates a bucket then lists all owned buckets - jclouds S3 sample that creates a bucket then lists all owned buckets - - - org.jclouds.api - s3 - ${project.version} - - - - ${project.artifactId} - - - - org.apache.maven.plugins - maven-jar-plugin - - - - org.jclouds.aws.s3.samples.MainApp - - - - - - - maven-assembly-plugin - - - jar-with-dependencies - - - - org.jclouds.aws.s3.samples.MainApp - - - - - - make-assembly - package - - single - - - - - - - - - diff --git a/demos/createandlistbuckets/src/main/java/org/jclouds/aws/s3/samples/MainApp.java b/demos/createandlistbuckets/src/main/java/org/jclouds/aws/s3/samples/MainApp.java deleted file mode 100755 index 52d6c077e7..0000000000 --- a/demos/createandlistbuckets/src/main/java/org/jclouds/aws/s3/samples/MainApp.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.aws.s3.samples; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; - -import org.jclouds.s3.S3AsyncClient; -import org.jclouds.s3.S3Client; -import org.jclouds.blobstore.BlobStore; -import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.blobstore.BlobStoreContextFactory; -import org.jclouds.blobstore.domain.Blob; -import org.jclouds.blobstore.domain.StorageMetadata; -import org.jclouds.blobstore.domain.StorageType; -import org.jclouds.rest.RestContext; - -/** - * This the Main class of an Application that demonstrates the use of the blobstore. - * - * Usage is: java MainApp \"accesskeyid\" \"secretkey\" \"bucketName\" - * - * @author Carlos Fernandes - * @author Adrian Cole - */ -public class MainApp { - - public static int PARAMETERS = 3; - public static String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: \"accesskeyid\" \"secretkey\" \"bucketName\" "; - - public static void main(String[] args) throws IOException { - - if (args.length < PARAMETERS) - throw new IllegalArgumentException(INVALID_SYNTAX); - - // Args - String accesskeyid = args[0]; - String secretkey = args[1]; - String containerName = args[2]; - - // Init - BlobStoreContext context = new BlobStoreContextFactory().createContext("s3", accesskeyid, - secretkey); - - try { - - // Create Container - BlobStore blobStore = context.getBlobStore(); - blobStore.createContainerInLocation(null, containerName); - - // Add Blob - Blob blob = blobStore.newBlob("test"); - blob.setPayload("testdata"); - blobStore.putBlob(containerName, blob); - - // List Container - for (StorageMetadata resourceMd : blobStore.list()) { - if (resourceMd.getType() == StorageType.CONTAINER - || resourceMd.getType() == StorageType.FOLDER) { - // Use Map API - Map containerMap = context.createInputStreamMap(resourceMd - .getName()); - System.out.printf(" %s: %s entries%n", resourceMd.getName(), containerMap.size()); - } - } - - // Use Provider API - RestContext providerContext = context - .getProviderSpecificContext(); - providerContext.getApi().getBucketLogging(containerName); - - } finally { - // Close connecton - context.close(); - System.exit(0); - } - - } -} diff --git a/demos/createlamp/pom.xml b/demos/createlamp/pom.xml deleted file mode 100644 index 11548599b5..0000000000 --- a/demos/createlamp/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - 4.0.0 - - org.jclouds - demos-project - 1.0-SNAPSHOT - - createlamp - jclouds ec2 sample that creates an instance and all you need to access it - jclouds ec2 sample that creates an instance and all you need to access it - - - org.jclouds.driver - jclouds-jsch - ${project.version} - - - org.jclouds - jclouds-scriptbuilder - ${project.version} - - - - ${project.artifactId} - - - - org.apache.maven.plugins - maven-jar-plugin - - - - org.jclouds.aws.ec2.demos.createlamp.MainApp - - - - - - - maven-assembly-plugin - - - jar-with-dependencies - - - - org.jclouds.aws.ec2.demos.createlamp.MainApp - - - - - - make-assembly - package - - single - - - - - - - - - diff --git a/demos/createlamp/src/main/java/org/jclouds/aws/ec2/demos/createlamp/MainApp.java b/demos/createlamp/src/main/java/org/jclouds/aws/ec2/demos/createlamp/MainApp.java deleted file mode 100755 index 65517ef4a9..0000000000 --- a/demos/createlamp/src/main/java/org/jclouds/aws/ec2/demos/createlamp/MainApp.java +++ /dev/null @@ -1,243 +0,0 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * 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.aws.ec2.demos.createlamp; - -import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.asType; -import static org.jclouds.scriptbuilder.domain.Statements.exec; - -import java.util.NoSuchElementException; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.jclouds.aws.ec2.EC2AsyncClient; -import org.jclouds.aws.ec2.EC2Client; -import org.jclouds.aws.ec2.domain.InstanceState; -import org.jclouds.aws.ec2.domain.InstanceType; -import org.jclouds.aws.ec2.domain.IpProtocol; -import org.jclouds.aws.ec2.domain.KeyPair; -import org.jclouds.aws.ec2.domain.Reservation; -import org.jclouds.aws.ec2.domain.RunningInstance; -import org.jclouds.aws.ec2.predicates.InstanceStateRunning; -import org.jclouds.net.IPSocket; -import org.jclouds.predicates.InetSocketAddressConnect; -import org.jclouds.predicates.RetryablePredicate; -import org.jclouds.rest.RestContext; -import org.jclouds.rest.RestContextFactory; -import org.jclouds.scriptbuilder.ScriptBuilder; -import org.jclouds.scriptbuilder.domain.OsFamily; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; - -/** - * This the Main class of an Application that demonstrates the use of the EC2Client by creating a - * small lamp server. - * - * Usage is: java MainApp accesskeyid secretkey command name where command in create destroy - * - * @author Adrian Cole - */ -public class MainApp { - - public static int PARAMETERS = 4; - public static String INVALID_SYNTAX = "Invalid number of parameters. Syntax is: accesskeyid secretkey command name\nwhere command in create destroy"; - - public static void main(String[] args) throws TimeoutException { - - if (args.length < PARAMETERS) - throw new IllegalArgumentException(INVALID_SYNTAX); - - // Args - String accesskeyid = args[0]; - String secretkey = args[1]; - String command = args[2]; - String name = args[3]; - - // Init - RestContext context = new RestContextFactory().createContext("ec2", accesskeyid, - secretkey); - - // Get a synchronous client - EC2Client client = context.getApi(); - - try { - if (command.equals("create")) { - - KeyPair pair = createKeyPair(client, name); - - RunningInstance instance = createSecurityGroupKeyPairAndInstance(client, name); - - System.out.printf("instance %s ready%n", instance.getId()); - System.out.printf("ip address: %s%n", instance.getIpAddress()); - System.out.printf("dns name: %s%n", instance.getDnsName()); - System.out.printf("login identity:%n%s%n", pair.getKeyMaterial()); - - } else if (command.equals("destroy")) { - destroySecurityGroupKeyPairAndInstance(client, name); - } else { - throw new IllegalArgumentException(INVALID_SYNTAX); - } - } finally { - // Close connecton - context.close(); - System.exit(0); - } - - } - - private static void destroySecurityGroupKeyPairAndInstance(EC2Client client, String name) { - try { - String id = findInstanceByKeyName(client, name).getId(); - System.out.printf("%d: %s terminating instance%n", System.currentTimeMillis(), id); - client.getInstanceServices().terminateInstancesInRegion(null, findInstanceByKeyName(client, name).getId()); - } catch (NoSuchElementException e) { - } catch (Exception e) { - e.printStackTrace(); - } - - try { - System.out.printf("%d: %s deleting keypair%n", System.currentTimeMillis(), name); - client.getKeyPairServices().deleteKeyPairInRegion(null, name); - } catch (Exception e) { - e.printStackTrace(); - } - - try { - System.out.printf("%d: %s deleting group%n", System.currentTimeMillis(), name); - client.getSecurityGroupServices().deleteSecurityGroupInRegion(null, name); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static RunningInstance createSecurityGroupKeyPairAndInstance(EC2Client client, String name) - throws TimeoutException { - // create a new security group - createSecurityGroupAndAuthorizePorts(client, name); - - // create a new instance - RunningInstance instance = runInstance(client, name, name); - - // await for the instance to start - return blockUntilInstanceRunning(client, instance); - } - - static void createSecurityGroupAndAuthorizePorts(EC2Client client, String name) { - System.out.printf("%d: creating security group: %s%n", System.currentTimeMillis(), name); - client.getSecurityGroupServices().createSecurityGroupInRegion(null, name, name); - for (int port : new int[] { 80, 8080, 443, 22 }) { - client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(null, name, IpProtocol.TCP, port, - port, "0.0.0.0/0"); - } - } - - static KeyPair createKeyPair(EC2Client client, String name) { - System.out.printf("%d: creating keypair: %s%n", System.currentTimeMillis(), name); - return client.getKeyPairServices().createKeyPairInRegion(null, name); - } - - static RunningInstance runInstance(EC2Client client, String securityGroupName, String keyPairName) { - String script = new ScriptBuilder() // lamp install script - .addStatement(exec("runurl run.alestic.com/apt/upgrade"))// - .addStatement(exec("runurl run.alestic.com/install/lamp"))// - .addStatement(exec("apt-get -y install openjdk-6-jdk"))// no license agreement! - .render(OsFamily.UNIX); - - System.out.printf("%d: running instance%n", System.currentTimeMillis()); - Reservation reservation = client.getInstanceServices().runInstancesInRegion(null, null, // allow - // ec2 - // to - // chose - // an - // availability - // zone - "ami-ccf615a5", // alestic ami allows auto-invoke of user data scripts - 1, // minimum instances - 1, // maximum instances - asType(InstanceType.M1_SMALL) // smallest instance size - .withKeyName(keyPairName) // key I created above - .withSecurityGroup(securityGroupName) // group I created above - .withUserData(script.getBytes())); // script to run as root - - return Iterables.getOnlyElement(reservation); - - } - - static RunningInstance blockUntilInstanceRunning(EC2Client client, RunningInstance instance) throws TimeoutException { - // create utilities that wait for the instance to finish - RetryablePredicate runningTester = new RetryablePredicate( - new InstanceStateRunning(client), 180, 5, TimeUnit.SECONDS); - - System.out.printf("%d: %s awaiting instance to run %n", System.currentTimeMillis(), instance.getId()); - if (!runningTester.apply(instance)) - throw new TimeoutException("timeout waiting for instance to run: " + instance.getId()); - - instance = findInstanceById(client, instance.getId()); - - RetryablePredicate socketTester = new RetryablePredicate(new InetSocketAddressConnect(), 300, - 1, TimeUnit.SECONDS); - System.out.printf("%d: %s awaiting ssh service to start%n", System.currentTimeMillis(), instance.getIpAddress()); - if (!socketTester.apply(new IPSocket(instance.getIpAddress(), 22))) - throw new TimeoutException("timeout waiting for ssh to start: " + instance.getIpAddress()); - - System.out.printf("%d: %s ssh service started%n", System.currentTimeMillis(), instance.getIpAddress()); - - System.out.printf("%d: %s awaiting http service to start%n", System.currentTimeMillis(), instance.getIpAddress()); - if (!socketTester.apply(new IPSocket(instance.getIpAddress(), 80))) - throw new TimeoutException("timeout waiting for http to start: " + instance.getIpAddress()); - - System.out.printf("%d: %s http service started%n", System.currentTimeMillis(), instance.getIpAddress()); - return instance; - } - - private static RunningInstance findInstanceById(EC2Client client, String instanceId) { - // search my account for the instance I just created - Set> reservations = client.getInstanceServices() - .describeInstancesInRegion(null, instanceId); // last parameter (ids) narrows the - // search - - // since we refined by instanceId there should only be one instance - return Iterables.getOnlyElement(Iterables.getOnlyElement(reservations)); - } - - private static RunningInstance findInstanceByKeyName(EC2Client client, final String keyName) { - // search my account for the instance I just created - Set> reservations = client.getInstanceServices() - .describeInstancesInRegion(null); - - // extract all the instances from all reservations - Set allInstances = Sets.newHashSet(); - for (Reservation reservation : reservations) { - allInstances.addAll(reservation); - } - - // get the first one that has a keyname matching what I just created - return Iterables.find(allInstances, new Predicate() { - - @Override - public boolean apply(RunningInstance input) { - return input.getKeyName().equals(keyName) && input.getInstanceState() != InstanceState.TERMINATED; - } - - }); - } -} diff --git a/demos/gae-tweetstore-spring/pom.xml b/demos/gae-tweetstore-spring/pom.xml index d365f311e6..cf56a469e1 100644 --- a/demos/gae-tweetstore-spring/pom.xml +++ b/demos/gae-tweetstore-spring/pom.xml @@ -79,7 +79,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/demos/gae-tweetstore/pom.xml b/demos/gae-tweetstore/pom.xml index a5cbe31c37..22ccd2ecd3 100644 --- a/demos/gae-tweetstore/pom.xml +++ b/demos/gae-tweetstore/pom.xml @@ -20,15 +20,12 @@ 4.0.0 - - org.jclouds - jclouds-demos-project - 1.0-SNAPSHOT - - jclouds-demo-gae-tweetstore + org.jclouds.demos + gae-replicator + 1.0-SNAPSHOT war - JClouds TweetStore for Google App Engine - JClouds TweetStore for Google App Engine + JClouds example to replicate the contents of a container + JClouds example to replicate the contents of a container YOUR_APPENGINE_HOME - jclouds-tweetstore + jclouds-replicate localhost 8088 - cloudfiles,googlestorage,s3,azureblob - jclouds-tweetstore + googlestorage + cloudfiles-us,aws-s3,azureblob + jclouds-replicate - - org.twitter4j - twitter4j-core - [2.1,) - ${project.groupId} - jclouds-blobstore + jclouds-allblobstore ${project.version} @@ -77,33 +70,18 @@ log4j log4j - 1.2.14 + 1.2.16 test - org.jclouds.provider - aws-s3 - ${project.version} - - - ${project.groupId} - jclouds-azure - ${project.version} - - - ${project.groupId} - jclouds-rackspace - ${project.version} - - - ${project.groupId} - jclouds-gae + org.jclouds.driver + gae ${project.version} com.google.code.guice guice-servlet - 3.0-snapshot-20101120 + 3.0-RC2 displaytag @@ -132,35 +110,62 @@ javax.servlet 1.1.2 - - org.apache.geronimo.specs - geronimo-el_1.0_spec - 1.0.1 - - - org.apache.geronimo.specs - geronimo-jsp_2.1_spec - 1.0.1 - provided - - - org.apache.geronimo.specs - geronimo-servlet_2.5_spec - 1.2 - provided - - - com.google.appengine - appengine-api-labs - 1.3.5 - - - com.google.appengine - appengine-tools-api - 1.3.5 - system - ${appengine.home}/lib/appengine-tools-api.jar - + + + + com.google.appengine + appengine-api-1.0-sdk + 1.4.2 + + + + + org.apache.geronimo.specs + geronimo-jta_1.1_spec + 1.1.1 + runtime + + + + org.apache.geronimo.specs + geronimo-jpa_3.0_spec + 1.1.1 + runtime + + + + com.google.appengine.orm + jdo2-api + 2.3-eb + runtime + + + + org.datanucleus + datanucleus-core + 1.1.5 + + + + com.google.appengine.orm + datanucleus-appengine + 1.0.8 + runtime + + + + org.datanucleus + datanucleus-jpa + 1.1.5 + runtime + + + + + com.google.appengine + appengine-tools-sdk + 1.4.2 + ${project.artifactId} @@ -237,14 +242,6 @@ - - test.twitter.identity - ${test.twitter.identity} - - - test.twitter.credential - ${test.twitter.credential} - test.azureblob.identity ${test.azureblob.identity} @@ -254,20 +251,20 @@ ${test.azureblob.credential} - test.cloudfiles.identity - ${test.cloudfiles.identity} + test.cloudfiles-us.identity + ${test.cloudfiles-us.identity} - test.cloudfiles.credential - ${test.cloudfiles.credential} + test.cloudfiles-us.credential + ${test.cloudfiles-us.credential} - test.s3.identity - ${test.s3.identity} + test.aws-s3.identity + ${test.aws-s3.identity} - test.s3.credential - ${test.s3.credential} + test.aws-s3.credential + ${test.aws-s3.credential} test.googlestorage.identity @@ -290,12 +287,16 @@ ${devappserver.port} - jclouds.tweetstore.blobstores - ${jclouds.tweetstore.blobstores} + jclouds.replicate.source + ${jclouds.replicate.source} - jclouds.tweetstore.container - ${jclouds.tweetstore.container} + jclouds.replicate.destinations + ${jclouds.replicate.destinations} + + + jclouds.replicate.container + ${jclouds.replicate.container} warfile diff --git a/demos/getpath/pom.xml b/demos/getpath/pom.xml index 887595ce98..192a73e6ee 100644 --- a/demos/getpath/pom.xml +++ b/demos/getpath/pom.xml @@ -52,7 +52,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/demos/googleappengine/README.md b/demos/googleappengine/README.md new file mode 100755 index 0000000000..2600e1822f --- /dev/null +++ b/demos/googleappengine/README.md @@ -0,0 +1,28 @@ +# googleappengine +This example will list the current instances and buckets in your Amazon account, using portable apis. This example runs inside Google AppEngine as a war file. + +## Prepare + +Please unzip http://googleappengine.googlecode.com/files/appengine-java-sdk-1.4.0.zip and export the system variable APPENGINE_HOME accordingly. + +## Build + +To install your test on your remote appengine application, first prepare locally via the below instructions: +mvn -Dappengine.applicationid=YOUR_APPLICATION -Dtest.aws.identity=YOUR_ACCESS_KEY_ID -Dtest.aws.credential=YOUR_SECRET_KEY -Plive install + +## Deploy + +then, you can upload this to google appengine like below: +appcfg.sh -e YOUR_EMAIL update target//jclouds-googleappengine-example + +## Test + +finally, you can verify with a web url: +http://YOUR_APPLICATION_ID.appspot.com/guice/status.check + +## License + +Copyright (C) 2011 Cloud Conscious, LLC. + +Licensed under the Apache License, Version 2.0 + diff --git a/demos/googleappengine/README.txt b/demos/googleappengine/README.txt deleted file mode 100755 index 8a165a903c..0000000000 --- a/demos/googleappengine/README.txt +++ /dev/null @@ -1,50 +0,0 @@ -==== - - Copyright (C) 2010 Cloud Conscious, LLC. - - ==================================================================== - 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. - ==================================================================== -==== - -This samples uses the Google App Engine for Java SDK located at http://googleappengine.googlecode.com/files/appengine-java-sdk-1.3.5.zip - -Please unzip the above file and modify your maven settings.xml like below before attempting to run 'mvn -Plive install' - - - appengine - - true - - - /path/to/appengine-java-sdk-1.3.5 - - - - - aws - - true - - - YOUR_ACCESS_KEY_ID - YOUR_SECRET_KEY - - - - - - jclouds - http://jclouds.googlecode.com/svn/trunk/repo - - diff --git a/demos/googleappengine/pom.xml b/demos/googleappengine/pom.xml index b952dff489..38ac68ee88 100644 --- a/demos/googleappengine/pom.xml +++ b/demos/googleappengine/pom.xml @@ -24,35 +24,54 @@ 4.0.0 org.jclouds - demos-project + jclouds-project 1.0-SNAPSHOT + ../../project/pom.xml - googleappengine + org.jclouds.examples + 1.0-SNAPSHOT + jclouds-googleappengine-example war JClouds Sample for Google App Engine JClouds Sample for Google App Engine - - YOUR_APPENGINE_HOME - aws-common-demo + jclouds-aws-demo localhost 8088 + + + org.jclouds + jclouds-blobstore + ${project.version} + + + org.jclouds + jclouds-compute + ${project.version} + + + org.jclouds.provider + aws-s3 + ${project.version} + + + org.jclouds.provider + aws-ec2 + ${project.version} + org.jclouds.driver jclouds-gae ${project.version} - com.google.code.guice + com.google.inject.extensions guice-servlet - 3.0-snapshot-20101120 + 3.0-rc2 displaytag @@ -100,10 +119,10 @@ com.google.appengine - appengine-tools-api - 1.3.5 + appengine-tools-sdk + 1.4.0 system - ${appengine.home}/lib/appengine-tools-api.jar + ${env.APPENGINE_HOME}/lib/appengine-tools-api.jar @@ -134,10 +153,6 @@ - - appengine.home - ${appengine.home} - devappserver.address ${devappserver.address} @@ -152,14 +167,13 @@ - ${appengine.home}/lib/appengine-tools-api.jar - + ${env.APPENGINE_HOME}/lib/appengine-tools-api.jar true - ${appengine.home}/bin - ${appengine.home}/lib - ${appengine.home}/config/sdk + ${env.APPENGINE_HOME}/bin + ${env.APPENGINE_HOME}/lib + ${env.APPENGINE_HOME}/config/sdk @@ -186,16 +200,16 @@ - jclouds.test.identity + test.aws.identity ${test.aws.identity} - jclouds.test.credential + test.aws.credential ${test.aws.credential} - appengine.home - ${appengine.home} + appengine.sdk.root + ${env.APPENGINE_HOME} devappserver.address diff --git a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/GetAllStatusController.java b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/GetAllStatusController.java index aa43ab0a1e..0d9d323432 100755 --- a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/GetAllStatusController.java +++ b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/GetAllStatusController.java @@ -20,7 +20,6 @@ package org.jclouds.samples.googleappengine; import java.io.IOException; -import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -39,11 +38,12 @@ import org.jclouds.logging.Logger; import org.jclouds.samples.googleappengine.functions.BlobStoreContextToStatusResult; import org.jclouds.samples.googleappengine.functions.ComputeServiceContextToStatusResult; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; /** - * Shows an example of how to use @{link BlobStoreContext} injected with Guice. + * Shows an example of how to use {@link BlobStoreContext} and {@link ComputeServiceContext} + * injected with Guice. * * @author Adrian Cole */ @@ -51,8 +51,8 @@ import com.google.common.collect.Sets; public class GetAllStatusController extends HttpServlet { private static final long serialVersionUID = 1L; - private final Map blobsStoreContexts; - private final Map computeServiceContexts; + private final Iterable blobsStoreContexts; + private final Iterable computeServiceContexts; private final BlobStoreContextToStatusResult blobStoreContextToContainerResult; private final ComputeServiceContextToStatusResult computeServiceContextToContainerResult; @@ -60,10 +60,10 @@ public class GetAllStatusController extends HttpServlet { protected Logger logger = Logger.NULL; @Inject - GetAllStatusController(Map blobsStoreContexts, - Map computeServiceContexts, - BlobStoreContextToStatusResult blobStoreContextToContainerResult, - ComputeServiceContextToStatusResult computeServiceContextToContainerResult) { + GetAllStatusController(Iterable blobsStoreContexts, + Iterable computeServiceContexts, + BlobStoreContextToStatusResult blobStoreContextToContainerResult, + ComputeServiceContextToStatusResult computeServiceContextToContainerResult) { this.blobsStoreContexts = blobsStoreContexts; this.computeServiceContexts = computeServiceContexts; this.blobStoreContextToContainerResult = blobStoreContextToContainerResult; @@ -71,12 +71,10 @@ public class GetAllStatusController extends HttpServlet { } @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { addStatusResultsToRequest(request); - RequestDispatcher dispatcher = getServletContext().getRequestDispatcher( - "/WEB-INF/jsp/status.jsp"); + RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/status.jsp"); dispatcher.forward(request, response); } catch (Exception e) { logger.error(e, "Error listing status"); @@ -84,12 +82,13 @@ public class GetAllStatusController extends HttpServlet { } } - private void addStatusResultsToRequest(HttpServletRequest request) throws InterruptedException, - ExecutionException, TimeoutException { - request.setAttribute("status", Sets - .newTreeSet(Iterables.concat(Iterables.transform(blobsStoreContexts.keySet(), - blobStoreContextToContainerResult), Iterables.transform( - computeServiceContexts.keySet(), computeServiceContextToContainerResult)))); + private void addStatusResultsToRequest(HttpServletRequest request) throws InterruptedException, ExecutionException, + TimeoutException { + request.setAttribute( + "status", + ImmutableSet.copyOf(Iterables.concat( + Iterables.transform(blobsStoreContexts, blobStoreContextToContainerResult), + Iterables.transform(computeServiceContexts, computeServiceContextToContainerResult)))); } } \ No newline at end of file diff --git a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java index 6614c7dcc1..99dd911334 100755 --- a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java +++ b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/config/GuiceServletConfig.java @@ -26,7 +26,6 @@ import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIM import java.io.IOException; import java.io.InputStream; -import java.util.Map; import java.util.Properties; import javax.servlet.ServletContextEvent; @@ -35,10 +34,9 @@ import org.jclouds.blobstore.BlobStoreContext; import org.jclouds.blobstore.BlobStoreContextFactory; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; -import org.jclouds.gae.config.GoogleAppEngineConfigurationModule; +import org.jclouds.gae.config.AsyncGoogleAppEngineConfigurationModule; import org.jclouds.samples.googleappengine.GetAllStatusController; -import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.io.Closeables; import com.google.inject.Guice; @@ -49,14 +47,14 @@ import com.google.inject.servlet.GuiceServletContextListener; import com.google.inject.servlet.ServletModule; /** - * Setup Logging and create Injector for use in testing S3. + * Setup Logging and create {@link Injector} for use in testing Amazon EC2 and S3. * * @author Adrian Cole */ public class GuiceServletConfig extends GuiceServletContextListener { - private Map blobsStoreContexts; - private Map computeServiceContexts; + private Iterable blobsStoreContexts; + private Iterable computeServiceContexts; @Override public void contextInitialized(ServletContextEvent servletContextEvent) { @@ -66,20 +64,19 @@ public class GuiceServletConfig extends GuiceServletContextListener { props.setProperty(PROPERTY_TIMEOUT_SCRIPT_COMPLETE, "25000"); props.setProperty(PROPERTY_TIMEOUT_PORT_OPEN, "25000"); - ImmutableSet modules = ImmutableSet - . of(new GoogleAppEngineConfigurationModule()); + // note that this module hooks into the async urlfetchservice + ImmutableSet modules = ImmutableSet. of(new AsyncGoogleAppEngineConfigurationModule()); - blobsStoreContexts = ImmutableMap. of("s3", - new BlobStoreContextFactory().createContext("s3", modules, props)); - computeServiceContexts = ImmutableMap. of("ec2", - new ComputeServiceContextFactory().createContext("ec2", modules, props)); + blobsStoreContexts = ImmutableSet. of(new BlobStoreContextFactory().createContext("aws-s3", + modules, props)); + computeServiceContexts = ImmutableSet. of(new ComputeServiceContextFactory() + .createContext("aws-ec2", modules, props)); super.contextInitialized(servletContextEvent); } private Properties loadJCloudsProperties(ServletContextEvent servletContextEvent) { - InputStream input = servletContextEvent.getServletContext().getResourceAsStream( - "/WEB-INF/jclouds.properties"); + InputStream input = servletContextEvent.getServletContext().getResourceAsStream("/WEB-INF/jclouds.properties"); Properties props = new Properties(); try { props.load(input); @@ -96,9 +93,9 @@ public class GuiceServletConfig extends GuiceServletContextListener { return Guice.createInjector(new ServletModule() { @Override protected void configureServlets() { - bind(new TypeLiteral>() { + bind(new TypeLiteral>() { }).toInstance(GuiceServletConfig.this.blobsStoreContexts); - bind(new TypeLiteral>() { + bind(new TypeLiteral>() { }).toInstance(GuiceServletConfig.this.computeServiceContexts); serve("*.check").with(GetAllStatusController.class); requestInjection(this); @@ -110,10 +107,10 @@ public class GuiceServletConfig extends GuiceServletContextListener { @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { - for (BlobStoreContext context : blobsStoreContexts.values()) { + for (BlobStoreContext context : blobsStoreContexts) { context.close(); } - for (ComputeServiceContext context : computeServiceContexts.values()) { + for (ComputeServiceContext context : computeServiceContexts) { context.close(); } super.contextDestroyed(servletContextEvent); diff --git a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/BlobStoreContextToStatusResult.java b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/BlobStoreContextToStatusResult.java index 042d325e6f..0bfffed3d7 100755 --- a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/BlobStoreContextToStatusResult.java +++ b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/BlobStoreContextToStatusResult.java @@ -19,79 +19,39 @@ package org.jclouds.samples.googleappengine.functions; -import java.util.Map; - import javax.annotation.Resource; -import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.blobstore.ContainerNotFoundException; -import org.jclouds.blobstore.domain.StorageMetadata; -import org.jclouds.blobstore.domain.StorageType; import org.jclouds.logging.Logger; import org.jclouds.samples.googleappengine.domain.StatusResult; import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; +/** + * + * @author Adrian Cole + */ @Singleton -public class BlobStoreContextToStatusResult implements Function { - private final class BuildContainerResult implements Function { - private final String host; - private final BlobStoreContext context; - private final String contextName; - - private BuildContainerResult(String host, BlobStoreContext context, String contextName) { - this.host = host; - this.context = context; - this.contextName = contextName; - } - - public StatusResult apply(StorageMetadata from) { - String status; - try { - try { - long start = System.currentTimeMillis(); - context.getBlobStore().containerExists(from.getName()); - status = ((System.currentTimeMillis() - start) + "ms"); - } catch (ContainerNotFoundException ex) { - status = ("not found"); - } - } catch (Exception e) { - logger.error(e, "Error listing container %s//%s", contextName, from); - status = (e.getMessage()); - } - return new StatusResult(contextName, host, from.getName(), status); - } - } - - @Inject - private Map contexts; +public class BlobStoreContextToStatusResult implements Function { @Resource protected Logger logger = Logger.NULL; - public StatusResult apply(final String contextName) { - final BlobStoreContext context = contexts.get(contextName); - final String host = context.getProviderSpecificContext().getEndpoint().getHost(); + public StatusResult apply(BlobStoreContext in) { + String host = in.getProviderSpecificContext().getEndpoint().getHost(); + String status; + String name = "not found"; try { - StorageMetadata md = Iterables.getLast(Sets.newTreeSet(Iterables.filter(context - .getBlobStore().list(), new Predicate() { + long start = System.currentTimeMillis(); - public boolean apply(StorageMetadata input) { - return input.getType() == StorageType.CONTAINER; - } + name = String.format("%d containers", in.getBlobStore().list().size()); - }))); - return new BuildContainerResult(host, context, contextName).apply(md); + status = ((System.currentTimeMillis() - start) + "ms"); } catch (Exception e) { - StatusResult result = new StatusResult(contextName, host, null, e.getMessage()); - logger.error(e, "Error listing service %s", contextName); - return result; + logger.error(e, "Error listing context %s", in); + status = (e.getMessage()); } - + return new StatusResult(in.getProviderSpecificContext().getId(), host, name, status); } } \ No newline at end of file diff --git a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/ComputeServiceContextToStatusResult.java b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/ComputeServiceContextToStatusResult.java index 7d58e5954e..255af6fa55 100644 --- a/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/ComputeServiceContextToStatusResult.java +++ b/demos/googleappengine/src/main/java/org/jclouds/samples/googleappengine/functions/ComputeServiceContextToStatusResult.java @@ -19,52 +19,39 @@ package org.jclouds.samples.googleappengine.functions; -import java.util.Map; - import javax.annotation.Resource; -import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.compute.ComputeServiceContext; -import org.jclouds.compute.options.TemplateOptions; import org.jclouds.logging.Logger; import org.jclouds.samples.googleappengine.domain.StatusResult; import com.google.common.base.Function; +/** + * + * @author Adrian Cole + */ @Singleton -public class ComputeServiceContextToStatusResult implements - Function { - - @Inject - private Map contexts; +public class ComputeServiceContextToStatusResult implements Function { @Resource protected Logger logger = Logger.NULL; - public StatusResult apply(final String contextName) { - final ComputeServiceContext context = contexts.get(contextName); - final String host = context.getProviderSpecificContext().getEndpoint() - .getHost(); + public StatusResult apply(ComputeServiceContext in) { + String host = in.getProviderSpecificContext().getEndpoint().getHost(); String status; String name = "not found"; try { long start = System.currentTimeMillis(); - // set options that don't block so that we can avoid - // DeadLineExceededExceptions - TemplateOptions options = context.getComputeService() - .templateOptions().blockUntilRunning(false); - // set the name to the default template to show that - // it works - name = context.getComputeService().templateBuilder().options(options) - .build().toString(); + name = String.format("%d nodes", in.getComputeService().listNodes().size()); status = ((System.currentTimeMillis() - start) + "ms"); } catch (Exception e) { - logger.error(e, "Error listing service %s", contextName); + logger.error(e, "Error listing context %s", in); status = (e.getMessage()); } - return new StatusResult(contextName, host, name, status); + return new StatusResult(in.getProviderSpecificContext().getId(), host, name, status); } } \ No newline at end of file diff --git a/demos/googleappengine/src/main/webapp/WEB-INF/jsp/status.jsp b/demos/googleappengine/src/main/webapp/WEB-INF/jsp/status.jsp index 78d30ff991..3075442c78 100755 --- a/demos/googleappengine/src/main/webapp/WEB-INF/jsp/status.jsp +++ b/demos/googleappengine/src/main/webapp/WEB-INF/jsp/status.jsp @@ -23,7 +23,7 @@ <%@ taglib uri="http://displaytag.sf.net" prefix="display"%> -jclouds: multi-cloud framework +jclouds: multi-cloud library

Status List

diff --git a/demos/googleappengine/src/test/java/org/jclouds/samples/googleappengine/functest/GoogleAppEngineLiveTest.java b/demos/googleappengine/src/test/java/org/jclouds/samples/googleappengine/functest/GoogleAppEngineLiveTest.java index 5c2c73068d..f9066a6d4e 100755 --- a/demos/googleappengine/src/test/java/org/jclouds/samples/googleappengine/functest/GoogleAppEngineLiveTest.java +++ b/demos/googleappengine/src/test/java/org/jclouds/samples/googleappengine/functest/GoogleAppEngineLiveTest.java @@ -33,7 +33,7 @@ import org.testng.annotations.Test; /** * Starts up the Google App Engine for Java Development environment and deploys an application which - * tests S3. + * tests Amazon EC2 and S3. * * @author Adrian Cole */ @@ -49,10 +49,10 @@ public class GoogleAppEngineLiveTest { throws Exception { url = new URL(String.format("http://%s:%s", address, port)); Properties props = new Properties(); - String identity = checkNotNull(System.getProperty("jclouds.test.identity"), - "jclouds.test.identity"); - String credential = checkNotNull(System.getProperty("jclouds.test.credential"), - "jclouds.test.credential"); + String identity = checkNotNull(System.getProperty("test.aws.identity"), + "test.aws.identity"); + String credential = checkNotNull(System.getProperty("test.aws.credential"), + "test.aws.credential"); /** * Since both s3 and ec2 use the same credentials, we can take a shortcut and specify both diff --git a/demos/pom.xml b/demos/pom.xml index 49c2b1d524..9733b74783 100644 --- a/demos/pom.xml +++ b/demos/pom.xml @@ -48,7 +48,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/drivers/apachehc/README.txt b/drivers/apachehc/README.txt new file mode 100644 index 0000000000..3acff509ff --- /dev/null +++ b/drivers/apachehc/README.txt @@ -0,0 +1,24 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# A driver to use the Apache HTTP Components Client (http://hc.apache.org/) +# as an encryption library in jclouds. +# +# TODO: Usage example. \ No newline at end of file diff --git a/drivers/apachehc/pom.xml b/drivers/apachehc/pom.xml index c86a731758..26c4c525b2 100644 --- a/drivers/apachehc/pom.xml +++ b/drivers/apachehc/pom.xml @@ -62,7 +62,8 @@ org.apache.httpcomponents httpclient - 4.0.3 + 4.1 + provided org.mortbay.jetty diff --git a/drivers/bouncycastle/README.txt b/drivers/bouncycastle/README.txt index ab70bc1683..9d9162d972 100644 --- a/drivers/bouncycastle/README.txt +++ b/drivers/bouncycastle/README.txt @@ -18,7 +18,7 @@ ==== # -# An extension to use the Bouncy Castle Crypto API (http://www.bouncycastle.org/) +# A driver to use the Bouncy Castle Crypto API (http://www.bouncycastle.org/) # as an encryption library in jclouds. # # TODO: Usage example. \ No newline at end of file diff --git a/drivers/bouncycastle/pom.xml b/drivers/bouncycastle/pom.xml index 8ee55fba32..7cd9d42566 100644 --- a/drivers/bouncycastle/pom.xml +++ b/drivers/bouncycastle/pom.xml @@ -60,8 +60,9 @@ org.bouncycastle - bcprov-jdk15 - 1.44 + bcprov-jdk16 + 1.45 + provided
diff --git a/drivers/enterprise/README.txt b/drivers/enterprise/README.txt index 4386890ebf..f2d66df88c 100644 --- a/drivers/enterprise/README.txt +++ b/drivers/enterprise/README.txt @@ -18,6 +18,8 @@ ==== # -# Sets up most commonly requested options for enterprise java support +# Sets up most commonly requested options for enterprise Java support. +# +# Expects the joda-time and bcprov JARs (see drivers/joda and drivers/bouncycastle) to be present on your application's classpath. # # TODO: Usage example. diff --git a/drivers/enterprise/pom.xml b/drivers/enterprise/pom.xml index b083011894..f81b2fff6d 100644 --- a/drivers/enterprise/pom.xml +++ b/drivers/enterprise/pom.xml @@ -63,11 +63,21 @@ jclouds-joda ${project.version}
+ + joda-time + joda-time + 1.6.2 + ${project.groupId} jclouds-bouncycastle ${project.version} + + org.bouncycastle + bcprov-jdk15 + 1.44 + org.mortbay.jetty jetty-ssl diff --git a/drivers/gae/README.txt b/drivers/gae/README.txt index 8726f7b8e3..f54e2cbcad 100644 --- a/drivers/gae/README.txt +++ b/drivers/gae/README.txt @@ -18,6 +18,8 @@ ==== # -# An extension to run jclouds on Google App Engine (http://code.google.com/appengine/). +# A driver to run jclouds on Google App Engine (http://code.google.com/appengine/). +# +# Expects the joda-time JAR (see drivers/joda) to be present on your application's classpath. # # TODO: Usage example. diff --git a/drivers/gae/pom.xml b/drivers/gae/pom.xml index dfecd54e23..4711e68040 100644 --- a/drivers/gae/pom.xml +++ b/drivers/gae/pom.xml @@ -49,6 +49,12 @@ jclouds-core ${project.version} + + com.google.appengine + appengine-api-1.0-sdk + 1.4.0 + + org.jclouds jclouds-core @@ -57,42 +63,20 @@ test - ${project.groupId} - jclouds-joda - ${project.version} - - - com.google.appengine - appengine-api - 1.3.5 + org.mortbay.jetty + jetty-ssl + test com.google.appengine appengine-api-stubs - 1.3.5 + 1.4.0 test com.google.appengine appengine-testing - 1.3.5 - test - - - com.google.appengine - appengine-local-runtime - 1.3.5 - test - - - org.apache.geronimo.specs - geronimo-servlet_2.5_spec - 1.2 - test - - - org.mortbay.jetty - jetty-ssl + 1.4.0 test diff --git a/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java b/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java index 11acb412d0..5c3784e936 100644 --- a/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java +++ b/drivers/gae/src/main/java/org/jclouds/gae/config/GoogleAppEngineConfigurationModule.java @@ -25,7 +25,6 @@ import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; -import org.jclouds.date.joda.config.JodaDateServiceModule; import org.jclouds.gae.GaeHttpCommandExecutorService; import org.jclouds.http.HttpCommandExecutorService; import org.jclouds.http.TransformingHttpCommandExecutorService; @@ -54,7 +53,6 @@ public class GoogleAppEngineConfigurationModule extends ExecutorServiceModule { @Override protected void configure() { super.configure(); - install(new JodaDateServiceModule()); bind(TransformingHttpCommandExecutorService.class).to(TransformingHttpCommandExecutorServiceImpl.class); } diff --git a/drivers/joda/README.txt b/drivers/joda/README.txt index 30ec94fbb1..ab9c5234bd 100644 --- a/drivers/joda/README.txt +++ b/drivers/joda/README.txt @@ -18,7 +18,7 @@ ==== # -# An extension to use Joda (http://joda-time.sourceforge.net/) as a time and date library +# A driver to use Joda (http://joda-time.sourceforge.net/) as a time and date library # in jclouds. # # TODO: Usage example. \ No newline at end of file diff --git a/drivers/joda/pom.xml b/drivers/joda/pom.xml index 012ca0b3f7..d4bbe07fa4 100644 --- a/drivers/joda/pom.xml +++ b/drivers/joda/pom.xml @@ -61,7 +61,8 @@ joda-time joda-time - 1.6 + 1.6.2 + provided diff --git a/drivers/jsch/README.txt b/drivers/jsch/README.txt index 1bca4fb8c3..48c3e2eee0 100644 --- a/drivers/jsch/README.txt +++ b/drivers/jsch/README.txt @@ -18,7 +18,7 @@ ==== # -# An extension to use JSch (http://www.jcraft.com/jsch/) as the SSH connection provider +# A driver to use JSch (http://www.jcraft.com/jsch/) as the SSH connection provider # for jclouds. # # TODO: Usage example. \ No newline at end of file diff --git a/drivers/jsch/pom.xml b/drivers/jsch/pom.xml index f5323ee021..64470f518e 100644 --- a/drivers/jsch/pom.xml +++ b/drivers/jsch/pom.xml @@ -43,6 +43,13 @@ true + + jsch + http://jsch.sourceforge.net/maven2 + + false + + @@ -66,7 +73,8 @@ com.jcraft jsch - 0.1.42 + 0.1.44 + provided commons-io diff --git a/drivers/log4j/README.txt b/drivers/log4j/README.txt index 4539b3f32c..b124f0adbf 100644 --- a/drivers/log4j/README.txt +++ b/drivers/log4j/README.txt @@ -18,7 +18,7 @@ ==== # -# An extension to use Log4j (http://logging.apache.org/log4j/) as the logging provider +# A driver to use Log4j (http://logging.apache.org/log4j/) as the logging provider # for jclouds. # # Expects log4j to be present on your application's classpath. diff --git a/drivers/log4j/pom.xml b/drivers/log4j/pom.xml index bb73b46d65..bd02d573c1 100644 --- a/drivers/log4j/pom.xml +++ b/drivers/log4j/pom.xml @@ -61,7 +61,8 @@ log4j log4j - 1.2.14 + 1.2.16 + provided diff --git a/git b/git deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/loadbalancer/pom.xml b/loadbalancer/pom.xml index c2497cc0b3..0436777819 100644 --- a/loadbalancer/pom.xml +++ b/loadbalancer/pom.xml @@ -71,7 +71,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java b/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java index 9438b69af5..3f86e3a9ad 100644 --- a/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java +++ b/loadbalancer/src/test/java/org/jclouds/loadbalancer/BaseLoadBalancerServiceLiveTest.java @@ -60,7 +60,7 @@ import com.google.inject.Module; public abstract class BaseLoadBalancerServiceLiveTest { protected SshClient.Factory sshFactory; - protected String tag; + protected String group; protected RetryablePredicate socketTester; protected Set nodes; @@ -126,8 +126,8 @@ public abstract class BaseLoadBalancerServiceLiveTest { @BeforeGroups(groups = { "integration", "live" }) public void setupClient() throws InterruptedException, ExecutionException, TimeoutException, IOException { setServiceDefaults(); - if (tag == null) - tag = checkNotNull(provider, "provider"); + if (group == null) + group = checkNotNull(provider, "provider"); setupCredentials(); initializeContext(); initializeComputeContext(); @@ -166,7 +166,7 @@ public abstract class BaseLoadBalancerServiceLiveTest { @BeforeGroups(groups = { "integration", "live" }, dependsOnMethods = "setupClient") public void createNodes() throws RunNodesException { try { - nodes = computeContext.getComputeService().runNodesWithTag(tag, 2); + nodes = computeContext.getComputeService().createNodesInGroup(group, 2); } catch (RunNodesException e) { nodes = e.getSuccessfulNodes(); throw e; @@ -177,7 +177,7 @@ public abstract class BaseLoadBalancerServiceLiveTest { public void testLoadBalanceNodesMatching() throws Exception { // create load balancers - loadbalancer = context.getLoadBalancerService().createLoadBalancerInLocation(null, tag, "HTTP", 80, 80, nodes); + loadbalancer = context.getLoadBalancerService().createLoadBalancerInLocation(null, group, "HTTP", 80, 80, nodes); assertNotNull(loadbalancer); validateNodesInLoadBalancer(); @@ -197,7 +197,7 @@ public abstract class BaseLoadBalancerServiceLiveTest { context.getLoadBalancerService().destroyLoadBalancer(loadbalancer.getId()); } if (nodes != null) { - computeContext.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); + computeContext.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group)); } computeContext.close(); context.close(); diff --git a/project/pom.xml b/project/pom.xml index 925202af67..a78fef39f2 100644 --- a/project/pom.xml +++ b/project/pom.xml @@ -86,9 +86,16 @@ - jclouds-rimu-snapshots-nexus - http://jclouds.rimuhosting.com/nexus/content/repositories/snapshots - + sonatype-nexus-snapshots + https://oss.sonatype.org/content/repositories/snapshots + + true + + + + googlecode.java-xmlbuilder + http://java-xmlbuilder.googlecode.com/svn/repo + false @@ -221,23 +228,23 @@ 2.4 test
- - org.clojure - clojure - 1.2.0 - true - - - org.clojure - clojure-contrib - 1.2.0 - true - - com.github.technomancy - swank-clojure - 1.2.1 - test + org.clojure + clojure + 1.2.0 + true + + + org.clojure + clojure-contrib + 1.2.0 + true + + + com.github.technomancy + swank-clojure + 1.2.1 + test @@ -379,7 +386,7 @@ - -J-Xmx128m + -J-Xmx256m ${project.build.sourceEncoding} true @@ -598,14 +605,15 @@ pageTracker._trackPageview(); true src-descriptor.xml - jar-with-dependencies-descriptor.xml + provided-dependencies-descriptor.xml + jar-with-dependencies-no-core-no-apis-descriptor.xml - ${project.groupId} + org.jclouds jclouds-assemblies ${project.version} diff --git a/providers/aws-ec2/README.txt b/providers/aws-ec2/README.txt new file mode 100644 index 0000000000..3b176f44ff --- /dev/null +++ b/providers/aws-ec2/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Amazon's EC2 (http://aws.amazon.com/ec2/). +# +# Expects the jclouds ec2 API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. diff --git a/providers/aws-ec2/pom.xml b/providers/aws-ec2/pom.xml index 9eb1731b09..c3b80283db 100644 --- a/providers/aws-ec2/pom.xml +++ b/providers/aws-ec2/pom.xml @@ -85,6 +85,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2AsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2AsyncClient.java new file mode 100644 index 0000000000..c556e487f7 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2AsyncClient.java @@ -0,0 +1,63 @@ +package org.jclouds.aws.ec2; + +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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. + * ==================================================================== + */ + +import org.jclouds.aws.ec2.services.AWSAMIAsyncClient; +import org.jclouds.aws.ec2.services.AWSInstanceAsyncClient; +import org.jclouds.aws.ec2.services.MonitoringAsyncClient; +import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides asynchronous access to EC2 services. + * + * @author Adrian Cole + */ +public interface AWSEC2AsyncClient extends EC2AsyncClient { + public final static String VERSION = "2010-06-15"; + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSInstanceAsyncClient getInstanceServices(); + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSAMIAsyncClient getAMIServices(); + + /** + * Provides asynchronous access to PlacementGroup services. + */ + @Delegate + PlacementGroupAsyncClient getPlacementGroupServices(); + + /** + * Provides asynchronous access to Monitoring services. + */ + @Delegate + MonitoringAsyncClient getMonitoringServices(); + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Client.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Client.java new file mode 100644 index 0000000000..8bd8ea53f7 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2Client.java @@ -0,0 +1,66 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.aws.ec2.services.AWSAMIClient; +import org.jclouds.aws.ec2.services.AWSInstanceClient; +import org.jclouds.aws.ec2.services.MonitoringClient; +import org.jclouds.aws.ec2.services.PlacementGroupClient; +import org.jclouds.concurrent.Timeout; +import org.jclouds.ec2.EC2Client; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides synchronous access to EC2 services. + * + * @author Adrian Cole + */ +@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS) +public interface AWSEC2Client extends EC2Client { + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSInstanceClient getInstanceServices(); + + /** + * {@inheritDoc} + */ + @Delegate + @Override + AWSAMIClient getAMIServices(); + + /** + * Provides synchronous access to PlacementGroup services. + */ + @Delegate + PlacementGroupClient getPlacementGroupServices(); + + /** + * Provides synchronous access to Monitoring services. + */ + @Delegate + MonitoringClient getMonitoringServices(); + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java index d92b6632fd..94430969a4 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java @@ -22,7 +22,8 @@ package org.jclouds.aws.ec2; import java.util.List; import java.util.Properties; -import org.jclouds.aws.ec2.config.AWSEC2ComputeServiceContextModule; +import org.jclouds.aws.ec2.compute.config.AWSEC2ComputeServiceContextModule; +import org.jclouds.aws.ec2.config.AWSEC2RestClientModule; import org.jclouds.ec2.EC2ContextBuilder; import com.google.inject.Module; @@ -37,6 +38,11 @@ public class AWSEC2ContextBuilder extends EC2ContextBuilder { super(props); } + @Override + protected void addClientModule(List modules) { + modules.add(new AWSEC2RestClientModule()); + } + @Override protected void addContextModule(List modules) { modules.add(new AWSEC2ComputeServiceContextModule()); diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java index 5a76413779..2159011596 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java @@ -19,13 +19,17 @@ package org.jclouds.aws.ec2; +import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.aws.domain.Region.AP_SOUTHEAST_1; import static org.jclouds.aws.domain.Region.EU_WEST_1; import static org.jclouds.aws.domain.Region.US_EAST_1; import static org.jclouds.aws.domain.Region.US_WEST_1; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_NODE_SUSPENDED; import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; -import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_CC_AMIs; +import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.util.Properties; @@ -40,11 +44,17 @@ import com.google.common.collect.ImmutableSet; * @author Adrian Cole */ public class AWSEC2PropertiesBuilder extends org.jclouds.ec2.EC2PropertiesBuilder { - public static Set DEFAULT_REGIONS = ImmutableSet.of(EU_WEST_1, US_EAST_1, US_WEST_1, AP_SOUTHEAST_1); + public static Set DEFAULT_REGIONS = ImmutableSet.of(US_EAST_1, US_WEST_1, EU_WEST_1, AP_SOUTHEAST_1); @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-VA,US-CA,IE,SG"); + properties.setProperty(PROPERTY_REGION + "." + US_EAST_1 + "." + ISO3166_CODES, "US-VA"); + properties.setProperty(PROPERTY_REGION + "." + US_WEST_1 + "." + ISO3166_CODES, "US-CA"); + properties.setProperty(PROPERTY_REGION + "." + EU_WEST_1 + "." + ISO3166_CODES, "IE"); + properties.setProperty(PROPERTY_REGION + "." + AP_SOUTHEAST_1 + "." + ISO3166_CODES, "SG"); + // 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 @@ -54,6 +64,7 @@ public class AWSEC2PropertiesBuilder extends org.jclouds.ec2.EC2PropertiesBuilde properties.setProperty("jclouds.ssh.max_retries", "7"); properties.setProperty("jclouds.ssh.retryable_messages", "Auth fail,invalid data,End of IO Stream Read,Connection reset,socket is not established"); + properties.setProperty(PROPERTY_ENDPOINT, "https://ec2.us-east-1.amazonaws.com"); properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(DEFAULT_REGIONS)); // amazon, alestic, canonical, and rightscale properties.setProperty(PROPERTY_EC2_AMI_OWNERS, "137112412989,063491364108,099720109477,411009282317"); diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java new file mode 100644 index 0000000000..57247c8ad1 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java @@ -0,0 +1,136 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute; + +import static com.google.common.base.Preconditions.checkState; + +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.concurrent.ExecutorService; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; + +import org.jclouds.Constants; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; +import org.jclouds.collect.Memoized; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; +import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetNodeMetadataStrategy; +import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; +import org.jclouds.compute.strategy.ListNodesStrategy; +import org.jclouds.compute.strategy.RebootNodeStrategy; +import org.jclouds.compute.strategy.ResumeNodeStrategy; +import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; +import org.jclouds.compute.strategy.SuspendNodeStrategy; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.ec2.compute.EC2ComputeService; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.util.Preconditions2; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; + +/** + * @author Adrian Cole + */ +@Singleton +public class AWSEC2ComputeService extends EC2ComputeService { + + private final Map placementGroupMap; + private final Predicate placementGroupDeleted; + private final AWSEC2Client ec2Client; + + @Inject + protected AWSEC2ComputeService(ComputeServiceContext context, Map credentialStore, + @Memoized Supplier> images, @Memoized Supplier> sizes, + @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, + GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, + RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, + ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy, + Provider templateBuilderProvider, Provider templateOptionsProvider, + @Named("NODE_RUNNING") Predicate nodeRunning, + @Named("NODE_TERMINATED") Predicate nodeTerminated, + @Named("NODE_SUSPENDED") Predicate nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, Timeouts timeouts, + @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, AWSEC2Client ec2Client, + Map credentialsMap, @Named("SECURITY") Map securityGroupMap, + @Named("PLACEMENT") Map placementGroupMap, + @Named("DELETED") Predicate placementGroupDeleted) { + super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, + runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, + stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, + nodeSuspended, initScriptRunnerFactory, timeouts, executor, ec2Client, credentialsMap, securityGroupMap); + this.ec2Client = ec2Client; + this.placementGroupMap = placementGroupMap; + this.placementGroupDeleted = placementGroupDeleted; + } + + @VisibleForTesting + void deletePlacementGroup(String region, String tag) { + Preconditions2.checkNotEmpty(tag, "tag"); + String group = String.format("jclouds#%s#%s", tag, region); + try { + if (ec2Client.getPlacementGroupServices().describePlacementGroupsInRegion(region, group).size() > 0) { + logger.debug(">> deleting placementGroup(%s)", group); + try { + ec2Client.getPlacementGroupServices().deletePlacementGroupInRegion(region, group); + checkState(placementGroupDeleted.apply(new PlacementGroup(region, group, "cluster", State.PENDING)), + String.format("placementGroup region(%s) name(%s) failed to delete", region, group)); + placementGroupMap.remove(new RegionAndName(region, group)); + logger.debug("<< deleted placementGroup(%s)", group); + } catch (IllegalStateException e) { + logger.debug("<< inUse placementGroup(%s)", group); + } + } + } catch (UnsupportedOperationException e) { + logger.trace("<< placementGroups unsupported in region %s", region); + } + } + + protected void cleanUpIncidentalResources(Entry regionTag) { + super.cleanUpIncidentalResources(regionTag); + deletePlacementGroup(regionTag.getKey(), regionTag.getValue()); + } + + /** + * returns template options, except of type {@link EC2TemplateOptions}. + */ + @Override + public EC2TemplateOptions templateOptions() { + return EC2TemplateOptions.class.cast(super.templateOptions()); + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderImpl.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderImpl.java new file mode 100644 index 0000000000..fd41fc3a84 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderImpl.java @@ -0,0 +1,72 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + +import org.jclouds.collect.Memoized; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Location; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; + +import com.google.common.base.Supplier; + +/** + * + * @author Adrian Cole + */ +public class AWSEC2TemplateBuilderImpl extends EC2TemplateBuilderImpl { + + @Inject + protected AWSEC2TemplateBuilderImpl(@Memoized Supplier> locations, + @Memoized Supplier> images, @Memoized Supplier> sizes, + Supplier defaultLocation, Provider optionsProvider, + @Named("DEFAULT") Provider defaultTemplateProvider, Map imageMap) { + super(locations, images, sizes, defaultLocation, optionsProvider, defaultTemplateProvider, imageMap); + } + + @Override + protected void copyTemplateOptions(TemplateOptions from, TemplateOptions to) { + super.copyTemplateOptions(from, to); + if (from instanceof AWSEC2TemplateOptions) { + AWSEC2TemplateOptions eFrom = AWSEC2TemplateOptions.class.cast(from); + AWSEC2TemplateOptions eTo = AWSEC2TemplateOptions.class.cast(to); + + if (eFrom.getSubnetId() != null) + eTo.subnetId(eFrom.getSubnetId()); + if (eFrom.isMonitoringEnabled()) + eTo.enableMonitoring(); + if (!eFrom.shouldAutomaticallyCreatePlacementGroup()) + eTo.noPlacementGroup(); + if (eFrom.getPlacementGroup() != null) + eTo.placementGroup(eFrom.getPlacementGroup()); + } + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java new file mode 100644 index 0000000000..51cb7ae5f6 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateOptions.java @@ -0,0 +1,552 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.Arrays; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.io.Payload; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.util.Preconditions2; + +/** + * Contains options supported in the {@code ComputeService#runNode} operation on the "ec2" provider. + *

+ * Usage

The recommended way to instantiate a AWSEC2TemplateOptions object is to statically + * import AWSEC2TemplateOptions.* and invoke a static creation method followed by an instance + * mutator (if needed): + *

+ * + * import static org.jclouds.aws.ec2.compute.options.AWSEC2TemplateOptions.Builder.*; + *

+ * ComputeService client = // get connection + * templateBuilder.options(inboundPorts(22, 80, 8080, 443)); + * Set set = client.runNodesWithTag(tag, 2, templateBuilder.build()); + * + * + * @author Adrian Cole + */ +public class AWSEC2TemplateOptions extends EC2TemplateOptions { + + private boolean monitoringEnabled; + private String placementGroup = null; + private boolean noPlacementGroup; + private String subnetId; + + public static final AWSEC2TemplateOptions NONE = new AWSEC2TemplateOptions(); + + /** + * Enable Cloudwatch monitoring + * + * @see CloudWatchClient + */ + public AWSEC2TemplateOptions enableMonitoring() { + this.monitoringEnabled = true; + return this; + } + + /** + * Specifies the keypair used to run instances with + */ + public AWSEC2TemplateOptions placementGroup(String placementGroup) { + checkNotNull(placementGroup, "use noPlacementGroup option to request boot without a keypair"); + checkState(!noPlacementGroup, "you cannot specify both options placementGroup and noPlacementGroup"); + Preconditions2.checkNotEmpty(placementGroup, "placementGroup must be non-empty"); + this.placementGroup = placementGroup; + return this; + } + + /** + * Do not use a keypair on instances + */ + public AWSEC2TemplateOptions noPlacementGroup() { + checkState(placementGroup == null, "you cannot specify both options placementGroup and noPlacementGroup"); + this.noPlacementGroup = true; + return this; + } + + /** + * Specifies the subnetId used to run instances in + */ + public AWSEC2TemplateOptions subnetId(String subnetId) { + checkNotNull(subnetId, "subnetId cannot be null"); + Preconditions2.checkNotEmpty(subnetId, "subnetId must be non-empty"); + this.subnetId = subnetId; + return this; + } + + public static class Builder { + /** + * @see EC2TemplateOptions#blockDeviceMappings + */ + public static AWSEC2TemplateOptions blockDeviceMappings(Set blockDeviceMappings) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.blockDeviceMappings(blockDeviceMappings); + } + + /** + * @see EC2TemplateOptions#mapEBSSnapshotToDeviceName + */ + public static AWSEC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId, + @Nullable Integer sizeInGib, boolean deleteOnTermination) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib, deleteOnTermination); + } + + /** + * @see EC2TemplateOptions#mapNewVolumeToDeviceName + */ + public static AWSEC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, + boolean deleteOnTermination) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination); + } + + /** + * @see EC2TemplateOptions#mapEphemeralDeviceToDeviceName + */ + public static AWSEC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.mapEphemeralDeviceToDeviceName(deviceName, virtualName); + } + + /** + * @see EC2TemplateOptions#unmapDeviceNamed + */ + public static AWSEC2TemplateOptions unmapDeviceNamed(String deviceName) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.unmapDeviceNamed(deviceName); + } + + /** + * @see AWSEC2TemplateOptions#securityGroups(Iterable) + */ + public static AWSEC2TemplateOptions securityGroups(String... groupIds) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.securityGroups(groupIds); + } + + /** + * @see AWSEC2TemplateOptions#securityGroups(Iterable) + */ + public static AWSEC2TemplateOptions securityGroups(Iterable groupIds) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.securityGroups(groupIds); + } + + /** + * @see AWSEC2TemplateOptions#keyPair + */ + public static AWSEC2TemplateOptions keyPair(String keyPair) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.keyPair(keyPair); + } + + /** + * @see AWSEC2TemplateOptions#userData + */ + public static AWSEC2TemplateOptions userData(byte[] unencodedData) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.userData(unencodedData); + } + + /** + * @see AWSEC2TemplateOptions#noKeyPair + */ + public static AWSEC2TemplateOptions noKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.noKeyPair(); + } + + /** + * @see AWSEC2TemplateOptions#placementGroup + */ + public static AWSEC2TemplateOptions placementGroup(String placementGroup) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.placementGroup(placementGroup); + } + + /** + * @see AWSEC2TemplateOptions#noPlacementGroup + */ + public static AWSEC2TemplateOptions noPlacementGroup() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.noPlacementGroup(); + } + + /** + * @see AWSEC2TemplateOptions#enableMonitoring + */ + public static AWSEC2TemplateOptions enableMonitoring() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.enableMonitoring(); + } + + // methods that only facilitate returning the correct object type + /** + * @see TemplateOptions#inboundPorts + */ + public static AWSEC2TemplateOptions inboundPorts(int... ports) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.inboundPorts(ports); + } + + /** + * @see TemplateOptions#port + */ + public static AWSEC2TemplateOptions blockOnPort(int port, int seconds) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.blockOnPort(port, seconds); + } + + /** + * @see TemplateOptions#runScript + */ + public static AWSEC2TemplateOptions runScript(byte[] script) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.runScript(script); + } + + /** + * @see TemplateOptions#installPrivateKey + */ + public static AWSEC2TemplateOptions installPrivateKey(String rsaKey) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.installPrivateKey(rsaKey); + } + + /** + * @see TemplateOptions#authorizePublicKey + */ + public static AWSEC2TemplateOptions authorizePublicKey(String rsaKey) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.authorizePublicKey(rsaKey); + } + + /** + * @see TemplateOptions#withDetails + */ + public static AWSEC2TemplateOptions withDetails() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.withMetadata(); + } + + /** + * @see TemplateOptions#withSubnetId + */ + public static AWSEC2TemplateOptions subnetId(String subnetId) { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + return options.subnetId(subnetId); + } + } + + // methods that only facilitate returning the correct object type + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions blockDeviceMappings(Set blockDeviceMappings) { + return AWSEC2TemplateOptions.class.cast(super.blockDeviceMappings(blockDeviceMappings)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions keyPair(String keyPair) { + return AWSEC2TemplateOptions.class.cast(super.keyPair(keyPair)); + } + + /** + * {@inheritDoc} + */ + + @Override + public AWSEC2TemplateOptions mapEBSSnapshotToDeviceName(String deviceName, String snapshotId, Integer sizeInGib, + boolean deleteOnTermination) { + return AWSEC2TemplateOptions.class.cast(super.mapEBSSnapshotToDeviceName(deviceName, snapshotId, sizeInGib, + deleteOnTermination)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions mapEphemeralDeviceToDeviceName(String deviceName, String virtualName) { + return AWSEC2TemplateOptions.class.cast(super.mapEphemeralDeviceToDeviceName(deviceName, virtualName)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions mapNewVolumeToDeviceName(String deviceName, int sizeInGib, boolean deleteOnTermination) { + return AWSEC2TemplateOptions.class.cast(super + .mapNewVolumeToDeviceName(deviceName, sizeInGib, deleteOnTermination)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions noKeyPair() { + return AWSEC2TemplateOptions.class.cast(super.noKeyPair()); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions securityGroups(Iterable groupIds) { + return AWSEC2TemplateOptions.class.cast(super.securityGroups(groupIds)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions securityGroups(String... groupIds) { + return AWSEC2TemplateOptions.class.cast(super.securityGroups(groupIds)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions unmapDeviceNamed(String deviceName) { + return AWSEC2TemplateOptions.class.cast(super.unmapDeviceNamed(deviceName)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions userData(byte[] unencodedData) { + return AWSEC2TemplateOptions.class.cast(super.userData(unencodedData)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions blockOnPort(int port, int seconds) { + return AWSEC2TemplateOptions.class.cast(super.blockOnPort(port, seconds)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions inboundPorts(int... ports) { + return AWSEC2TemplateOptions.class.cast(super.inboundPorts(ports)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions authorizePublicKey(String publicKey) { + return AWSEC2TemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * {@inheritDoc} + */ + @Override + @Deprecated + public AWSEC2TemplateOptions authorizePublicKey(Payload publicKey) { + return AWSEC2TemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions installPrivateKey(String privateKey) { + return AWSEC2TemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * {@inheritDoc} + */ + @Override + @Deprecated + public AWSEC2TemplateOptions installPrivateKey(Payload privateKey) { + return AWSEC2TemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions runScript(Payload script) { + return AWSEC2TemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + @Deprecated + public AWSEC2TemplateOptions runScript(byte[] script) { + return AWSEC2TemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions withMetadata() { + return AWSEC2TemplateOptions.class.cast(super.withMetadata()); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions blockUntilRunning(boolean blockUntilRunning) { + return AWSEC2TemplateOptions.class.cast(super.blockUntilRunning(blockUntilRunning)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions dontAuthorizePublicKey() { + return AWSEC2TemplateOptions.class.cast(super.dontAuthorizePublicKey()); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions nameTask(String name) { + return AWSEC2TemplateOptions.class.cast(super.nameTask(name)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions runAsRoot(boolean runAsRoot) { + return AWSEC2TemplateOptions.class.cast(super.runAsRoot(runAsRoot)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions runScript(Statement script) { + return AWSEC2TemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + public AWSEC2TemplateOptions withOverridingCredentials(Credentials overridingCredentials) { + return AWSEC2TemplateOptions.class.cast(super.withOverridingCredentials(overridingCredentials)); + } + + /** + * @return placementGroup to use when running the instance or null, to generate a placementGroup. + */ + public String getPlacementGroup() { + return placementGroup; + } + + /** + * @return true (default) if we are supposed to use a placementGroup + */ + public boolean shouldAutomaticallyCreatePlacementGroup() { + return !noPlacementGroup; + } + + /** + * @return true (default) if we are supposed to enable cloudwatch + */ + public boolean isMonitoringEnabled() { + return monitoringEnabled; + } + + /** + * @return subnetId to use when running the instance or null. + */ + public String getSubnetId() { + return subnetId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + (monitoringEnabled ? 1231 : 1237); + result = prime * result + (noPlacementGroup ? 1231 : 1237); + result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); + result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + AWSEC2TemplateOptions other = (AWSEC2TemplateOptions) obj; + if (monitoringEnabled != other.monitoringEnabled) + return false; + if (noPlacementGroup != other.noPlacementGroup) + return false; + if (placementGroup == null) { + if (other.placementGroup != null) + return false; + } else if (!placementGroup.equals(other.placementGroup)) + return false; + if (subnetId == null) { + if (other.subnetId != null) + return false; + } else if (!subnetId.equals(other.subnetId)) + return false; + return true; + } + + @Override + public String toString() { + + return "[groupIds=" + getGroupIds() + ", keyPair=" + getKeyPair() + ", noKeyPair=" + + !shouldAutomaticallyCreateKeyPair() + ", monitoringEnabled=" + monitoringEnabled + ", placementGroup=" + + placementGroup + ", noPlacementGroup=" + noPlacementGroup + ", subnetId=" + subnetId + ", userData=" + + Arrays.toString(getUserData()) + ", blockDeviceMappings=" + getBlockDeviceMappings() + "]"; + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2ComputeServiceContextModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java similarity index 54% rename from providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2ComputeServiceContextModule.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java index 4d93da2c86..0ea1bd580c 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2ComputeServiceContextModule.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceContextModule.java @@ -17,14 +17,22 @@ * ==================================================================== */ -package org.jclouds.aws.ec2.config; +package org.jclouds.aws.ec2.compute.config; import static org.jclouds.compute.domain.OsFamily.AMZN_LINUX; -import org.jclouds.aws.ec2.strategy.AWSEC2ReviseParsedImage; +import org.jclouds.aws.ec2.compute.AWSEC2TemplateBuilderImpl; +import org.jclouds.aws.ec2.compute.strategy.AWSEC2ReviseParsedImage; +import org.jclouds.aws.ec2.compute.strategy.CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions; +import org.jclouds.aws.ec2.compute.suppliers.AWSEC2HardwareSupplier; +import org.jclouds.aws.ec2.compute.suppliers.AWSRegionAndNameToImageSupplier; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.ec2.compute.config.EC2ComputeServiceContextModule; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; +import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions; import org.jclouds.ec2.compute.strategy.ReviseParsedImage; +import org.jclouds.ec2.compute.suppliers.EC2HardwareSupplier; +import org.jclouds.ec2.compute.suppliers.RegionAndNameToImageSupplier; import com.google.inject.Injector; @@ -43,6 +51,16 @@ public class AWSEC2ComputeServiceContextModule extends EC2ComputeServiceContextM protected void configure() { super.configure(); bind(ReviseParsedImage.class).to(AWSEC2ReviseParsedImage.class); + bind(CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class).to( + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class); + bind(EC2HardwareSupplier.class).to(AWSEC2HardwareSupplier.class); + bind(RegionAndNameToImageSupplier.class).to(AWSRegionAndNameToImageSupplier.class); + bind(EC2TemplateBuilderImpl.class).to(AWSEC2TemplateBuilderImpl.class); + } + + @Override + protected void installDependencies() { + install(new AWSEC2ComputeServiceDependenciesModule()); } } diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java new file mode 100644 index 0000000000..cfdfd72bc2 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java @@ -0,0 +1,117 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute.config; + +import static com.google.common.collect.Iterables.toArray; +import static com.google.common.collect.Maps.newLinkedHashMap; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.compute.AWSEC2ComputeService; +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable; +import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.internal.ComputeServiceContextImpl; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Credentials; +import org.jclouds.ec2.compute.config.EC2ComputeServiceDependenciesModule; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CredentialsForInstance; +import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; +import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.predicates.RetryablePredicate; +import org.jclouds.rest.RestContext; +import org.jclouds.rest.internal.RestContextImpl; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Splitter; +import com.google.inject.Provides; +import com.google.inject.Scopes; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDependenciesModule { + @Override + protected void configure() { + bind(TemplateBuilder.class).to(EC2TemplateBuilderImpl.class); + bind(TemplateOptions.class).to(AWSEC2TemplateOptions.class); + bind(ComputeService.class).to(AWSEC2ComputeService.class); + bind(new TypeLiteral>() { + }).to(RunningInstanceToNodeMetadata.class); + bind(new TypeLiteral>() { + }).to(CredentialsForInstance.class); + bind(new TypeLiteral() { + }).to(new TypeLiteral>() { + }).in(Scopes.SINGLETON); + bind(new TypeLiteral>() { + }).to(new TypeLiteral>() { + }).in(Scopes.SINGLETON); + } + + @Provides + @Singleton + @Named("AVAILABLE") + protected Predicate placementGroupAvailable(PlacementGroupAvailable available) { + return new RetryablePredicate(available, 60, 1, TimeUnit.SECONDS); + } + + @Provides + @Singleton + @Named("DELETED") + protected Predicate placementGroupDeleted(PlacementGroupDeleted deleted) { + return new RetryablePredicate(deleted, 60, 1, TimeUnit.SECONDS); + } + + @Provides + @Singleton + @Named("PLACEMENT") + protected Map placementGroupMap(CreateSecurityGroupIfNeeded in) { + // doesn't seem to clear when someone issues remove(key) + // return new MapMaker().makeComputingMap(in); + return newLinkedHashMap(); + } + + @Provides + @Singleton + @Named(PROPERTY_EC2_CC_AMIs) + protected String[] ccAmis(@Named(PROPERTY_EC2_CC_AMIs) String ccAmis) { + if (ccAmis.trim().equals("")) + return new String[] {}; + return toArray(Splitter.on(',').split(ccAmis), String.class); + } +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/strategy/AWSEC2ReviseParsedImage.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImage.java similarity index 99% rename from providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/strategy/AWSEC2ReviseParsedImage.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImage.java index 88824475a6..83a894594b 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/strategy/AWSEC2ReviseParsedImage.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImage.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.aws.ec2.strategy; +package org.jclouds.aws.ec2.compute.strategy; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java new file mode 100644 index 0000000000..35913beb32 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.java @@ -0,0 +1,113 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute.strategy; + +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.aws.ec2.functions.CreatePlacementGroupIfNeeded; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; +import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; +import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.options.RunInstancesOptions; + +import com.google.common.annotations.VisibleForTesting; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions extends + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions { + + @VisibleForTesting + final Map placementGroupMap; + @VisibleForTesting + final CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded; + + @Inject + public CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions( + Map credentialsMap, @Named("SECURITY") Map securityGroupMap, + @Named("PLACEMENT") Map placementGroupMap, CreateUniqueKeyPair createUniqueKeyPair, + CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded, + javax.inject.Provider optionsProvider, + CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded) { + super(credentialsMap, securityGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, optionsProvider); + this.placementGroupMap = placementGroupMap; + this.createPlacementGroupIfNeeded = createPlacementGroupIfNeeded; + } + + public AWSRunInstancesOptions execute(String region, String tag, Template template) { + AWSRunInstancesOptions instanceOptions = AWSRunInstancesOptions.class.cast(super.execute(region, tag, template)); + + String placementGroupName = template.getHardware().getId().startsWith("cc") ? createNewPlacementGroupUnlessUserSpecifiedOtherwise( + region, tag, template.getOptions()) + : null; + + if (placementGroupName != null) + instanceOptions.inPlacementGroup(placementGroupName); + + if (AWSEC2TemplateOptions.class.cast(template.getOptions()).isMonitoringEnabled()) + instanceOptions.enableMonitoring(); + + return instanceOptions; + } + + @VisibleForTesting + String createNewPlacementGroupUnlessUserSpecifiedOtherwise(String region, String tag, TemplateOptions options) { + String placementGroupName = null; + boolean shouldAutomaticallyCreatePlacementGroup = true; + if (options instanceof EC2TemplateOptions) { + placementGroupName = AWSEC2TemplateOptions.class.cast(options).getPlacementGroup(); + if (placementGroupName == null) + shouldAutomaticallyCreatePlacementGroup = AWSEC2TemplateOptions.class.cast(options) + .shouldAutomaticallyCreatePlacementGroup(); + } + if (placementGroupName == null && shouldAutomaticallyCreatePlacementGroup) { + placementGroupName = String.format("jclouds#%s#%s", tag, region); + RegionAndName regionAndName = new RegionAndName(region, placementGroupName); + if (!placementGroupMap.containsKey(regionAndName)) { + placementGroupMap.put(regionAndName, createPlacementGroupIfNeeded.apply(regionAndName)); + } + } + return placementGroupName; + } + + @Override + protected void addSecurityGroups(String region, String tag, Template template, RunInstancesOptions instanceOptions) { + String subnetId = AWSEC2TemplateOptions.class.cast(template.getOptions()).getSubnetId(); + if (subnetId != null) { + AWSRunInstancesOptions.class.cast(instanceOptions).withSubnetId(subnetId); + } else { + super.addSecurityGroups(region, tag, template, instanceOptions); + } + } +} \ No newline at end of file diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2HardwareSupplier.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2HardwareSupplier.java new file mode 100644 index 0000000000..c1c6316a56 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSEC2HardwareSupplier.java @@ -0,0 +1,90 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute.suppliers; + +import static com.google.common.collect.Iterables.find; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.cc1_4xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_2xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_4xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m2_xlarge; +import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.t1_micro; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.collect.Memoized; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationScope; +import org.jclouds.ec2.compute.suppliers.EC2HardwareSupplier; +import org.jclouds.location.Provider; + +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class AWSEC2HardwareSupplier extends EC2HardwareSupplier { + + private final Supplier> locations; + private final String[] ccAmis; + + @Inject + public AWSEC2HardwareSupplier(@Memoized Supplier> locations, @Provider String providerName, + @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis) { + this.locations = locations; + this.ccAmis = ccAmis; + } + + @Override + public Set get() { + Builder sizes = ImmutableSet.builder(); + for (String ccAmi : ccAmis) { + final String region = ccAmi.split("/")[0]; + Location location = find(locations.get(), new Predicate() { + + @Override + public boolean apply(Location input) { + return input.getScope() == LocationScope.REGION && input.getId().equals(region); + } + + }); + sizes.add(cc1_4xlarge().location(location).supportsImageIds(ccAmi).build()); + } + sizes.addAll(ImmutableSet. of(t1_micro().build(), c1_medium().build(), c1_xlarge().build(), m1_large() + .build(), m1_small().build(), m1_xlarge().build(), m2_xlarge().build(), m2_2xlarge().build(), + m2_4xlarge().build())); + return sizes.build(); + } +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSRegionAndNameToImageSupplier.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSRegionAndNameToImageSupplier.java new file mode 100644 index 0000000000..be88ce886e --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/suppliers/AWSRegionAndNameToImageSupplier.java @@ -0,0 +1,93 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute.suppliers; + +/** + * + * + * ==================================================================== + * 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. + * ==================================================================== + */ + +import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Maps.newLinkedHashMap; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_CC_AMIs; +import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds; +import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; + +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.Image; +import org.jclouds.ec2.compute.domain.RegionAndName; +import org.jclouds.ec2.compute.functions.EC2ImageParser; +import org.jclouds.ec2.compute.strategy.DescribeImagesParallel; +import org.jclouds.ec2.compute.suppliers.RegionAndNameToImageSupplier; +import org.jclouds.ec2.options.DescribeImagesOptions; +import org.jclouds.location.Region; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class AWSRegionAndNameToImageSupplier extends RegionAndNameToImageSupplier { + + private final String[] ccAmis; + + @Inject + AWSRegionAndNameToImageSupplier(@Region Set regions, DescribeImagesParallel describer, + @Named(PROPERTY_EC2_CC_AMIs) String[] ccAmis, @Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, + EC2ImageParser parser, Map images) { + super(regions, describer, amiOwners, parser, images); + this.ccAmis = ccAmis; + } + + public Iterable> getDescribeQueriesForOwnersInRegions(Set regions, + String[] amiOwners) { + return concat(super.getDescribeQueriesForOwnersInRegions(regions, amiOwners), ccAmisToDescribeQueries(ccAmis) + .entrySet()); + } + + static Map ccAmisToDescribeQueries(String[] ccAmis) { + Map queries = newLinkedHashMap(); + for (String from : ccAmis) { + queries.put(from.split("/")[0], imageIds(from.split("/")[1])); + } + return queries; + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2RestClientModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2RestClientModule.java new file mode 100644 index 0000000000..ad0866e6d2 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/config/AWSEC2RestClientModule.java @@ -0,0 +1,133 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.config; + +import java.util.Map; + +import javax.inject.Singleton; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; +import org.jclouds.aws.ec2.services.AWSAMIAsyncClient; +import org.jclouds.aws.ec2.services.AWSAMIClient; +import org.jclouds.aws.ec2.services.AWSInstanceAsyncClient; +import org.jclouds.aws.ec2.services.AWSInstanceClient; +import org.jclouds.aws.ec2.services.MonitoringAsyncClient; +import org.jclouds.aws.ec2.services.MonitoringClient; +import org.jclouds.aws.ec2.services.PlacementGroupAsyncClient; +import org.jclouds.aws.ec2.services.PlacementGroupClient; +import org.jclouds.ec2.EC2AsyncClient; +import org.jclouds.ec2.EC2Client; +import org.jclouds.ec2.config.EC2RestClientModule; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.services.AMIAsyncClient; +import org.jclouds.ec2.services.AMIClient; +import org.jclouds.ec2.services.AvailabilityZoneAndRegionAsyncClient; +import org.jclouds.ec2.services.AvailabilityZoneAndRegionClient; +import org.jclouds.ec2.services.ElasticBlockStoreAsyncClient; +import org.jclouds.ec2.services.ElasticBlockStoreClient; +import org.jclouds.ec2.services.ElasticIPAddressAsyncClient; +import org.jclouds.ec2.services.ElasticIPAddressClient; +import org.jclouds.ec2.services.InstanceAsyncClient; +import org.jclouds.ec2.services.InstanceClient; +import org.jclouds.ec2.services.KeyPairAsyncClient; +import org.jclouds.ec2.services.KeyPairClient; +import org.jclouds.ec2.services.SecurityGroupAsyncClient; +import org.jclouds.ec2.services.SecurityGroupClient; +import org.jclouds.ec2.services.WindowsAsyncClient; +import org.jclouds.ec2.services.WindowsClient; +import org.jclouds.http.RequiresHttp; +import org.jclouds.rest.ConfiguresRestClient; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Provides; + +/** + * Configures the EC2 connection. + * + * @author Adrian Cole + */ +@RequiresHttp +@ConfiguresRestClient +public class AWSEC2RestClientModule extends EC2RestClientModule { + + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// + .put(AWSAMIClient.class, AWSAMIAsyncClient.class)// + .put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)// + .put(AWSInstanceClient.class, AWSInstanceAsyncClient.class)// + .put(KeyPairClient.class, KeyPairAsyncClient.class)// + .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)// + .put(PlacementGroupClient.class, PlacementGroupAsyncClient.class)// + .put(MonitoringClient.class, MonitoringAsyncClient.class)// + .put(WindowsClient.class, WindowsAsyncClient.class)// + .put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)// + .put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)// + .build(); + + public AWSEC2RestClientModule() { + super(AWSEC2Client.class, AWSEC2AsyncClient.class, DELEGATE_MAP); + } + + @Singleton + @Provides + EC2Client provide(AWSEC2Client in) { + return in; + } + + @Singleton + @Provides + EC2AsyncClient provide(AWSEC2AsyncClient in) { + return in; + } + + @Singleton + @Provides + InstanceClient getInstanceServices(AWSEC2Client in) { + return in.getInstanceServices(); + } + + @Singleton + @Provides + InstanceAsyncClient getInstanceServices(AWSEC2AsyncClient in) { + return in.getInstanceServices(); + } + + @Singleton + @Provides + AMIClient getAMIServices(AWSEC2Client in) { + return in.getAMIServices(); + } + + @Singleton + @Provides + AMIAsyncClient getAMIServices(AWSEC2AsyncClient in) { + return in.getAMIServices(); + } + + @Override + protected void configure() { + bind(RunningInstance.Builder.class).to(AWSRunningInstance.Builder.class); + bind(RunInstancesOptions.class).to(AWSRunInstancesOptions.class); + super.configure(); + } +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/AWSRunningInstance.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/AWSRunningInstance.java new file mode 100644 index 0000000000..03f4ad0e75 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/AWSRunningInstance.java @@ -0,0 +1,354 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Date; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.RunningInstance; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; + +/** + * + * @see + * @author Adrian Cole + */ +public class AWSRunningInstance extends RunningInstance { + + public static class Builder extends org.jclouds.ec2.domain.RunningInstance.Builder { + private MonitoringState monitoringState; + private String placementGroup; + private Set productCodes = Sets.newLinkedHashSet(); + private String subnetId; + private String spotInstanceRequestId; + private String vpcId; + + public Builder monitoringState(MonitoringState monitoringState) { + this.monitoringState = monitoringState; + return this; + } + + public Builder placementGroup(String placementGroup) { + this.placementGroup = placementGroup; + return this; + } + + public Builder productCodes(Iterable productCodes) { + this.productCodes = ImmutableSet.copyOf(checkNotNull(productCodes, "productCodes")); + return this; + } + + public Builder productCode(String productCode) { + if (productCode != null) + this.productCodes.add(productCode); + return this; + } + + public Builder subnetId(String subnetId) { + this.subnetId = subnetId; + return this; + } + + public Builder spotInstanceRequestId(String spotInstanceRequestId) { + this.spotInstanceRequestId = spotInstanceRequestId; + return this; + } + + public Builder vpcId(String vpcId) { + this.vpcId = vpcId; + return this; + } + + @Override + public Builder amiLaunchIndex(String amiLaunchIndex) { + return Builder.class.cast(super.amiLaunchIndex(amiLaunchIndex)); + } + + @Override + public Builder availabilityZone(String availabilityZone) { + return Builder.class.cast(super.availabilityZone(availabilityZone)); + } + + @Override + public Builder devices(Map ebsBlockDevices) { + return Builder.class.cast(super.devices(ebsBlockDevices)); + } + + @Override + public Builder dnsName(String dnsName) { + return Builder.class.cast(super.dnsName(dnsName)); + } + + @Override + public Builder imageId(String imageId) { + return Builder.class.cast(super.imageId(imageId)); + } + + @Override + public Builder instanceId(String instanceId) { + return Builder.class.cast(super.instanceId(instanceId)); + } + + @Override + public Builder instanceState(InstanceState instanceState) { + return Builder.class.cast(super.instanceState(instanceState)); + } + + @Override + public Builder instanceType(String instanceType) { + return Builder.class.cast(super.instanceType(instanceType)); + } + + @Override + public Builder ipAddress(String ipAddress) { + return Builder.class.cast(super.ipAddress(ipAddress)); + } + + @Override + public Builder kernelId(String kernelId) { + return Builder.class.cast(super.kernelId(kernelId)); + } + + @Override + public Builder keyName(String keyName) { + return Builder.class.cast(super.keyName(keyName)); + } + + @Override + public Builder launchTime(Date launchTime) { + return Builder.class.cast(super.launchTime(launchTime)); + } + + @Override + public Builder platform(String platform) { + return Builder.class.cast(super.platform(platform)); + } + + @Override + public Builder privateDnsName(String privateDnsName) { + return Builder.class.cast(super.privateDnsName(privateDnsName)); + } + + @Override + public Builder privateIpAddress(String privateIpAddress) { + return Builder.class.cast(super.privateIpAddress(privateIpAddress)); + } + + @Override + public Builder ramdiskId(String ramdiskId) { + return Builder.class.cast(super.ramdiskId(ramdiskId)); + } + + @Override + public Builder reason(String reason) { + return Builder.class.cast(super.reason(reason)); + } + + @Override + public Builder region(String region) { + return Builder.class.cast(super.region(region)); + } + + @Override + public Builder rootDeviceName(String rootDeviceName) { + return Builder.class.cast(super.rootDeviceName(rootDeviceName)); + } + + @Override + public Builder rootDeviceType(RootDeviceType rootDeviceType) { + return Builder.class.cast(super.rootDeviceType(rootDeviceType)); + } + + @Override + public Builder virtualizationType(String virtualizationType) { + return Builder.class.cast(super.virtualizationType(virtualizationType)); + } + + @Override + public Builder device(String key, BlockDevice value) { + return Builder.class.cast(super.device(key, value)); + } + + @Override + public Builder groupId(String groupId) { + return Builder.class.cast(super.groupId(groupId)); + } + + @Override + public Builder groupIds(Iterable groupIds) { + return Builder.class.cast(super.groupIds(groupIds)); + } + + @Override + public AWSRunningInstance build() { + return new AWSRunningInstance(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState, + instanceType, ipAddress, kernelId, keyName, launchTime, availabilityZone, virtualizationType, + platform, privateDnsName, privateIpAddress, ramdiskId, reason, rootDeviceType, rootDeviceName, + ebsBlockDevices, monitoringState, placementGroup, productCodes, subnetId, spotInstanceRequestId, + vpcId); + } + + } + + private final MonitoringState monitoringState; + @Nullable + private final String placementGroup; + private final Set productCodes; + @Nullable + private final String subnetId; + @Nullable + private final String spotInstanceRequestId; + @Nullable + private final String vpcId; + + protected AWSRunningInstance(String region, Iterable groupIds, String amiLaunchIndex, String dnsName, + String imageId, String instanceId, InstanceState instanceState, String instanceType, String ipAddress, + String kernelId, String keyName, Date launchTime, String availabilityZone, String virtualizationType, + String platform, String privateDnsName, String privateIpAddress, String ramdiskId, String reason, + RootDeviceType rootDeviceType, String rootDeviceName, Map ebsBlockDevices, + MonitoringState monitoringState, String placementGroup, Iterable productCodes, String subnetId, + String spotInstanceRequestId, String vpcId) { + super(region, groupIds, amiLaunchIndex, dnsName, imageId, instanceId, instanceState, instanceType, ipAddress, + kernelId, keyName, launchTime, availabilityZone, virtualizationType, platform, privateDnsName, + privateIpAddress, ramdiskId, reason, rootDeviceType, rootDeviceName, ebsBlockDevices); + this.monitoringState = checkNotNull(monitoringState, "monitoringState"); + this.placementGroup = placementGroup; + this.productCodes = ImmutableSet.copyOf(checkNotNull(groupIds, "groupIds")); + this.subnetId = subnetId; + this.spotInstanceRequestId = spotInstanceRequestId; + this.vpcId = vpcId; + } + + /** + * State of monitoring for the instance. + */ + public MonitoringState getMonitoringState() { + return monitoringState; + } + + /** + * The name of the placement group the instance is in (for cluster compute instances). + */ + public String getPlacementGroup() { + return placementGroup; + } + + /** + * Product codes attached to this instance. + */ + public Set getProductCodes() { + return productCodes; + } + + /** + * The ID of the Spot Instance request + */ + public String getSpotInstanceRequestId() { + return spotInstanceRequestId; + } + + /** + * Specifies the VPC in which the instance is running (Amazon Virtual Private Cloud). + */ + public String getVpcId() { + return vpcId; + } + + /** + * Specifies the subnet ID in which the instance is running (Amazon Virtual Private Cloud). + */ + public String getSubnetId() { + return subnetId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((placementGroup == null) ? 0 : placementGroup.hashCode()); + result = prime * result + ((productCodes == null) ? 0 : productCodes.hashCode()); + result = prime * result + ((spotInstanceRequestId == null) ? 0 : spotInstanceRequestId.hashCode()); + result = prime * result + ((subnetId == null) ? 0 : subnetId.hashCode()); + result = prime * result + ((vpcId == null) ? 0 : vpcId.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + AWSRunningInstance other = (AWSRunningInstance) obj; + if (placementGroup == null) { + if (other.placementGroup != null) + return false; + } else if (!placementGroup.equals(other.placementGroup)) + return false; + if (productCodes == null) { + if (other.productCodes != null) + return false; + } else if (!productCodes.equals(other.productCodes)) + return false; + if (spotInstanceRequestId == null) { + if (other.spotInstanceRequestId != null) + return false; + } else if (!spotInstanceRequestId.equals(other.spotInstanceRequestId)) + return false; + if (subnetId == null) { + if (other.subnetId != null) + return false; + } else if (!subnetId.equals(other.subnetId)) + return false; + if (vpcId == null) { + if (other.vpcId != null) + return false; + } else if (!vpcId.equals(other.vpcId)) + return false; + return true; + } + + @Override + public String toString() { + return "[region=" + region + ", availabilityZone=" + availabilityZone + ", instanceId=" + instanceId + + ", instanceState=" + instanceState + ", instanceType=" + instanceType + ", virtualizationType=" + + virtualizationType + ", imageId=" + imageId + ", ipAddress=" + ipAddress + ", dnsName=" + dnsName + + ", privateIpAddress=" + privateIpAddress + ", privateDnsName=" + privateDnsName + ", keyName=" + + keyName + ", platform=" + platform + ", launchTime=" + launchTime + ", rootDeviceName=" + + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", ebsBlockDevices=" + ebsBlockDevices + + ", monitoringState=" + monitoringState + ", placementGroup=" + placementGroup + ", productCodes=" + + productCodes + ", spotInstanceRequestId=" + spotInstanceRequestId + ", subnetId=" + subnetId + + ", vpcId=" + vpcId + "]"; + } + +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/MonitoringState.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/MonitoringState.java similarity index 86% rename from apis/ec2/src/main/java/org/jclouds/ec2/domain/MonitoringState.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/MonitoringState.java index cdf7a2a669..0facfdd784 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/MonitoringState.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/MonitoringState.java @@ -17,12 +17,12 @@ * ==================================================================== */ -package org.jclouds.ec2.domain; +package org.jclouds.aws.ec2.domain; import static com.google.common.base.Preconditions.checkNotNull; +import org.jclouds.aws.ec2.services.MonitoringClient; import org.jclouds.ec2.services.InstanceClient; -import org.jclouds.ec2.services.MonitoringClient; /** * @@ -47,13 +47,6 @@ public enum MonitoringState { } public static MonitoringState fromValue(String state) { - /** - * Eucalyptus - */ - if ("false".endsWith(state)) - return DISABLED; - if ("true".endsWith(state)) - return ENABLED; try { return valueOf(checkNotNull(state, "state").toUpperCase()); } catch (IllegalArgumentException e) { diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/PlacementGroup.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/PlacementGroup.java similarity index 99% rename from apis/ec2/src/main/java/org/jclouds/ec2/domain/PlacementGroup.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/PlacementGroup.java index 2d2f5cd6cd..467b8a6498 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/PlacementGroup.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/domain/PlacementGroup.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.domain; +package org.jclouds.aws.ec2.domain; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreatePlacementGroupIfNeeded.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java similarity index 90% rename from apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreatePlacementGroupIfNeeded.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java index 549582a5c1..584a04bb38 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/functions/CreatePlacementGroupIfNeeded.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/functions/CreatePlacementGroupIfNeeded.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.compute.functions; +package org.jclouds.aws.ec2.functions; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -28,11 +28,11 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.aws.AWSResponseException; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.compute.domain.RegionAndName; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; import org.jclouds.logging.Logger; import com.google.common.base.Function; @@ -47,11 +47,11 @@ public class CreatePlacementGroupIfNeeded implements Function placementGroupAvailable; @Inject - public CreatePlacementGroupIfNeeded(EC2Client ec2Client, + public CreatePlacementGroupIfNeeded(AWSEC2Client ec2Client, @Named("AVAILABLE") Predicate placementGroupAvailable) { this.ec2Client = ec2Client; this.placementGroupAvailable = placementGroupAvailable; diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptions.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptions.java new file mode 100644 index 0000000000..a4cf04183c --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptions.java @@ -0,0 +1,220 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.options; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Set; + +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.options.RunInstancesOptions; + +/** + * Contains options supported in the Form API for the RunInstances operation.

+ * Usage

The recommended way to instantiate a RunInstancesOptions object is to statically + * import RunInstancesOptions.Builder.* and invoke a static creation method followed by an instance + * mutator (if needed): + *

+ * + * import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.* + *

+ * EC2Client connection = // get connection + * Future instances = connection.runInstances(executableBy("123125").imageIds(1000, 1004)); + * + * + * @author Adrian Cole + * @see + */ +public class AWSRunInstancesOptions extends RunInstancesOptions { + public static final AWSRunInstancesOptions NONE = new AWSRunInstancesOptions(); + + /** + * Specifies the name of an existing placement group you want to launch the instance into (for + * cluster compute instances). + * + * @param placementGroup + * name of an existing placement group + */ + public AWSRunInstancesOptions inPlacementGroup(String placementGroup) { + formParameters.put("Placement.GroupName", checkNotNull(placementGroup, "placementGroup")); + return this; + } + + String getPlacementGroup() { + return getFirstFormOrNull("Placement.GroupName"); + } + + /** + * Enables monitoring for the instance. + */ + public AWSRunInstancesOptions enableMonitoring() { + formParameters.put("Monitoring.Enabled", "true"); + return this; + } + + String getMonitoringEnabled() { + return getFirstFormOrNull("Monitoring.Enabled"); + } + + /** + * Specifies the subnet ID within which to launch the instance(s) for Amazon Virtual Private + * Cloud. + */ + public AWSRunInstancesOptions withSubnetId(String subnetId) { + formParameters.put("SubnetId", checkNotNull(subnetId, "subnetId")); + return this; + } + + String getSubnetId() { + return getFirstFormOrNull("SubnetId"); + } + + public static class Builder extends RunInstancesOptions.Builder { + + /** + * @see AWSRunInstancesOptions#inPlacementGroup(String) + */ + public static AWSRunInstancesOptions inPlacementGroup(String placementGroup) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.inPlacementGroup(placementGroup); + } + + /** + * @see AWSRunInstancesOptions#enableMonitoring() + */ + public static AWSRunInstancesOptions enableMonitoring() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.enableMonitoring(); + } + + /** + * @see AWSRunInstancesOptions#withSubnetId(String) + */ + public static AWSRunInstancesOptions withSubnetId(String subnetId) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withSubnetId(subnetId); + } + + /** + * @see AWSRunInstancesOptions#withKeyName(String) + */ + public static AWSRunInstancesOptions withKeyName(String keyName) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withKeyName(keyName); + } + + /** + * @see AWSRunInstancesOptions#withSecurityGroup(String) + */ + public static AWSRunInstancesOptions withSecurityGroup(String securityGroup) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withSecurityGroup(securityGroup); + } + + /** + * @see AWSRunInstancesOptions#withUserData(byte []) + */ + public static AWSRunInstancesOptions withUserData(byte[] unencodedData) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withUserData(unencodedData); + } + + /** + * @see AWSRunInstancesOptions#asType(InstanceType) + */ + public static AWSRunInstancesOptions asType(String instanceType) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.asType(instanceType); + } + + /** + * @see AWSRunInstancesOptions#withKernelId(String) + */ + public static AWSRunInstancesOptions withKernelId(String kernelId) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withKernelId(kernelId); + } + + /** + * @see AWSRunInstancesOptions#withRamdisk(String) + */ + public static AWSRunInstancesOptions withRamdisk(String ramdiskId) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withRamdisk(ramdiskId); + } + + /** + * @see AWSRunInstancesOptions#withBlockDeviceMappings(Set mappings) + */ + public static AWSRunInstancesOptions withBlockDeviceMappings(Set mappings) { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + return options.withBlockDeviceMappings(mappings); + } + + } + + @Override + public AWSRunInstancesOptions withBlockDeviceMappings(Set mappings) { + return AWSRunInstancesOptions.class.cast(super.withBlockDeviceMappings(mappings)); + } + + @Override + public AWSRunInstancesOptions withKernelId(String kernelId) { + return AWSRunInstancesOptions.class.cast(super.withKernelId(kernelId)); + } + + @Override + public AWSRunInstancesOptions withKeyName(String keyName) { + return AWSRunInstancesOptions.class.cast(super.withKeyName(keyName)); + } + + @Override + public AWSRunInstancesOptions withRamdisk(String ramDiskId) { + return AWSRunInstancesOptions.class.cast(super.withRamdisk(ramDiskId)); + } + + @Override + public AWSRunInstancesOptions withSecurityGroup(String securityGroup) { + return AWSRunInstancesOptions.class.cast(super.withSecurityGroup(securityGroup)); + } + + @Override + public AWSRunInstancesOptions withSecurityGroups(Iterable securityGroups) { + return AWSRunInstancesOptions.class.cast(super.withSecurityGroups(securityGroups)); + } + + @Override + public AWSRunInstancesOptions withSecurityGroups(String... securityGroups) { + return AWSRunInstancesOptions.class.cast(super.withSecurityGroups(securityGroups)); + } + + @Override + public AWSRunInstancesOptions withUserData(byte[] unencodedData) { + return AWSRunInstancesOptions.class.cast(super.withUserData(unencodedData)); + } + + @Override + public AWSRunInstancesOptions asType(String type) { + return AWSRunInstancesOptions.class.cast(super.asType(type)); + } +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupAvailable.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupAvailable.java similarity index 90% rename from apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupAvailable.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupAvailable.java index 21ebc2057c..9acdd978cd 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupAvailable.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupAvailable.java @@ -17,15 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.predicates; +package org.jclouds.aws.ec2.predicates; import java.util.NoSuchElementException; import javax.annotation.Resource; import javax.inject.Singleton; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.logging.Logger; import org.jclouds.rest.ResourceNotFoundException; @@ -41,13 +41,13 @@ import com.google.inject.Inject; @Singleton public class PlacementGroupAvailable implements Predicate { - private final EC2Client client; + private final AWSEC2Client client; @Resource protected Logger logger = Logger.NULL; @Inject - public PlacementGroupAvailable(EC2Client client) { + public PlacementGroupAvailable(AWSEC2Client client) { this.client = client; } diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupDeleted.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupDeleted.java similarity index 89% rename from apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupDeleted.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupDeleted.java index e3cfa0bfdd..b8e6c86564 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/predicates/PlacementGroupDeleted.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/predicates/PlacementGroupDeleted.java @@ -17,15 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.predicates; +package org.jclouds.aws.ec2.predicates; import java.util.NoSuchElementException; import javax.annotation.Resource; import javax.inject.Singleton; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.logging.Logger; import com.google.common.base.Predicate; @@ -40,13 +40,13 @@ import com.google.inject.Inject; @Singleton public class PlacementGroupDeleted implements Predicate { - private final EC2Client client; + private final AWSEC2Client client; @Resource protected Logger logger = Logger.NULL; @Inject - public PlacementGroupDeleted(EC2Client client) { + public PlacementGroupDeleted(AWSEC2Client client) { this.client = client; } diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/reference/AWSEC2Constants.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/reference/AWSEC2Constants.java new file mode 100644 index 0000000000..a410666c32 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/reference/AWSEC2Constants.java @@ -0,0 +1,58 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.reference; + +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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. + * ==================================================================== + */ + +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.reference.EC2Constants; + +/** + * Configuration properties and constants used in EC2 connections. + * + * @author Adrian Cole + */ +public interface AWSEC2Constants extends EC2Constants { + + /** + * amis that work on the cluster instance type + * + * @see InstanceType.CC1_4XLARGE + */ + public static final String PROPERTY_EC2_CC_AMIs = "jclouds.ec2.cc-amis"; + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClient.java new file mode 100644 index 0000000000..9962e31246 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClient.java @@ -0,0 +1,94 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import static org.jclouds.aws.reference.FormParameters.ACTION; +import static org.jclouds.aws.reference.FormParameters.VERSION; + +import java.util.Set; + +import javax.annotation.Nullable; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.xml.ProductCodesHandler; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.ec2.binders.BindProductCodesToIndexedFormParams; +import org.jclouds.ec2.services.AMIAsyncClient; +import org.jclouds.ec2.services.AMIClient; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.EndpointParam; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides access to AMI Services. + *

+ * + * @author Adrian Cole + */ +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION) +@VirtualHost +public interface AWSAMIAsyncClient extends AMIAsyncClient { + // TODO make AWSImage as it has product codes... + + /** + * @see AMIClient#getProductCodesForImageInRegion + */ + @POST + @Path("/") + @FormParams(keys = { ACTION, "Attribute" }, values = { "DescribeImageAttribute", "productCodes" }) + @XMLResponseParser(ProductCodesHandler.class) + ListenableFuture> getProductCodesForImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @FormParam("ImageId") String imageId); + + /** + * @see AMIClient#addProductCodesToImageInRegion + */ + @POST + @Path("/") + @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "add", + "productCodes" }) + ListenableFuture addProductCodesToImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, + @FormParam("ImageId") String imageId); + + /** + * @see AMIClient#removeProductCodesToImageInRegion + */ + @POST + @Path("/") + @FormParams(keys = { ACTION, "OperationType", "Attribute" }, values = { "ModifyImageAttribute", "remove", + "productCodes" }) + ListenableFuture removeProductCodesFromImageInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindProductCodesToIndexedFormParams.class) Iterable productCodes, + @FormParam("ImageId") String imageId); +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIClient.java new file mode 100644 index 0000000000..aa66609d9a --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSAMIClient.java @@ -0,0 +1,94 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nullable; + +import org.jclouds.concurrent.Timeout; +import org.jclouds.ec2.options.DescribeImagesOptions; +import org.jclouds.ec2.services.AMIClient; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS) +public interface AWSAMIClient extends AMIClient{ + + + /** + * Returns the Product Codes of an image. + * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. + * @param imageId + * The ID of the AMI for which an attribute will be described + * @see #describeImages + * @see #modifyImageAttribute + * @see #resetImageAttribute + * @see + * @see DescribeImagesOptions + */ + Set getProductCodesForImageInRegion(@Nullable String region, String imageId); + + + /** + * Adds {@code productCode}s to an AMI. + * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. + * @param productCodes + * Product Codes + * @param imageId + * The AMI ID. + * + * @see #removeProductCodesFromImage + * @see #describeImageAttribute + * @see #resetImageAttribute + * @see + */ + void addProductCodesToImageInRegion(@Nullable String region, Iterable productCodes, String imageId); + + /** + * Removes {@code productCode}s from an AMI. + * + * @param region + * AMIs are tied to the Region where its files are located within Amazon S3. + * @param productCodes + * Product Codes + * @param imageId + * The AMI ID. + * + * @see #addProductCodesToImage + * @see #describeImageAttribute + * @see #resetImageAttribute + * @see + */ + void removeProductCodesFromImageInRegion(@Nullable String region, Iterable productCodes, + String imageId); +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClient.java new file mode 100644 index 0000000000..f01ecedbfd --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClient.java @@ -0,0 +1,92 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import static org.jclouds.aws.reference.FormParameters.ACTION; +import static org.jclouds.aws.reference.FormParameters.VERSION; + +import java.util.Set; + +import javax.annotation.Nullable; +import javax.ws.rs.FormParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.xml.AWSDescribeInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.AWSRunInstancesResponseHandler; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams; +import org.jclouds.ec2.binders.IfNotNullBindAvailabilityZoneToFormParam; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.services.InstanceAsyncClient; +import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; +import org.jclouds.rest.annotations.BinderParam; +import org.jclouds.rest.annotations.EndpointParam; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.FormParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.VirtualHost; +import org.jclouds.rest.annotations.XMLResponseParser; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides access to EC2 Instance Services via their REST API. + *

+ * + * @author Adrian Cole + */ +@RequestFilters(FormSigner.class) +@FormParams(keys = VERSION, values = AWSEC2AsyncClient.VERSION) +@VirtualHost +public interface AWSInstanceAsyncClient extends InstanceAsyncClient { + + /** + * @see AWSInstanceClient#describeInstancesInRegion + */ + @Override + @POST + @Path("/") + @FormParams(keys = ACTION, values = "DescribeInstances") + @XMLResponseParser(AWSDescribeInstancesResponseHandler.class) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture>> describeInstancesInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @BinderParam(BindInstanceIdsToIndexedFormParams.class) String... instanceIds); + + /** + * @see AWSInstanceClient#runInstancesInRegion + */ + @Override + @POST + @Path("/") + @FormParams(keys = ACTION, values = "RunInstances") + @XMLResponseParser(AWSRunInstancesResponseHandler.class) + ListenableFuture> runInstancesInRegion( + @EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region, + @Nullable @BinderParam(IfNotNullBindAvailabilityZoneToFormParam.class) String nullableAvailabilityZone, + @FormParam("ImageId") String imageId, @FormParam("MinCount") int minCount, + @FormParam("MaxCount") int maxCount, RunInstancesOptions... options); + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceClient.java new file mode 100644 index 0000000000..185fb04567 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/AWSInstanceClient.java @@ -0,0 +1,51 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Nullable; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.concurrent.Timeout; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.services.InstanceClient; + +/** + * Provides access to EC2 via their REST API. + *

+ * + * @author Adrian Cole + */ +@Timeout(duration = 90, timeUnit = TimeUnit.SECONDS) +public interface AWSInstanceClient extends InstanceClient { + + @Override + Set> describeInstancesInRegion(@Nullable String region, + String... instanceIds); + + @Override + Reservation runInstancesInRegion(@Nullable String region, + @Nullable String nullableAvailabilityZone, String imageId, int minCount, int maxCount, + RunInstancesOptions... options); + +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java similarity index 95% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringAsyncClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java index 6e3264d3c1..0c42604f61 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringAsyncClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringAsyncClient.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static org.jclouds.aws.reference.FormParameters.ACTION; import static org.jclouds.aws.reference.FormParameters.VERSION; @@ -29,11 +29,11 @@ import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.aws.filters.FormSigner; import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.binders.BindInstanceIdsToIndexedFormParams; -import org.jclouds.ec2.domain.MonitoringState; -import org.jclouds.ec2.xml.MonitoringStateHandler; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.EndpointParam; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java similarity index 94% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java index a9b11bfae5..2b272216fb 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/MonitoringClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/MonitoringClient.java @@ -17,14 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.util.Map; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.ec2.services.InstanceClient; +import org.jclouds.aws.ec2.domain.MonitoringState; import org.jclouds.concurrent.Timeout; /** diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupAsyncClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClient.java similarity index 96% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupAsyncClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClient.java index a5f431cf88..45adce9236 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupAsyncClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClient.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static org.jclouds.aws.reference.FormParameters.ACTION; import static org.jclouds.aws.reference.FormParameters.VERSION; @@ -29,11 +29,11 @@ import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler; import org.jclouds.aws.filters.FormSigner; import org.jclouds.ec2.EC2AsyncClient; import org.jclouds.ec2.binders.BindGroupNamesToIndexedFormParams; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.xml.DescribePlacementGroupsResponseHandler; import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.EndpointParam; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupClient.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupClient.java similarity index 97% rename from apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupClient.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupClient.java index 4e07ee137c..b02357839a 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/services/PlacementGroupClient.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/services/PlacementGroupClient.java @@ -17,14 +17,14 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.concurrent.Timeout; /** diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandler.java new file mode 100644 index 0000000000..40553a7302 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandler.java @@ -0,0 +1,71 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.xml; + +import java.util.Set; + +import javax.inject.Inject; + +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.domain.RunningInstance.Builder; +import org.jclouds.location.Region; + +import com.google.common.collect.Sets; +import com.google.inject.Provider; + +/** + * Parses the following XML document: + *

+ * DescribeImagesResponse xmlns="http: + * + * @author Adrian Cole + * @see + * RunInstancesResponse xmlns="http: + * + * @author Adrian Cole + * @see extends BaseReservationHandler { + + public BaseAWSReservationHandler(DateService dateService, String defaultRegion, Provider builderProvider) { + super(dateService, defaultRegion, builderProvider); + } + + protected String currentOrNull() { + String returnVal = currentText.toString().trim(); + return returnVal.equals("") ? null : returnVal; + } + + public void endElement(String uri, String name, String qName) { + if (qName.equals("state")) { + builder().monitoringState(MonitoringState.fromValue(currentOrNull())); + } else if (qName.equals("groupName")) { + builder().placementGroup(currentOrNull()); + } else if (qName.equals("subnetId")) { + builder().subnetId(currentOrNull()); + } else if (qName.equals("spotInstanceRequestId")) { + builder().spotInstanceRequestId(currentOrNull()); + } else if (qName.equals("vpcId")) { + builder().vpcId(currentOrNull()); + } else if (qName.equals("productCode")) { + builder().productCode(currentOrNull()); + } + super.endElement(uri, name, qName); + } + + @Override + protected AWSRunningInstance.Builder builder() { + return AWSRunningInstance.Builder.class.cast(builder); + } + + public void characters(char ch[], int start, int length) { + super.characters(ch, start, length); + } + +} diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandler.java similarity index 96% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandler.java index 38f6484a45..7596b05957 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandler.java @@ -17,13 +17,13 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Set; import javax.inject.Inject; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ParseSax.HandlerWithResult; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java similarity index 98% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java index 9b3f2b1590..c036d71c47 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandler.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Set; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/MonitoringStateHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/MonitoringStateHandler.java similarity index 95% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/MonitoringStateHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/MonitoringStateHandler.java index cfa7e8ec60..9e6e6626b6 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/MonitoringStateHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/MonitoringStateHandler.java @@ -17,11 +17,11 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Map; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.domain.MonitoringState; import org.jclouds.http.functions.ParseSax; import com.google.common.collect.Maps; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/PlacementGroupHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/PlacementGroupHandler.java similarity index 94% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/PlacementGroupHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/PlacementGroupHandler.java index ce2cc6cf66..e466204b6c 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/PlacementGroupHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/PlacementGroupHandler.java @@ -17,12 +17,12 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import javax.inject.Inject; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; import org.jclouds.aws.util.AWSUtils; import org.jclouds.date.DateService; import org.jclouds.http.functions.ParseSax; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ProductCodesHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ProductCodesHandler.java similarity index 98% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/ProductCodesHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ProductCodesHandler.java index 820fe74ad1..6f9e76722d 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ProductCodesHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ProductCodesHandler.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import java.util.Set; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ReservedInstancesOfferingHandler.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ReservedInstancesOfferingHandler.java similarity index 99% rename from apis/ec2/src/main/java/org/jclouds/ec2/xml/ReservedInstancesOfferingHandler.java rename to providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ReservedInstancesOfferingHandler.java index f29c1fb567..c09d409b4b 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/ReservedInstancesOfferingHandler.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/xml/ReservedInstancesOfferingHandler.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import javax.inject.Inject; diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2AsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2AsyncClientTest.java new file mode 100644 index 0000000000..d17725be56 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2AsyncClientTest.java @@ -0,0 +1,91 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2; + +import java.io.IOException; +import java.util.concurrent.ExecutionException; + +import org.jclouds.aws.ec2.services.BaseAWSEC2AsyncClientTest; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code AWSEC2AsyncClient} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSEC2AsyncClientTest") +public class AWSEC2AsyncClientTest extends BaseAWSEC2AsyncClientTest { + + private AWSEC2AsyncClient asyncClient; + private AWSEC2Client syncClient; + + public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException { + assert syncClient.getAMIServices() != null; + assert syncClient.getAvailabilityZoneAndRegionServices() != null; + assert syncClient.getElasticBlockStoreServices() != null; + assert syncClient.getElasticIPAddressServices() != null; + assert syncClient.getInstanceServices() != null; + assert syncClient.getKeyPairServices() != null; + assert syncClient.getMonitoringServices() != null; + assert syncClient.getSecurityGroupServices() != null; + assert syncClient.getPlacementGroupServices() != null; + assert syncClient.getWindowsServices() != null; + + } + + public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException { + assert asyncClient.getAMIServices() != null; + assert asyncClient.getAvailabilityZoneAndRegionServices() != null; + assert asyncClient.getElasticBlockStoreServices() != null; + assert asyncClient.getElasticIPAddressServices() != null; + assert asyncClient.getInstanceServices() != null; + assert asyncClient.getKeyPairServices() != null; + assert asyncClient.getMonitoringServices() != null; + assert asyncClient.getSecurityGroupServices() != null; + assert asyncClient.getPlacementGroupServices() != null; + assert asyncClient.getWindowsServices() != null; + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + + @BeforeClass + @Override + protected void setupFactory() throws IOException { + super.setupFactory(); + asyncClient = injector.getInstance(AWSEC2AsyncClient.class); + syncClient = injector.getInstance(AWSEC2Client.class); + } + + @Override + protected void checkFilters(HttpRequest request) { + + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java index bf214e6507..937339785f 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeServiceLiveTest.java @@ -19,9 +19,30 @@ package org.jclouds.aws.ec2.compute; +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.compute.predicates.NodePredicates; +import org.jclouds.domain.Credentials; +import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest; +import org.jclouds.ec2.domain.IpProtocol; +import org.jclouds.ec2.domain.KeyPair; +import org.jclouds.ec2.domain.SecurityGroup; +import org.jclouds.ec2.services.InstanceClient; +import org.jclouds.ec2.services.KeyPairClient; +import org.jclouds.ec2.services.SecurityGroupClient; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSortedSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; + /** * * @author Adrian Cole @@ -31,7 +52,152 @@ public class AWSEC2ComputeServiceLiveTest extends EC2ComputeServiceLiveTest { public AWSEC2ComputeServiceLiveTest() { provider = "aws-ec2"; - tag = "ec2"; + group = "ec2"; + } + + @Override + @Test(enabled = true, dependsOnMethods = "testCompareSizes") + public void testExtendedOptionsAndLogin() throws Exception { + SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getSecurityGroupServices(); + + KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getKeyPairServices(); + + InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getInstanceServices(); + + String group = this.group + "o"; + + TemplateOptions options = client.templateOptions(); + + // Date before = new Date(); + + options.as(AWSEC2TemplateOptions.class).securityGroups(group); + options.as(AWSEC2TemplateOptions.class).keyPair(group); + options.as(AWSEC2TemplateOptions.class).enableMonitoring(); + + String startedId = null; + try { + cleanupExtendedStuff(securityGroupClient, keyPairClient, group); + + // create a security group that allows ssh in so that our scripts later + // will work + securityGroupClient.createSecurityGroupInRegion(null, group, group); + securityGroupClient.authorizeSecurityGroupIngressInRegion(null, group, IpProtocol.TCP, 22, 22, "0.0.0.0/0"); + + // create a keypair to pass in as well + KeyPair result = keyPairClient.createKeyPairInRegion(null, group); + + Set nodes = client.createNodesInGroup(group, 1, options); + NodeMetadata first = Iterables.get(nodes, 0); + assert first.getCredentials() != null : first; + assert first.getCredentials().identity != null : first; + + startedId = Iterables.getOnlyElement(nodes).getProviderId(); + + AWSRunningInstance instance = AWSRunningInstance.class.cast(getInstance(instanceClient, startedId)); + + assertEquals(instance.getKeyName(), group); + assertEquals(instance.getMonitoringState(), MonitoringState.ENABLED); + + // TODO when the cloudwatchclient is finished + + // RestContext monitoringContext = new + // RestContextFactory().createContext( + // "cloudwatch", identity, credential, ImmutableSet. of(new Log4JLoggingModule())); + // + // try { + // Set datapoints = + // monitoringContext.getApi().getMetricStatisticsInRegion(instance.getRegion(), + // "CPUUtilization", before, new Date(), 60, "Average"); + // assert datapoints != null; + // } finally { + // monitoringContext.close(); + // } + + // make sure we made our dummy group and also let in the user's group + assertEquals(Sets.newTreeSet(instance.getGroupIds()), ImmutableSortedSet. of("jclouds#" + group + "#" + + instance.getRegion(), group)); + + // make sure our dummy group has no rules + SecurityGroup secgroup = Iterables.getOnlyElement(securityGroupClient.describeSecurityGroupsInRegion(null, + "jclouds#" +group + "#" + instance.getRegion())); + assert secgroup.getIpPermissions().size() == 0 : secgroup; + + // try to run a script with the original keyPair + runScriptWithCreds(group, first.getOperatingSystem(), new Credentials(first.getCredentials().identity, result + .getKeyMaterial())); + + } finally { + client.destroyNodesMatching(NodePredicates.inGroup(group)); + if (startedId != null) { + // ensure we didn't delete these resources! + assertEquals(keyPairClient.describeKeyPairsInRegion(null, group).size(), 1); + assertEquals(securityGroupClient.describeSecurityGroupsInRegion(null, group).size(), 1); + } + cleanupExtendedStuff(securityGroupClient, keyPairClient, group); + } + + } + @Test(enabled = true, dependsOnMethods = "testCompareSizes") + public void testExtendedOptionsWithSubnetId() throws Exception { + + String subnetId = System.getProperty("test.subnetId"); + if (subnetId == null) { + // Skip test and return + return; + } + SecurityGroupClient securityGroupClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getSecurityGroupServices(); + + KeyPairClient keyPairClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getKeyPairServices(); + + InstanceClient instanceClient = EC2Client.class.cast(context.getProviderSpecificContext().getApi()) + .getInstanceServices(); + + String group = this.group + "g"; + + TemplateOptions options = client.templateOptions(); + + // options.as(AWSEC2TemplateOptions.class).securityGroups(group); + options.as(AWSEC2TemplateOptions.class).keyPair(group); + options.as(AWSEC2TemplateOptions.class).subnetId(subnetId); + + String startedId = null; + String nodeId = null; + try { + cleanupExtendedStuff(securityGroupClient, keyPairClient, group); + + // create the security group + // securityGroupClient.createSecurityGroupInRegion(null, group, group); + + // create a keypair to pass in as well + keyPairClient.createKeyPairInRegion(null, group); + + Set nodes = client.createNodesInGroup(group, 1, options); + + NodeMetadata first = Iterables.get(nodes, 0); + assert first.getCredentials() != null : first; + assert first.getCredentials().identity != null : first; + + startedId = Iterables.getOnlyElement(nodes).getProviderId(); + nodeId = Iterables.getOnlyElement(nodes).getId(); + + AWSRunningInstance instance = AWSRunningInstance.class.cast(getInstance(instanceClient, startedId)); + + assertEquals(instance.getSubnetId(), subnetId); + + } finally { + if (nodeId != null) + client.destroyNode(nodeId); + if (startedId != null) { + // ensure we didn't delete these resources! + assertEquals(keyPairClient.describeKeyPairsInRegion(null, group).size(), 1); + } + cleanupExtendedStuff(securityGroupClient, keyPairClient, group); + } } } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java index e0267fbf55..a67ffedbb5 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/AWSEC2TemplateBuilderLiveTest.java @@ -20,11 +20,14 @@ package org.jclouds.aws.ec2.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import static org.testng.Assert.assertEquals; import java.io.IOException; import java.util.Properties; +import java.util.Set; +import org.jclouds.aws.domain.Region; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; @@ -57,9 +60,16 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Override public boolean apply(OsFamilyVersion64Bit input) { - return input.family == OsFamily.RHEL || // - (input.family == OsFamily.CENTOS && !input.version.matches("5.[42]")) || // - (input.family == OsFamily.WINDOWS && !input.version.matches("200[38]")); + switch (input.family) { + case UBUNTU: + return false; + case CENTOS: + return !(input.version.matches("5.[42]") || input.version.equals("")); + case WINDOWS: + return !(input.version.matches("200[38]") || input.version.equals("")); + default: + return true; + } } }; @@ -69,13 +79,12 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { public void testTemplateBuilderM1SMALLWithDescription() { 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(), "20110122"); assertEquals(template.getImage().getUserMetadata().get("rootDeviceType"), "instance-store"); assertEquals(template.getLocation().getId(), "us-east-1"); assertEquals(getCores(template.getHardware()), 1.0d); @@ -86,8 +95,8 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Test public void testTemplateBuilderCanUseImageIdAndhardwareId() { - Template template = context.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5") - .hardwareId(InstanceType.M2_2XLARGE).build(); + Template template = context.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").hardwareId( + InstanceType.M2_2XLARGE).build(); System.out.println(template.getHardware()); assert (template.getImage().getProviderId().startsWith("ami-")) : template; @@ -119,11 +128,12 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { @Test public void testTemplateBuilderMicro() throws IOException { - Template microTemplate = context.getComputeService().templateBuilder().hardwareId(InstanceType.T1_MICRO).build(); + Template microTemplate = context.getComputeService().templateBuilder().hardwareId(InstanceType.T1_MICRO) + .osFamily(OsFamily.UBUNTU).osVersionMatches("10.10").os64Bit(true).build(); assert (microTemplate.getImage().getProviderId().startsWith("ami-")) : microTemplate; - assertEquals(microTemplate.getImage().getOperatingSystem().getVersion(), "9.10"); - assertEquals(microTemplate.getImage().getOperatingSystem().is64Bit(), false); + assertEquals(microTemplate.getImage().getOperatingSystem().getVersion(), "10.10"); + assertEquals(microTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(microTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(microTemplate.getImage().getUserMetadata().get("rootDeviceType"), "ebs"); assertEquals(microTemplate.getLocation().getId(), "us-east-1"); @@ -139,8 +149,8 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { // set owners to nothing overrides.setProperty(EC2Constants.PROPERTY_EC2_AMI_OWNERS, ""); - context = new ComputeServiceContextFactory().createContext(provider, - ImmutableSet. of(new Log4JLoggingModule()), overrides); + context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet + . of(new Log4JLoggingModule()), overrides); assertEquals(context.getComputeService().listImages().size(), 0); @@ -166,4 +176,40 @@ public class AWSEC2TemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { } } + @Test + public void testTemplateBuilderWithLessRegions() throws IOException { + ComputeServiceContext context = null; + try { + Properties overrides = setupProperties(); + // set regions to only 1 + overrides.setProperty(PROPERTY_REGIONS, Region.US_EAST_1); + + context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet + . of(new Log4JLoggingModule()), overrides); + + assert context.getComputeService().listImages().size() < this.context.getComputeService().listImages().size(); + + Template template = context.getComputeService().templateBuilder().imageId("us-east-1/ami-ccb35ea5").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()), 2.0d); + assertEquals(template.getHardware().getId(), "m1.large"); // because it is 64bit + + } finally { + if (context != null) + context.close(); + } + } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-VA", "US-CA", "IE", "SG"); + } + } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/options/AWSEC2TemplateOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/options/AWSEC2TemplateOptionsTest.java new file mode 100644 index 0000000000..1445940736 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/options/AWSEC2TemplateOptionsTest.java @@ -0,0 +1,313 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.compute.options; + +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.authorizePublicKey; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.blockOnPort; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.enableMonitoring; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.inboundPorts; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.installPrivateKey; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.keyPair; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.noKeyPair; +import static org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions.Builder.securityGroups; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.compute.options.TemplateOptions; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests possible uses of AWSEC2TemplateOptions and AWSEC2TemplateOptions.Builder.* + * + * @author Adrian Cole + */ +public class AWSEC2TemplateOptionsTest { + + public void testAs() { + TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.as(AWSEC2TemplateOptions.class), options); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsIterableBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(ImmutableSet.of("group1", "")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsIterableEmptyNotOk() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(ImmutableSet. of()); + } + + @Test + public void testsecurityGroupsIterable() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(ImmutableSet.of("group1", "group2")); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + + } + + @Test + public void testsecurityGroupsIterableStatic() { + AWSEC2TemplateOptions options = securityGroups(ImmutableSet.of("group1", "group2")); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsVarArgsBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups("mygroup", ""); + } + + @Test + public void testsecurityGroupsVarArgs() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups("group1", "group2"); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testsecurityGroupsVarArgsEmptyNotOk() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.securityGroups(); + } + + @Test + public void testDefaultGroupsVarArgsEmpty() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getGroupIds(), ImmutableSet.of()); + } + + @Test + public void testsecurityGroupsVarArgsStatic() { + AWSEC2TemplateOptions options = securityGroups("group1", "group2"); + assertEquals(options.getGroupIds(), ImmutableSet.of("group1", "group2")); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testkeyPairBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.keyPair(""); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testkeyPairAndNoKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.keyPair("mykeypair"); + options.noKeyPair(); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testNoKeyPairAndKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.noKeyPair(); + options.keyPair("mykeypair"); + } + + @Test + public void testkeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.keyPair("mykeypair"); + assertEquals(options.getKeyPair(), "mykeypair"); + } + + @Test + public void testNullkeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getKeyPair(), null); + } + + @Test + public void testkeyPairStatic() { + AWSEC2TemplateOptions options = keyPair("mykeypair"); + assertEquals(options.getKeyPair(), "mykeypair"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testkeyPairNPE() { + keyPair(null); + } + + @Test + public void testnoKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.noKeyPair(); + assertEquals(options.getKeyPair(), null); + assert !options.shouldAutomaticallyCreateKeyPair(); + } + + @Test + public void testFalsenoKeyPair() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getKeyPair(), null); + assert options.shouldAutomaticallyCreateKeyPair(); + } + + @Test + public void testnoKeyPairStatic() { + AWSEC2TemplateOptions options = noKeyPair(); + assertEquals(options.getKeyPair(), null); + assert !options.shouldAutomaticallyCreateKeyPair(); + } + + @Test + public void testMonitoringEnabledDefault() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assert !options.isMonitoringEnabled(); + } + + @Test + public void testMonitoringEnabled() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.enableMonitoring(); + assert options.isMonitoringEnabled(); + } + + @Test + public void testEnableMonitoringStatic() { + AWSEC2TemplateOptions options = enableMonitoring(); + assertEquals(options.getKeyPair(), null); + assert options.isMonitoringEnabled(); + } + + // superclass tests + @Test(expectedExceptions = IllegalArgumentException.class) + public void testinstallPrivateKeyBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.installPrivateKey("whompy"); + } + + @Test + public void testinstallPrivateKey() throws IOException { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); + } + + @Test + public void testNullinstallPrivateKey() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getPrivateKey(), null); + } + + @Test + public void testinstallPrivateKeyStatic() throws IOException { + AWSEC2TemplateOptions options = installPrivateKey("-----BEGIN RSA PRIVATE KEY-----"); + assertEquals(options.getPrivateKey(), "-----BEGIN RSA PRIVATE KEY-----"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testinstallPrivateKeyNPE() { + installPrivateKey(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testauthorizePublicKeyBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.authorizePublicKey("whompy"); + } + + @Test + public void testauthorizePublicKey() throws IOException { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.authorizePublicKey("ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); + } + + @Test + public void testNullauthorizePublicKey() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getPublicKey(), null); + } + + @Test + public void testauthorizePublicKeyStatic() throws IOException { + AWSEC2TemplateOptions options = authorizePublicKey("ssh-rsa"); + assertEquals(options.getPublicKey(), "ssh-rsa"); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testauthorizePublicKeyNPE() { + authorizePublicKey(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testblockOnPortBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.blockOnPort(-1, -1); + } + + @Test + public void testblockOnPort() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.blockOnPort(22, 30); + assertEquals(options.getPort(), 22); + assertEquals(options.getSeconds(), 30); + + } + + @Test + public void testNullblockOnPort() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getPort(), -1); + assertEquals(options.getSeconds(), -1); + } + + @Test + public void testblockOnPortStatic() { + AWSEC2TemplateOptions options = blockOnPort(22, 30); + assertEquals(options.getPort(), 22); + assertEquals(options.getSeconds(), 30); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testinboundPortsBadFormat() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.inboundPorts(-1, -1); + } + + @Test + public void testinboundPorts() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + options.inboundPorts(22, 30); + assertEquals(options.getInboundPorts()[0], 22); + assertEquals(options.getInboundPorts()[1], 30); + + } + + @Test + public void testDefaultOpen22() { + AWSEC2TemplateOptions options = new AWSEC2TemplateOptions(); + assertEquals(options.getInboundPorts()[0], 22); + } + + @Test + public void testinboundPortsStatic() { + AWSEC2TemplateOptions options = inboundPorts(22, 30); + assertEquals(options.getInboundPorts()[0], 22); + assertEquals(options.getInboundPorts()[1], 30); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/strategy/AWSEC2ImageParserTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java similarity index 94% rename from providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/strategy/AWSEC2ImageParserTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java index 2de043d677..cbb9dd98a0 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/strategy/AWSEC2ImageParserTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.aws.ec2.strategy; +package org.jclouds.aws.ec2.compute.strategy; import static org.testng.Assert.assertEquals; @@ -31,8 +31,8 @@ import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.ec2.compute.functions.EC2ImageParser; import org.jclouds.ec2.compute.strategy.EC2PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.ec2.domain.Image; @@ -126,11 +126,11 @@ public class AWSEC2ImageParserTest { assertEquals( 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\",\"iso3166Codes\":[],\"metadata\":{}},\"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\"}}"); + "{\"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\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}"); } public void testParseAmznImage() { @@ -153,7 +153,8 @@ public class AWSEC2ImageParserTest { ImmutableMap.of("owner", "137112412989", "rootDeviceType", "ebs")).build()); } - static Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", "us-east-1", null); + static Location defaultLocation = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1").description( + "us-east-1").build(); public static Set convertImages(String resource) { @@ -164,7 +165,7 @@ public class AWSEC2ImageParserTest { Set result = DescribeImagesResponseHandlerTest.parseImages(resource); EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, Suppliers.> ofInstance(ImmutableSet. of(defaultLocation)), Suppliers - .ofInstance(defaultLocation), "ec2", new AWSEC2ReviseParsedImage(map)); + .ofInstance(defaultLocation), new AWSEC2ReviseParsedImage(map)); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); } } diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java similarity index 71% rename from apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java index b023e570d0..244f481b2a 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.compute.strategy; +package org.jclouds.aws.ec2.compute.strategy; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; @@ -29,7 +29,13 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.Set; +import javax.inject.Provider; + import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.compute.AWSEC2TemplateOptions; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.functions.CreatePlacementGroupIfNeeded; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Template; import org.jclouds.compute.options.TemplateOptions; @@ -37,13 +43,11 @@ import org.jclouds.ec2.compute.EC2TemplateBuilderTest; import org.jclouds.ec2.compute.domain.EC2HardwareBuilder; import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.domain.RegionNameAndIngressRules; -import org.jclouds.ec2.compute.functions.CreatePlacementGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreateSecurityGroupIfNeeded; import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; -import org.jclouds.ec2.compute.options.EC2TemplateOptions; +import org.jclouds.ec2.compute.strategy.CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions; import org.jclouds.ec2.domain.BlockDeviceMapping; import org.jclouds.ec2.domain.KeyPair; -import org.jclouds.ec2.domain.PlacementGroup; import org.jclouds.ec2.options.RunInstancesOptions; import org.jclouds.encryption.internal.Base64; import org.testng.annotations.Test; @@ -56,6 +60,14 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit") public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsTest { + private static final Provider OPTIONS_PROVIDER = new javax.inject.Provider() { + + @Override + public RunInstancesOptions get() { + return new AWSRunInstancesOptions(); + } + + }; public void testExecuteWithDefaultOptionsEC2() throws SecurityException, NoSuchMethodException { // setup constants @@ -68,31 +80,33 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class - .getDeclaredMethod("getProvider"), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -102,10 +116,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", - generatedGroup, "KeyName", systemGeneratedKeyPairName).entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName) + .entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -127,31 +140,35 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - generatedGroup); + generatedGroup); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -161,11 +178,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", - generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup) - .entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName, + "Placement.GroupName", generatedGroup).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -187,31 +202,35 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - generatedGroup); + generatedGroup); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -221,11 +240,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", - generatedGroup, "KeyName", systemGeneratedKeyPairName, "Placement.GroupName", generatedGroup) - .entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", generatedGroup, "KeyName", systemGeneratedKeyPairName, + "Placement.GroupName", generatedGroup).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -245,28 +262,32 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(options.getSubnetId()).andReturn("1"); expect(options.getUserData()).andReturn(null); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -276,10 +297,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SubnetId", "1", "KeyName", - systemGeneratedKeyPairName).entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SubnetId", "1", "KeyName", systemGeneratedKeyPairName).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -301,29 +320,33 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = createMock( - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, - new Method[] { - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, - TemplateOptions.class), - CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( - "getSecurityGroupsForTagAndOptions", String.class, String.class, TemplateOptions.class) }); + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class, new Method[] { + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getOptionsProvider"), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewKeyPairUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions.class.getDeclaredMethod( + "createNewPlacementGroupUnlessUserSpecifiedOtherwise", String.class, String.class, + TemplateOptions.class), + CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions.class + .getDeclaredMethod("getSecurityGroupsForTagAndOptions", String.class, String.class, + TemplateOptions.class) }); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); Template template = createMock(Template.class); // setup expectations + expect(strategy.getOptionsProvider()).andReturn(OPTIONS_PROVIDER); expect(template.getHardware()).andReturn(size).atLeastOnce(); expect(template.getOptions()).andReturn(options).atLeastOnce(); expect(options.getBlockDeviceMappings()).andReturn(ImmutableSet. of()).atLeastOnce(); expect(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options)).andReturn( - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); expect(strategy.getSecurityGroupsForTagAndOptions(region, tag, options)).andReturn(generatedGroups); expect(options.getSubnetId()).andReturn(null); expect(options.getUserData()).andReturn("hello".getBytes()); + expect(options.isMonitoringEnabled()).andReturn(false); // replay mocks replay(options); @@ -333,10 +356,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run RunInstancesOptions customize = strategy.execute(region, tag, template); assertEquals(customize.buildQueryParameters(), ImmutableMultimap. of()); - assertEquals( - customize.buildFormParameters().entries(), - ImmutableMultimap. of("InstanceType", size.getProviderId(), "SecurityGroup.1", "group", - "KeyName", systemGeneratedKeyPairName, "UserData", Base64.encodeBytes("hello".getBytes())).entries()); + assertEquals(customize.buildFormParameters().entries(), ImmutableMultimap. of("InstanceType", + size.getProviderId(), "SecurityGroup.1", "group", "KeyName", systemGeneratedKeyPairName, "UserData", + Base64.encodeBytes("hello".getBytes())).entries()); assertEquals(customize.buildMatrixParameters(), ImmutableMultimap. of()); assertEquals(customize.buildRequestHeaders(), ImmutableMultimap. of()); assertEquals(customize.buildStringPayload(), null); @@ -355,7 +377,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); KeyPair keyPair = createMock(KeyPair.class); // setup expectations @@ -385,7 +407,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); KeyPair keyPair = createMock(KeyPair.class); // setup expectations @@ -394,7 +416,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT expect(strategy.createUniqueKeyPair.apply(new RegionAndName(region, tag))).andReturn(keyPair); expect(keyPair.getKeyName()).andReturn(systemGeneratedKeyPairName).atLeastOnce(); expect(strategy.credentialsMap.put(new RegionAndName(region, systemGeneratedKeyPairName), keyPair)).andReturn( - null); + null); // replay mocks replay(options); @@ -403,7 +425,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run assertEquals(strategy.createNewKeyPairUnlessUserSpecifiedOtherwise(region, tag, options), - systemGeneratedKeyPairName); + systemGeneratedKeyPairName); // verify mocks verify(options); @@ -421,7 +443,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); KeyPair keyPair = createMock(KeyPair.class); // setup expectations @@ -455,13 +477,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); + ports, shouldAuthorizeSelf); expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); @@ -491,13 +513,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); + ports, shouldAuthorizeSelf); expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); expect(strategy.createSecurityGroupIfNeeded.apply(regionNameAndIngressRules)).andReturn(generatedMarkerGroup); expect(strategy.securityGroupMap.put(regionNameAndIngressRules, generatedMarkerGroup)).andReturn(null); @@ -527,13 +549,13 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); expect(options.getInboundPorts()).andReturn(ports).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); + ports, shouldAuthorizeSelf); expect(strategy.securityGroupMap.containsKey(regionNameAndIngressRules)).andReturn(groupExisted); // replay mocks @@ -561,12 +583,12 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getGroupIds()).andReturn(groupIds).atLeastOnce(); RegionNameAndIngressRules regionNameAndIngressRules = new RegionNameAndIngressRules(region, generatedMarkerGroup, - ports, shouldAuthorizeSelf); // note + ports, shouldAuthorizeSelf); // note // this // works // since @@ -594,7 +616,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); PlacementGroup placementGroup = createMock(PlacementGroup.class); // setup expectations @@ -607,7 +629,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options), - userSuppliedPlacementGroup); + userSuppliedPlacementGroup); // verify mocks verify(options); @@ -625,16 +647,16 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); // setup expectations expect(options.getPlacementGroup()).andReturn(userSuppliedPlacementGroup); expect(options.shouldAutomaticallyCreatePlacementGroup()).andReturn(shouldAutomaticallyCreatePlacementGroup); expect(strategy.placementGroupMap.containsKey(new RegionAndName(region, generatedMarkerGroup))).andReturn(false); expect(strategy.createPlacementGroupIfNeeded.apply(new RegionAndName(region, generatedMarkerGroup))).andReturn( - generatedMarkerGroup); + generatedMarkerGroup); expect(strategy.placementGroupMap.put(new RegionAndName(region, generatedMarkerGroup), generatedMarkerGroup)) - .andReturn(null); + .andReturn(null); // replay mocks replay(options); @@ -642,7 +664,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // run assertEquals(strategy.createNewPlacementGroupUnlessUserSpecifiedOtherwise(region, tag, options), - generatedMarkerGroup); + generatedMarkerGroup); // verify mocks verify(options); @@ -659,7 +681,7 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT // create mocks CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy = setupStrategy(); - EC2TemplateOptions options = createMock(EC2TemplateOptions.class); + AWSEC2TemplateOptions options = createMock(AWSEC2TemplateOptions.class); PlacementGroup placementGroup = createMock(PlacementGroup.class); // setup expectations @@ -689,12 +711,8 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT verify(strategy.createPlacementGroupIfNeeded); } - private CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() { - return setupStrategy("ec2"); - } - @SuppressWarnings("unchecked") - private CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy(String provider) { + private CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions setupStrategy() { Map credentialsMap = createMock(Map.class); Map securityGroupMap = createMock(Map.class); Map placementGroupMap = createMock(Map.class); @@ -702,9 +720,9 @@ public class CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptionsT CreateSecurityGroupIfNeeded createSecurityGroupIfNeeded = createMock(CreateSecurityGroupIfNeeded.class); CreatePlacementGroupIfNeeded createPlacementGroupIfNeeded = createMock(CreatePlacementGroupIfNeeded.class); - return new CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(provider, credentialsMap, - securityGroupMap, placementGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, - createPlacementGroupIfNeeded); + return new CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions(credentialsMap, securityGroupMap, + placementGroupMap, createUniqueKeyPair, createSecurityGroupIfNeeded, OPTIONS_PROVIDER, + createPlacementGroupIfNeeded); } private void replayStrategy(CreateKeyPairPlacementAndSecurityGroupsAsNeededAndReturnRunOptions strategy) { diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptionsTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptionsTest.java new file mode 100644 index 0000000000..ff28c73d25 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/options/AWSRunInstancesOptionsTest.java @@ -0,0 +1,295 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.options; + +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.asType; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.enableMonitoring; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withBlockDeviceMappings; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withKernelId; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withKeyName; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withRamdisk; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withSecurityGroup; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withSubnetId; +import static org.jclouds.aws.ec2.options.AWSRunInstancesOptions.Builder.withUserData; +import static org.testng.Assert.assertEquals; + +import java.util.Collections; + +import org.jclouds.ec2.domain.BlockDeviceMapping; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.http.options.HttpRequestOptions; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; + +/** + * Tests possible uses of AWSRunInstancesOptions and AWSRunInstancesOptions.Builder.* + * + * @author Adrian Cole + */ +public class AWSRunInstancesOptionsTest { + + @Test + public void testAssignability() { + assert HttpRequestOptions.class.isAssignableFrom(AWSRunInstancesOptions.class); + assert !String.class.isAssignableFrom(AWSRunInstancesOptions.class); + } + + @Test + public void testWithKeyName() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withKeyName("test"); + assertEquals(options.buildFormParameters().get("KeyName"), Collections.singletonList("test")); + } + + @Test + public void testNullWithKeyName() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("KeyName"), Collections.EMPTY_LIST); + } + + @Test + public void testWithKeyNameStatic() { + AWSRunInstancesOptions options = withKeyName("test"); + assertEquals(options.buildFormParameters().get("KeyName"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithKeyNameNPE() { + withKeyName(null); + } + + @Test + public void testWithSecurityGroup() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withSecurityGroup("test"); + assertEquals(options.buildFormParameters().get("SecurityGroup.1"), Collections.singletonList("test")); + } + + @Test + public void testNullWithSecurityGroup() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("SecurityGroup"), Collections.EMPTY_LIST); + } + + @Test + public void testWithSecurityGroupStatic() { + AWSRunInstancesOptions options = withSecurityGroup("test"); + assertEquals(options.buildFormParameters().get("SecurityGroup.1"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithSecurityGroupNPE() { + withSecurityGroup(null); + } + + @Test + public void testNullWithAdditionalInfo() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("AdditionalInfo"), Collections.EMPTY_LIST); + } + + @Test + public void testWithUserData() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withUserData("test".getBytes()); + assertEquals(options.buildFormParameters().get("UserData"), Collections.singletonList("dGVzdA==")); + } + + @Test + public void testNullWithUserData() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("UserData"), Collections.EMPTY_LIST); + } + + @Test + public void testWithUserDataStatic() { + AWSRunInstancesOptions options = withUserData("test".getBytes()); + assertEquals(options.buildFormParameters().get("UserData"), Collections.singletonList("dGVzdA==")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithUserDataNPE() { + withUserData(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testWithUserDataEmpty() { + withUserData("".getBytes()); + } + + @Test + public void testWithInstanceType() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.asType(InstanceType.C1_XLARGE); + assertEquals(options.buildFormParameters().get("InstanceType"), Collections.singletonList("c1.xlarge")); + } + + @Test + public void testNullWithInstanceType() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("InstanceType"), Collections.EMPTY_LIST); + } + + @Test + public void testWithInstanceTypeStatic() { + AWSRunInstancesOptions options = asType(InstanceType.C1_XLARGE); + assertEquals(options.buildFormParameters().get("InstanceType"), Collections.singletonList("c1.xlarge")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithInstanceTypeNPE() { + asType(null); + } + + @Test + public void testWithKernelId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withKernelId("test"); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.singletonList("test")); + } + + @Test + public void testNullWithKernelId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.EMPTY_LIST); + } + + @Test + public void testWithKernelIdStatic() { + AWSRunInstancesOptions options = withKernelId("test"); + assertEquals(options.buildFormParameters().get("KernelId"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithKernelIdNPE() { + withKernelId(null); + } + + @Test + public void testWithMonitoringEnabled() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.enableMonitoring(); + assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); + } + + @Test + public void testNullWithMonitoringEnabled() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.EMPTY_LIST); + } + + @Test + public void testWithMonitoringEnabledStatic() { + AWSRunInstancesOptions options = enableMonitoring(); + assertEquals(options.buildFormParameters().get("Monitoring.Enabled"), Collections.singletonList("true")); + } + + @Test + public void testWithSubnetId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withSubnetId("test"); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); + } + + @Test + public void testNullWithSubnetId() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.EMPTY_LIST); + } + + @Test + public void testWithSubnetIdStatic() { + AWSRunInstancesOptions options = withSubnetId("test"); + assertEquals(options.buildFormParameters().get("SubnetId"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithSubnetIdNPE() { + withSubnetId(null); + } + + @Test + public void testWithRamdisk() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + options.withRamdisk("test"); + assertEquals(options.buildFormParameters().get("RamdiskId"), Collections.singletonList("test")); + } + + @Test + public void testNullWithRamdisk() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("RamdiskId"), Collections.EMPTY_LIST); + } + + @Test + public void testWithRamdiskStatic() { + AWSRunInstancesOptions options = withRamdisk("test"); + assertEquals(options.buildFormParameters().get("RamdiskId"), Collections.singletonList("test")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithRamdiskNPE() { + withRamdisk(null); + } + + @Test + public void testNullWithVirtualName() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.VirtualName"), Collections.EMPTY_LIST); + } + + @Test + public void testWithBlockDeviceMapping() { + BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true); + AWSRunInstancesOptions options = new AWSRunInstancesOptions().withBlockDeviceMappings(ImmutableSet + . of(mapping)); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections + .singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections + .singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections + .singletonList("true")); + } + + @Test + public void testNullWithBlockDeviceMapping() { + AWSRunInstancesOptions options = new AWSRunInstancesOptions(); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping"), Collections.EMPTY_LIST); + } + + @Test + public void testWithBlockDeviceMappingStatic() { + BlockDeviceMapping mapping = new BlockDeviceMapping.MapNewVolumeToDevice("/dev/sda1", 120, true); + AWSRunInstancesOptions options = withBlockDeviceMappings(ImmutableSet. of(mapping)); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.DeviceName"), Collections + .singletonList("/dev/sda1")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.VolumeSize"), Collections + .singletonList("120")); + assertEquals(options.buildFormParameters().get("BlockDeviceMapping.1.Ebs.DeleteOnTermination"), Collections + .singletonList("true")); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testWithBlockDeviceMappingNPE() { + withBlockDeviceMappings(null); + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClientTest.java new file mode 100644 index 0000000000..55e59271ab --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIAsyncClientTest.java @@ -0,0 +1,386 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.executableBy; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; + +import org.jclouds.aws.ec2.xml.ProductCodesHandler; +import org.jclouds.ec2.options.CreateImageOptions; +import org.jclouds.ec2.options.DescribeImagesOptions; +import org.jclouds.ec2.options.RegisterImageBackedByEbsOptions; +import org.jclouds.ec2.options.RegisterImageOptions; +import org.jclouds.ec2.xml.BlockDeviceMappingHandler; +import org.jclouds.ec2.xml.DescribeImagesResponseHandler; +import org.jclouds.ec2.xml.ImageIdHandler; +import org.jclouds.ec2.xml.PermissionHandler; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReleasePayloadAndReturn; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code AWSAMIAsyncClient} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSAMIAsyncClientTest") +public class AWSAMIAsyncClientTest extends BaseAWSEC2AsyncClientTest { + public AWSAMIAsyncClientTest() { + provider = "aws-ec2"; + } + + public void testCreateImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("createImageInRegion", String.class, String.class, + String.class, Array.newInstance(CreateImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "instanceId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=CreateImage&InstanceId=instanceId&Name=name", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testCreateImageOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("createImageInRegion", String.class, String.class, + String.class, Array.newInstance(CreateImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "instanceId", new CreateImageOptions() + .withDescription("description").noReboot()); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=CreateImage&InstanceId=instanceId&Name=name&Description=description&NoReboot=true", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testDescribeImages() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class, Array.newInstance( + DescribeImagesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, (String) null); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeImages", "application/x-www-form-urlencoded", + false); + filter.filter(request); + assertPayloadEquals( + request, + "Action=DescribeImages&Signature=qE4vexSFJqS0UWK%2BccV3s%2BP9woL3M5HI5bTBoM7s%2FLY%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDescribeImagesOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("describeImagesInRegion", String.class, Array.newInstance( + DescribeImagesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, executableBy("me").ownedBy("fred", "nancy").imageIds( + "1", "2")); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=DescribeImages&ExecutableBy=me&Owner.1=fred&Owner.2=nancy&ImageId.1=1&ImageId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, DescribeImagesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDeregisterImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("deregisterImageInRegion", String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DeregisterImage&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageFromManifest() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "pathToManifest"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageFromManifestOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerImageFromManifestInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "name", "pathToManifest", new RegisterImageOptions() + .withDescription("description")); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RegisterImage&ImageLocation=pathToManifest&Name=name&Description=description", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageBackedByEBS() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerUnixImageBackedByEbsInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "imageName", "snapshotId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRegisterImageBackedByEBSOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("registerUnixImageBackedByEbsInRegion", String.class, + String.class, String.class, Array.newInstance(RegisterImageBackedByEbsOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "imageName", "snapshotId", + new RegisterImageBackedByEbsOptions().withDescription("description").addBlockDeviceFromSnapshot( + "/dev/device", null, "snapshot").addNewBlockDevice("/dev/newdevice", "newblock", 100)); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RegisterImage&RootDeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.0.Ebs.SnapshotId=snapshotId&Name=imageName&Description=description&BlockDeviceMapping.1.Ebs.DeleteOnTermination=false&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fdevice&BlockDeviceMapping.1.Ebs.SnapshotId=snapshot&BlockDeviceMapping.2.Ebs.DeleteOnTermination=false&BlockDeviceMapping.2.DeviceName=%2Fdev%2Fnewdevice&BlockDeviceMapping.2.VirtualName=newblock&BlockDeviceMapping.2.Ebs.VolumeSize=100", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ImageIdHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetProductCodesForImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("getProductCodesForImageInRegion", String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=productCodes&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, ProductCodesHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetBlockDeviceMappingsForImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("getBlockDeviceMappingsForImageInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=blockDeviceMapping&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, BlockDeviceMappingHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetLaunchPermissionForImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("getLaunchPermissionForImageInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeImageAttribute&Attribute=launchPermission&ImageId=imageId", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, PermissionHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testAddLaunchPermissionsToImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("addLaunchPermissionsToImageInRegion", String.class, + Iterable.class, Iterable.class, String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"), ImmutableList + .of("all"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue", + "application/x-www-form-urlencoded", false); + filter.filter(request); + assertPayloadEquals( + request, + "Action=ModifyImageAttribute&Attribute=launchPermission&ImageId=imageId&OperationType=add&Signature=WZzNWOC1KHbuySvXEuLTiBA%2BVUfKpSBN2Lud6MrhlCQ%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&UserGroup.1=all&UserId.1=bob&UserId.2=sue&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRemoveLaunchPermissionsFromImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("removeLaunchPermissionsFromImageInRegion", String.class, + Iterable.class, Iterable.class, String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("bob", "sue"), ImmutableList + .of("all"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=launchPermission&ImageId=imageId&UserGroup.1=all&UserId.1=bob&UserId.2=sue", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testResetLaunchPermissionsOnImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("resetLaunchPermissionsOnImageInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ResetImageAttribute&Attribute=launchPermission&ImageId=imageId", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testAddProductCodesToImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("addProductCodesToImageInRegion", String.class, Iterable.class, + String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=add&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRemoveProductCodesFromImage() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSAMIAsyncClient.class.getMethod("removeProductCodesFromImageInRegion", String.class, + Iterable.class, String.class); + HttpRequest request = processor.createRequest(method, null, ImmutableList.of("code1", "code2"), "imageId"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyImageAttribute&OperationType=remove&Attribute=productCodes&ImageId=imageId&ProductCode.1=code1&ProductCode.2=code2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java new file mode 100644 index 0000000000..93670a523a --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSAMIClientLiveTest.java @@ -0,0 +1,243 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.imageIds; +import static org.jclouds.ec2.options.RegisterImageBackedByEbsOptions.Builder.addNewBlockDevice; +import static org.jclouds.ec2.options.RegisterImageOptions.Builder.withDescription; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; + +import org.jclouds.Constants; +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.ec2.domain.Image; +import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.Image.ImageType; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.AuthorizationException; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.inject.Module; + +/** + * Tests behavior of {@code AWSAMIClient} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true) +public class AWSAMIClientLiveTest { + + private AWSAMIClient client; + private String imageId = "ami-7ea24a17"; + private static final String DEFAULT_MANIFEST = "adrianimages/image.manifest.xml"; + private static final String DEFAULT_SNAPSHOT = "TODO"; + private RestContext context; + + private Set imagesToDeregister = Sets.newHashSet(); + + protected String provider = "aws-ec2"; + protected String identity; + protected String credential; + protected String endpoint; + protected String apiversion; + + @BeforeClass + 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; + } + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + setupCredentials(); + Properties overrides = setupProperties(); + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); + client = context.getApi().getAMIServices(); + } + + public void testDescribeImageNotExists() { + assertEquals(client.describeImagesInRegion(null, imageIds("ami-cdf819a3")).size(), 0); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testDescribeImageBadId() { + client.describeImagesInRegion(null, imageIds("asdaasdsa")); + } + + public void testDescribeImages() { + for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1, + Region.AP_SOUTHEAST_1)) { + Set allResults = Sets.newLinkedHashSet(client.describeImagesInRegion(region)); + assertNotNull(allResults); + assert allResults.size() >= 2 : allResults.size(); + Iterator iterator = allResults.iterator(); + String id1 = iterator.next().getId(); + String id2 = iterator.next().getId(); + Set twoResults = Sets.newLinkedHashSet(client.describeImagesInRegion(region, imageIds(id1, id2))); + assertNotNull(twoResults); + assertEquals(twoResults.size(), 2); + iterator = twoResults.iterator(); + assertEquals(iterator.next().getId(), id1); + assertEquals(iterator.next().getId(), id2); + } + } + + @Test(enabled = false) + public void testRegisterImageFromManifest() { + String imageRegisteredId = client.registerImageFromManifestInRegion(null, "jcloudstest1", DEFAULT_MANIFEST); + imagesToDeregister.add(imageRegisteredId); + Image imageRegisteredFromManifest = Iterables.getOnlyElement(client.describeImagesInRegion(null, + imageIds(imageRegisteredId))); + assertEquals(imageRegisteredFromManifest.getName(), "jcloudstest1"); + assertEquals(imageRegisteredFromManifest.getImageLocation(), DEFAULT_MANIFEST); + assertEquals(imageRegisteredFromManifest.getImageType(), ImageType.MACHINE); + assertEquals(imageRegisteredFromManifest.getRootDeviceType(), RootDeviceType.INSTANCE_STORE); + assertEquals(imageRegisteredFromManifest.getRootDeviceName(), "/dev/sda1"); + } + + @Test(enabled = false) + public void testRegisterImageFromManifestOptions() { + String imageRegisteredWithOptionsId = client.registerImageFromManifestInRegion(null, "jcloudstest2", + DEFAULT_MANIFEST, withDescription("adrian")); + imagesToDeregister.add(imageRegisteredWithOptionsId); + Image imageRegisteredFromManifestWithOptions = Iterables.getOnlyElement(client.describeImagesInRegion(null, + imageIds(imageRegisteredWithOptionsId))); + assertEquals(imageRegisteredFromManifestWithOptions.getName(), "jcloudstest2"); + assertEquals(imageRegisteredFromManifestWithOptions.getImageLocation(), DEFAULT_MANIFEST); + assertEquals(imageRegisteredFromManifestWithOptions.getImageType(), ImageType.MACHINE); + assertEquals(imageRegisteredFromManifestWithOptions.getRootDeviceType(), RootDeviceType.INSTANCE_STORE); + assertEquals(imageRegisteredFromManifestWithOptions.getRootDeviceName(), "/dev/sda1"); + assertEquals(imageRegisteredFromManifestWithOptions.getDescription(), "adrian"); + } + + @Test(enabled = false) + // awaiting EBS functionality to be added to jclouds + public void testRegisterImageBackedByEBS() { + String imageRegisteredId = client.registerUnixImageBackedByEbsInRegion(null, "jcloudstest1", DEFAULT_MANIFEST); + imagesToDeregister.add(imageRegisteredId); + Image imageRegistered = Iterables + .getOnlyElement(client.describeImagesInRegion(null, imageIds(imageRegisteredId))); + assertEquals(imageRegistered.getName(), "jcloudstest1"); + assertEquals(imageRegistered.getImageType(), ImageType.MACHINE); + assertEquals(imageRegistered.getRootDeviceType(), RootDeviceType.EBS); + assertEquals(imageRegistered.getRootDeviceName(), "/dev/sda1"); + } + + @Test(enabled = false) + // awaiting EBS functionality to be added to jclouds + public void testRegisterImageBackedByEBSOptions() { + String imageRegisteredWithOptionsId = client.registerUnixImageBackedByEbsInRegion(null, "jcloudstest2", + DEFAULT_SNAPSHOT, addNewBlockDevice("/dev/sda2", "myvirtual", 1).withDescription("adrian")); + imagesToDeregister.add(imageRegisteredWithOptionsId); + Image imageRegisteredWithOptions = Iterables.getOnlyElement(client.describeImagesInRegion(null, + imageIds(imageRegisteredWithOptionsId))); + assertEquals(imageRegisteredWithOptions.getName(), "jcloudstest2"); + assertEquals(imageRegisteredWithOptions.getImageType(), ImageType.MACHINE); + assertEquals(imageRegisteredWithOptions.getRootDeviceType(), RootDeviceType.EBS); + assertEquals(imageRegisteredWithOptions.getRootDeviceName(), "/dev/sda1"); + assertEquals(imageRegisteredWithOptions.getDescription(), "adrian"); + assertEquals(imageRegisteredWithOptions.getEbsBlockDevices().entrySet(), ImmutableMap.of("/dev/sda1", + new Image.EbsBlockDevice("/dev/sda1", 30, true), "/dev/sda2", + new Image.EbsBlockDevice("/dev/sda2", 1, true)).entrySet()); + } + + @Test(enabled = false) + public void testCreateImage() { + // TODO client.createImageInRegion(null, name, instanceId, options); + } + + @Test(enabled = false) + public void testAddProductCodesToImage() { + // TODO client.addProductCodesToImageInRegion(null, productCodes, imageId); + } + + @Test(enabled = false) + public void testAddLaunchPermissionsToImage() { + // TODO client.addLaunchPermissionsToImageInRegion(null, userIds, userGroups, + // imageId); + } + + @Test(enabled = false) + public void testRemoveLaunchPermissionsFromImage() { + // TODO client.removeLaunchPermissionsFromImageInRegion(null, userIds, userGroups, + // imageId); + } + + @Test(enabled = false) + public void testResetLaunchPermissionsOnImage() { + // TODO client.resetLaunchPermissionsOnImageInRegion(null, imageId); + } + + @Test(expectedExceptions = AuthorizationException.class) + public void testGetLaunchPermissionForImage() { + System.out.println(client.getLaunchPermissionForImageInRegion(null, imageId)); + } + + @Test(expectedExceptions = AuthorizationException.class) + public void testGetProductCodesForImage() { + System.out.println(client.getProductCodesForImageInRegion(null, imageId)); + } + + @Test(enabled = false) + // awaiting ebs support + public void testGetBlockDeviceMappingsForImage() { + System.out.println(client.getBlockDeviceMappingsForImageInRegion(null, imageId)); + } + + @AfterTest + public void deregisterImages() { + for (String imageId : imagesToDeregister) + client.deregisterImageInRegion(null, imageId); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClientTest.java new file mode 100644 index 0000000000..6ba5b680a7 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceAsyncClientTest.java @@ -0,0 +1,505 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.Map; + +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.options.AWSRunInstancesOptions; +import org.jclouds.aws.ec2.xml.AWSDescribeInstancesResponseHandler; +import org.jclouds.aws.ec2.xml.AWSRunInstancesResponseHandler; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.domain.Volume.InstanceInitiatedShutdownBehavior; +import org.jclouds.ec2.options.RunInstancesOptions; +import org.jclouds.ec2.xml.BlockDeviceMappingHandler; +import org.jclouds.ec2.xml.BooleanValueHandler; +import org.jclouds.ec2.xml.InstanceInitiatedShutdownBehaviorHandler; +import org.jclouds.ec2.xml.InstanceStateChangeHandler; +import org.jclouds.ec2.xml.InstanceTypeHandler; +import org.jclouds.ec2.xml.StringValueHandler; +import org.jclouds.ec2.xml.UnencodeStringValueHandler; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ReleasePayloadAndReturn; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.internal.RestAnnotationProcessor; +import org.testng.annotations.Test; + +import com.google.common.collect.Maps; +import com.google.inject.TypeLiteral; + +/** + * Tests behavior of {@code AWSInstanceAsyncClient} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSInstanceAsyncClientTest") +public class AWSInstanceAsyncClientTest extends BaseAWSEC2AsyncClientTest { + public void testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, String[].class); + HttpRequest request = processor.createRequest(method, (String) null); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstances", "application/x-www-form-urlencoded", + false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSDescribeInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testDescribeInstancesArgs() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, String[].class); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSDescribeInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, ReturnEmptySetOnNotFoundOr404.class); + + checkFilters(request); + } + + public void testTerminateInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("terminateInstancesInRegion", String.class, Array + .newInstance(String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=TerminateInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRunInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("runInstancesInRegion", String.class, String.class, + String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, null, "ami-voo", 1, 1); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + try { + assertPayloadEquals(request, "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=1", + "application/x-www-form-urlencoded", false); + } catch (AssertionError e) { + // mvn 3.0 osx 10.6.5 somehow sorts differently + assertPayloadEquals(request, "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MaxCount=1&MinCount=1", + "application/x-www-form-urlencoded", false); + } + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSRunInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRunInstancesOptions() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("runInstancesInRegion", String.class, String.class, + String.class, int.class, int.class, Array.newInstance(RunInstancesOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, Region.EU_WEST_1, AvailabilityZone.EU_WEST_1A, "ami-voo", + 1, 5, new AWSRunInstancesOptions().withKernelId("kernelId").enableMonitoring().withSecurityGroups( + "group1", "group2")); + + assertRequestLineEquals(request, "POST https://ec2.eu-west-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.eu-west-1.amazonaws.com\n"); + try { + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MinCount=1&MaxCount=5&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=eu-west-1a", + "application/x-www-form-urlencoded", false); + } catch (AssertionError e) { + // mvn 3.0 osx 10.6.5 somehow sorts differently + assertPayloadEquals( + request, + "Version=2010-06-15&Action=RunInstances&ImageId=ami-voo&MaxCount=5&MinCount=1&KernelId=kernelId&Monitoring.Enabled=true&SecurityGroup.1=group1&SecurityGroup.2=group2&Placement.AvailabilityZone=eu-west-1a", + "application/x-www-form-urlencoded", false); + } + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, AWSRunInstancesResponseHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testStopInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("stopInstancesInRegion", String.class, boolean.class, + Array.newInstance(String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, true, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=StopInstances&Force=true&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testRebootInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("rebootInstancesInRegion", String.class, Array + .newInstance(String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=RebootInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testStartInstances() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("startInstancesInRegion", String.class, Array.newInstance( + String.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "2"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=StartInstances&InstanceId.1=1&InstanceId.2=2", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceStateChangeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetUserDataForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getUserDataForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=userData&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, UnencodeStringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetRootDeviceNameForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getRootDeviceNameForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=rootDeviceName&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, StringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetRamdiskForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getRamdiskForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=ramdisk&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, StringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetDisableApiTerminationForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("isApiTerminationDisabledForInstanceInRegion", + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=disableApiTermination&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, BooleanValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetKernelForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class + .getMethod("getKernelForInstanceInRegion", String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=kernel&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, StringValueHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetInstanceTypeForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getInstanceTypeForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=instanceType&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceTypeHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetInstanceInitiatedShutdownBehaviorForInstanceInRegion() throws SecurityException, + NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getInstanceInitiatedShutdownBehaviorForInstanceInRegion", + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, InstanceInitiatedShutdownBehaviorHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testGetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("getBlockDeviceMappingForInstanceInRegion", String.class, + String.class); + HttpRequest request = processor.createRequest(method, null, "1"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=DescribeInstanceAttribute&Attribute=blockDeviceMapping&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, BlockDeviceMappingHandler.class); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetUserDataForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setUserDataForInstanceInRegion", String.class, + String.class, Array.newInstance(byte.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, null, "1", "test".getBytes()); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=userData&Value=dGVzdA%3D%3D&InstanceId=1", + "application/x-www-form-urlencoded", false); + filter.filter(request);// ensure encoding worked properly + assertPayloadEquals( + request, + "Action=ModifyInstanceAttribute&Attribute=userData&InstanceId=1&Signature=LfUmzLM5DsACR5nQcEfGF5FPdznOwwhJ7tjhBWfHtGs%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Value=dGVzdA%3D%3D&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetRamdiskForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setRamdiskForInstanceInRegion", String.class, + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1", "test"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=ramdisk&Value=test&InstanceId=1", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetKernelForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setKernelForInstanceInRegion", String.class, + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1", "test"); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=kernel&Value=test&InstanceId=1", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetApiTerminationDisabledForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setApiTerminationDisabledForInstanceInRegion", + String.class, String.class, boolean.class); + HttpRequest request = processor.createRequest(method, null, "1", true); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=disableApiTermination&Value=true&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetInstanceTypeForInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setInstanceTypeForInstanceInRegion", String.class, + String.class, String.class); + HttpRequest request = processor.createRequest(method, null, "1", InstanceType.C1_MEDIUM); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals(request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=instanceType&Value=c1.medium&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetInstanceInitiatedShutdownBehaviorForInstanceInRegion() throws SecurityException, + NoSuchMethodException, IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setInstanceInitiatedShutdownBehaviorForInstanceInRegion", + String.class, String.class, InstanceInitiatedShutdownBehavior.class); + HttpRequest request = processor.createRequest(method, null, "1", InstanceInitiatedShutdownBehavior.TERMINATE); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&Attribute=instanceInitiatedShutdownBehavior&Value=terminate&InstanceId=1", + "application/x-www-form-urlencoded", false); + + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + public void testSetBlockDeviceMappingForInstanceInRegion() throws SecurityException, NoSuchMethodException, + IOException { + Method method = AWSInstanceAsyncClient.class.getMethod("setBlockDeviceMappingForInstanceInRegion", String.class, + String.class, Map.class); + + Map mapping = Maps.newLinkedHashMap(); + mapping.put("/dev/sda1", new BlockDevice("vol-test1", true)); + HttpRequest request = processor.createRequest(method, null, "1", mapping); + + assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n"); + assertPayloadEquals( + request, + "Version=2010-06-15&Action=ModifyInstanceAttribute&InstanceId=1&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true", + "application/x-www-form-urlencoded", false); + filter.filter(request);// ensure encoding worked properly + assertPayloadEquals( + request, + "Action=ModifyInstanceAttribute&BlockDeviceMapping.1.DeviceName=%2Fdev%2Fsda1&BlockDeviceMapping.1.Ebs.DeleteOnTermination=true&BlockDeviceMapping.1.Ebs.VolumeId=vol-test1&InstanceId=1&Signature=RwY8lVPHSQxQkd5efUKccHdSTkN4OxMIMFiYAe3rrUE%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2009-11-08T15%3A54%3A08.897Z&Version=2010-06-15&AWSAccessKeyId=identity", + "application/x-www-form-urlencoded", false); + assertResponseParserClassEquals(method, request, ReleasePayloadAndReturn.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, null); + + checkFilters(request); + } + + @Override + protected TypeLiteral> createTypeLiteral() { + return new TypeLiteral>() { + }; + } + +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java new file mode 100644 index 0000000000..a6e801a9aa --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/AWSInstanceClientLiveTest.java @@ -0,0 +1,106 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.services; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.testng.Assert.assertNotNull; + +import java.util.Properties; +import java.util.Set; + +import org.jclouds.Constants; +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.rest.RestContext; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeGroups; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.inject.Module; + +/** + * Tests behavior of {@code EC2Client} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true) +public class AWSInstanceClientLiveTest { + public static final String PREFIX = System.getProperty("user.name") + "-ec2"; + + private AWSInstanceClient client; + private RestContext context; + protected String provider = "aws-ec2"; + protected String identity; + protected String credential; + protected String endpoint; + protected String apiversion; + + protected void setupCredentials() { + identity = checkNotNull(System.getProperty("test." + provider + ".identity"), "test." + provider + ".identity"); + credential = checkNotNull(System.getProperty("test." + provider + ".credential"), "test." + provider + + ".credential"); + endpoint = checkNotNull(System.getProperty("test." + provider + ".endpoint"), "test." + provider + ".endpoint"); + apiversion = checkNotNull(System.getProperty("test." + provider + ".apiversion"), "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); + overrides.setProperty(provider + ".credential", credential); + overrides.setProperty(provider + ".endpoint", endpoint); + overrides.setProperty(provider + ".apiversion", apiversion); + return overrides; + } + + @BeforeGroups(groups = { "live" }) + public void setupClient() { + setupCredentials(); + Properties overrides = setupProperties(); + context = new ComputeServiceContextFactory().createContext(provider, + ImmutableSet. of(new Log4JLoggingModule()), overrides).getProviderSpecificContext(); + client = context.getApi().getInstanceServices(); + + } + + @Test + void testDescribeInstances() { + for (String region : Lists.newArrayList(null, Region.EU_WEST_1, Region.US_EAST_1, Region.US_WEST_1, + Region.AP_SOUTHEAST_1)) { + Set> allResults = client.describeInstancesInRegion(region); + assertNotNull(allResults); + assert allResults.size() >= 0 : allResults.size(); + } + } + + @AfterTest + public void shutdown() { + context.close(); + } +} diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/BaseAWSEC2AsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/BaseAWSEC2AsyncClientTest.java new file mode 100644 index 0000000000..d661123576 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/BaseAWSEC2AsyncClientTest.java @@ -0,0 +1,94 @@ +package org.jclouds.aws.ec2.services; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Properties; + +import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.config.AWSEC2RestClientModule; +import org.jclouds.aws.filters.FormSigner; +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.RequiresHttp; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.RestClientTest; +import org.jclouds.rest.RestContextFactory; +import org.jclouds.rest.RestContextSpec; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Module; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit") +public abstract class BaseAWSEC2AsyncClientTest extends RestClientTest { + + @RequiresHttp + @ConfiguresRestClient + protected static class StubAWSEC2RestClientModule extends AWSEC2RestClientModule { + + @Override + protected String provideTimeStamp(DateService dateService, int expiration) { + return "2009-11-08T15:54:08.897Z"; + } + + protected void bindRegionsToProvider() { + bindRegionsToProvider(Regions.class); + } + + static class Regions implements javax.inject.Provider> { + @Override + public Map get() { + return ImmutableMap. of(Region.EU_WEST_1, URI.create("https://ec2.eu-west-1.amazonaws.com"), + Region.US_EAST_1, URI.create("https://ec2.us-east-1.amazonaws.com"), Region.US_WEST_1, + URI.create("https://ec2.us-west-1.amazonaws.com")); + } + } + + protected void bindZonesToProvider() { + bindZonesToProvider(Zones.class); + } + + static class Zones implements javax.inject.Provider> { + @Override + public Map get() { + return ImmutableMap. of(AvailabilityZone.US_EAST_1A, Region.US_EAST_1); + } + } + } + + protected FormSigner filter; + + @Override + protected void checkFilters(HttpRequest request) { + assertEquals(request.getFilters().size(), 1); + assertEquals(request.getFilters().get(0).getClass(), FormSigner.class); + } + + @Override + @BeforeTest + protected void setupFactory() throws IOException { + super.setupFactory(); + this.filter = injector.getInstance(FormSigner.class); + } + + @Override + protected Module createModule() { + return new StubAWSEC2RestClientModule(); + } + + protected String provider = "aws-ec2"; + + @Override + public RestContextSpec createContextSpec() { + return new RestContextFactory().createContextSpec(provider, "identity", "credential", new Properties()); + } + +} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java similarity index 94% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringAsyncClientTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java index e3aa9399c6..1a576a4e1c 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringAsyncClientTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringAsyncClientTest.java @@ -17,13 +17,13 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.io.IOException; import java.lang.reflect.Array; import java.lang.reflect.Method; -import org.jclouds.ec2.xml.MonitoringStateHandler; +import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.RestAnnotationProcessor; @@ -38,7 +38,7 @@ import com.google.inject.TypeLiteral; */ // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "MonitoringAsyncClientTest") -public class MonitoringAsyncClientTest extends BaseEC2AsyncClientTest { +public class MonitoringAsyncClientTest extends BaseAWSEC2AsyncClientTest { public void testUnmonitorInstances() throws SecurityException, NoSuchMethodException, IOException { Method method = MonitoringAsyncClient.class.getMethod("unmonitorInstancesInRegion", String.class, String.class, diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java similarity index 92% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringClientLiveTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java index b05a8b4152..f8f58f1fe6 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/MonitoringClientLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/MonitoringClientLiveTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static com.google.common.base.Preconditions.checkNotNull; import static org.testng.Assert.assertEquals; @@ -26,9 +26,9 @@ import java.util.Map; import java.util.Properties; import org.jclouds.Constants; -import org.jclouds.ec2.EC2AsyncClient; -import org.jclouds.ec2.EC2Client; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.AWSEC2AsyncClient; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.MonitoringState; import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.rest.RestContext; @@ -48,8 +48,8 @@ public class MonitoringClientLiveTest { private MonitoringClient client; private static final String DEFAULT_INSTANCE = "i-TODO"; - private RestContext context; - protected String provider = "ec2"; + private RestContext context; + protected String provider = "aws-ec2"; protected String identity; protected String credential; protected String endpoint; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupAsyncClientTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClientTest.java similarity index 96% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupAsyncClientTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClientTest.java index 237135ffb5..421d885e23 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupAsyncClientTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupAsyncClientTest.java @@ -17,12 +17,12 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import java.io.IOException; import java.lang.reflect.Method; -import org.jclouds.ec2.xml.DescribePlacementGroupsResponseHandler; +import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.ParseSax; import org.jclouds.http.functions.ReleasePayloadAndReturn; @@ -40,7 +40,7 @@ import com.google.inject.TypeLiteral; */ // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire @Test(groups = "unit", testName = "PlacementGroupAsyncClientTest") -public class PlacementGroupAsyncClientTest extends BaseEC2AsyncClientTest { +public class PlacementGroupAsyncClientTest extends BaseAWSEC2AsyncClientTest { public void testDeletePlacementGroup() throws SecurityException, NoSuchMethodException, IOException { Method method = PlacementGroupAsyncClient.class.getMethod("deletePlacementGroupInRegion", String.class, diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupClientLiveTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java similarity index 87% rename from apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupClientLiveTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java index cd7e5e64b4..c735d8750f 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/services/PlacementGroupClientLiveTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/services/PlacementGroupClientLiveTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.services; +package org.jclouds.aws.ec2.services; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.any; @@ -38,8 +38,12 @@ import java.util.SortedSet; import java.util.concurrent.TimeUnit; import org.jclouds.Constants; -import org.jclouds.aws.AWSResponseException; import org.jclouds.aws.domain.Region; +import org.jclouds.aws.ec2.AWSEC2Client; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup.State; +import org.jclouds.aws.ec2.predicates.PlacementGroupAvailable; +import org.jclouds.aws.ec2.predicates.PlacementGroupDeleted; import org.jclouds.compute.ComputeServiceContext; import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.compute.RunNodesException; @@ -48,12 +52,7 @@ import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; import org.jclouds.compute.predicates.NodePredicates; -import org.jclouds.ec2.EC2Client; import org.jclouds.ec2.domain.InstanceType; -import org.jclouds.ec2.domain.PlacementGroup; -import org.jclouds.ec2.domain.PlacementGroup.State; -import org.jclouds.ec2.predicates.PlacementGroupAvailable; -import org.jclouds.ec2.predicates.PlacementGroupDeleted; import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.ssh.jsch.config.JschSshClientModule; @@ -75,13 +74,13 @@ import com.google.inject.Module; @Test(groups = "live", sequential = true) public class PlacementGroupClientLiveTest { - private EC2Client client; + private AWSEC2Client client; private ComputeServiceContext context; private RetryablePredicate availableTester; private RetryablePredicate deletedTester; private PlacementGroup group; private Map keyPair; - protected String provider = "ec2"; + protected String provider = "aws-ec2"; protected String identity; protected String credential; protected String endpoint; @@ -113,14 +112,14 @@ public class PlacementGroupClientLiveTest { public void setupClient() throws FileNotFoundException, IOException { setupCredentials(); Properties overrides = setupProperties(); - context = new ComputeServiceContextFactory().createContext(provider, - ImmutableSet. of(new Log4JLoggingModule(), new JschSshClientModule()), overrides); + context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet. of( + new Log4JLoggingModule(), new JschSshClientModule()), overrides); keyPair = setupKeyPair(); - client = EC2Client.class.cast(context.getProviderSpecificContext().getApi()); + client = AWSEC2Client.class.cast(context.getProviderSpecificContext().getApi()); availableTester = new RetryablePredicate(new PlacementGroupAvailable(client), 60, 1, - TimeUnit.SECONDS); + TimeUnit.SECONDS); deletedTester = new RetryablePredicate(new PlacementGroupDeleted(client), 60, 1, TimeUnit.SECONDS); } @@ -129,12 +128,12 @@ public class PlacementGroupClientLiveTest { void testDescribe() { for (String region : newArrayList(Region.US_EAST_1)) { SortedSet allResults = newTreeSet(client.getPlacementGroupServices() - .describePlacementGroupsInRegion(region)); + .describePlacementGroupsInRegion(region)); assertNotNull(allResults); if (allResults.size() >= 1) { PlacementGroup group = allResults.last(); SortedSet result = newTreeSet(client.getPlacementGroupServices() - .describePlacementGroupsInRegion(region, group.getName())); + .describePlacementGroupsInRegion(region, group.getName())); assertNotNull(result); PlacementGroup compare = result.last(); assertEquals(compare, group); @@ -145,8 +144,7 @@ public class PlacementGroupClientLiveTest { try { client.getPlacementGroupServices().describePlacementGroupsInRegion(region); assert false : "should be unsupported"; - } catch (AWSResponseException e) { - assertEquals(e.getError().getCode(), "UnsupportedOperation"); + } catch (UnsupportedOperationException e) { } } } @@ -163,7 +161,7 @@ public class PlacementGroupClientLiveTest { private void verifyPlacementGroup(String groupName) { assert availableTester.apply(new PlacementGroup(Region.US_EAST_1, groupName, "cluster", State.PENDING)) : group; Set oneResult = client.getPlacementGroupServices().describePlacementGroupsInRegion(null, - groupName); + groupName); assertNotNull(oneResult); assertEquals(oneResult.size(), 1); group = oneResult.iterator().next(); @@ -199,25 +197,25 @@ public class PlacementGroupClientLiveTest { assertEquals(template.getImage().getId(), "us-east-1/ami-7ea24a17"); template.getOptions().installPrivateKey(keyPair.get("private")).authorizePublicKey(keyPair.get("public")) - .runScript(buildScript(template.getImage().getOperatingSystem())); + .runScript(buildScript(template.getImage().getOperatingSystem())); - String tag = PREFIX + "cccluster"; - context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); + String group = PREFIX + "cccluster"; + context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group)); // TODO make this not lookup an explicit region - client.getPlacementGroupServices().deletePlacementGroupInRegion(null, "jclouds#" + tag + "#us-east-1"); + client.getPlacementGroupServices().deletePlacementGroupInRegion(null, "jclouds#" + group + "#us-east-1"); try { - Set nodes = context.getComputeService().runNodesWithTag(tag, 1, template); + Set nodes = context.getComputeService().createNodesInGroup(group, 1, template); NodeMetadata node = getOnlyElement(nodes); getOnlyElement(getOnlyElement(client.getInstanceServices().describeInstancesInRegion(null, - node.getProviderId()))); + node.getProviderId()))); } catch (RunNodesException e) { System.err.println(e.getNodeErrors().keySet()); Throwables.propagate(e); } finally { - context.getComputeService().destroyNodesMatching(NodePredicates.withTag(tag)); + context.getComputeService().destroyNodesMatching(NodePredicates.inGroup(group)); } } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandlerTest.java new file mode 100644 index 0000000000..ff2099e669 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/AWSDescribeInstancesResponseHandlerTest.java @@ -0,0 +1,161 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.xml; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; +import java.net.UnknownHostException; +import java.util.Set; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.Attachment; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RootDeviceType; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.location.Region; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * Tests behavior of {@code AWSDescribeInstancesResponseHandler} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "AWSDescribeInstancesResponseHandlerTest") +public class AWSDescribeInstancesResponseHandlerTest extends BaseEC2HandlerTest { + + private DateService dateService; + + @BeforeTest + @Override + protected void setUpInjector() { + super.setUpInjector(); + dateService = injector.getInstance(DateService.class); + assert dateService != null; + } + + public void testWhenRunning() throws UnknownHostException { + + Set> contents = ImmutableSet.of(new Reservation( + defaultRegion, ImmutableSet.of("adriancole.ec2ingress"), ImmutableSet + .of(new AWSRunningInstance.Builder().region(defaultRegion).groupId("adriancole.ec2ingress") + .amiLaunchIndex("0").dnsName("ec2-174-129-81-68.compute-1.amazonaws.com").imageId( + "ami-82e4b5c7").instanceId("i-0799056f").instanceState(InstanceState.RUNNING) + .instanceType(InstanceType.M1_SMALL).ipAddress("174.129.81.68").kernelId( + "aki-a71cf9ce").keyName("adriancole.ec21").launchTime( + dateService.iso8601DateParse("2009-11-09T03:00:34.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1C) + .virtualizationType("paravirtual").privateDnsName("ip-10-243-42-70.ec2.internal") + .privateIpAddress("10.243.42.70").ramdiskId("ari-a51cf9cc").rootDeviceType( + RootDeviceType.INSTANCE_STORE).build()), "993194456877", null, "r-a3c508cb")); + + Set> result = parseAWSRunningInstances("/describe_instances_running.xml"); + + assertEquals(result, contents); + } + + public void testApplyInputStream() { + Set> contents = ImmutableSet.of(new Reservation( + defaultRegion, ImmutableSet.of("default"), ImmutableSet.of(new AWSRunningInstance.Builder().region( + defaultRegion).groupId("default").amiLaunchIndex("23").dnsName( + "ec2-72-44-33-4.compute-1.amazonaws.com").imageId("ami-6ea54007").instanceId("i-28a64341") + .instanceState(InstanceState.RUNNING).instanceType(InstanceType.M1_LARGE).kernelId( + "aki-ba3adfd3").keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1B) + .virtualizationType("paravirtual").privateDnsName("10-251-50-132.ec2.internal").productCode( + "774F4FF8").ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE) + .build(), new AWSRunningInstance.Builder().region(defaultRegion).groupId("default") + .amiLaunchIndex("23").dnsName("ec2-72-44-33-6.compute-1.amazonaws.com").imageId("ami-6ea54007") + .instanceId("i-28a64435").instanceState(InstanceState.RUNNING).instanceType( + InstanceType.M1_LARGE).kernelId("aki-ba3adfd3").keyName("example-key-name") + .launchTime(dateService.iso8601DateParse("2007-08-07T11:54:42.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1B) + .virtualizationType("paravirtual").privateDnsName("10-251-50-134.ec2.internal").productCode( + "774F4FF8").ramdiskId("ari-badbad00").rootDeviceType(RootDeviceType.INSTANCE_STORE) + .build()), "UYY3TLBUXIEON5NQVUUX6OMPWBZIQNFM", null, "r-44a5402d")); + + Set> result = parseAWSRunningInstances("/describe_instances.xml"); + + assertEquals(result, contents); + } + + public void testEBS() throws UnknownHostException { + + Set> contents = ImmutableSet.of(new Reservation( + defaultRegion, ImmutableSet.of("adriancole.ec2ebsingress"), ImmutableSet + .of(new AWSRunningInstance.Builder().region(defaultRegion).groupId("adriancole.ec2ebsingress") + .amiLaunchIndex("0").dnsName("ec2-75-101-203-146.compute-1.amazonaws.com").imageId( + "ami-849875ed").instanceId("i-e564438d").instanceState(InstanceState.RUNNING) + .instanceType(InstanceType.M1_SMALL).ipAddress("75.101.203.146").kernelId( + "aki-a71cf9ce").keyName("adriancole.ec2ebs1").launchTime( + dateService.iso8601DateParse("2009-12-30T04:06:23.000Z")).monitoringState( + MonitoringState.DISABLED).availabilityZone(AvailabilityZone.US_EAST_1B) + .placementGroup("placement").virtualizationType("hvm").privateDnsName( + "domU-12-31-39-09-CE-53.compute-1.internal").privateIpAddress( + "10.210.209.157").ramdiskId("ari-a51cf9cc") + .rootDeviceType(RootDeviceType.EBS).rootDeviceName("/dev/sda1").device( + "/dev/sda1", + new BlockDevice("vol-dc6ca8b5", Attachment.Status.ATTACHED, dateService + .iso8601DateParse("2009-12-30T04:06:29.000Z"), true)).build()), + "993194456877", null, "r-596dd731")); + + Set> result = parseAWSRunningInstances("/describe_instances_ebs.xml"); + + assertEquals(result, contents); + } + + static ParseSax>> createParser() { + Injector injector = Guice.createInjector(new SaxParserModule(), new AbstractModule() { + + @Override + protected void configure() { + bind(String.class).annotatedWith(Region.class).toInstance("us-east-1"); + bind(RunningInstance.Builder.class).to(AWSRunningInstance.Builder.class); + } + + }); + ParseSax>> parser = (ParseSax>>) injector + .getInstance(ParseSax.Factory.class).create( + injector.getInstance(AWSDescribeInstancesResponseHandler.class)); + return parser; + } + + public static Set> parseAWSRunningInstances(String resource) { + InputStream is = AWSDescribeInstancesResponseHandlerTest.class.getResourceAsStream(resource); + return createParser().parse(is); + } +} diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java similarity index 92% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java index 22b2c6d28b..0b84c608a3 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribePlacementGroupsResponseHandlerTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; @@ -26,7 +26,9 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; -import org.jclouds.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.domain.PlacementGroup; +import org.jclouds.aws.ec2.xml.DescribePlacementGroupsResponseHandler; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.testng.annotations.Test; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java similarity index 97% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java index da9c2475c2..2f27a2b59a 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/DescribeReservedInstancesOfferingResponseHandlerTest.java @@ -17,7 +17,7 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.easymock.EasyMock.expect; import static org.easymock.classextension.EasyMock.createMock; @@ -27,6 +27,7 @@ import static org.testng.Assert.assertEquals; import java.io.InputStream; import org.jclouds.ec2.domain.ReservedInstancesOffering; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.testng.annotations.Test; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/MonitoringStateHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/MonitoringStateHandlerTest.java similarity index 92% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/MonitoringStateHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/MonitoringStateHandlerTest.java index 02fac61471..23f1778902 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/MonitoringStateHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/MonitoringStateHandlerTest.java @@ -17,14 +17,15 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.util.Map; -import org.jclouds.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.aws.ec2.xml.MonitoringStateHandler; import org.jclouds.http.functions.BaseHandlerTest; import org.testng.annotations.Test; diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/ProductCodesHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/ProductCodesHandlerTest.java similarity index 95% rename from apis/ec2/src/test/java/org/jclouds/ec2/xml/ProductCodesHandlerTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/ProductCodesHandlerTest.java index 64996fa507..0db3680dd1 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/ProductCodesHandlerTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/ProductCodesHandlerTest.java @@ -17,13 +17,14 @@ * ==================================================================== */ -package org.jclouds.ec2.xml; +package org.jclouds.aws.ec2.xml; import static org.testng.Assert.assertEquals; import java.io.InputStream; import java.util.Set; +import org.jclouds.aws.ec2.xml.ProductCodesHandler; import org.jclouds.http.functions.BaseHandlerTest; import org.testng.annotations.Test; diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java new file mode 100644 index 0000000000..77cee3c388 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/xml/RunInstancesResponseHandlerTest.java @@ -0,0 +1,117 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2.xml; + +import static org.easymock.EasyMock.expect; +import static org.easymock.classextension.EasyMock.createMock; +import static org.easymock.classextension.EasyMock.replay; +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; + +import org.jclouds.aws.ec2.domain.AWSRunningInstance; +import org.jclouds.aws.ec2.domain.MonitoringState; +import org.jclouds.date.DateService; +import org.jclouds.ec2.domain.AvailabilityZone; +import org.jclouds.ec2.domain.InstanceState; +import org.jclouds.ec2.domain.InstanceType; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.xml.BaseEC2HandlerTest; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.location.Region; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; + +/** + * Tests behavior of {@code RunInstancesResponseHandler} + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "RunInstancesResponseHandlerTest") +public class RunInstancesResponseHandlerTest extends BaseEC2HandlerTest { + + private DateService dateService; + + @BeforeTest + @Override + protected void setUpInjector() { + injector = Guice.createInjector(new SaxParserModule(), new AbstractModule() { + + @Override + protected void configure() { + bind(String.class).annotatedWith(Region.class).toInstance("us-east-1"); + bind(RunningInstance.Builder.class).to(AWSRunningInstance.Builder.class); + } + + }); + factory = injector.getInstance(ParseSax.Factory.class); + dateService = injector.getInstance(DateService.class); + assert dateService != null; + } + + public void testApplyInputStream() { + + InputStream is = getClass().getResourceAsStream("/run_instances.xml"); + + Reservation expected = new Reservation(defaultRegion, + ImmutableSet.of("default"), ImmutableSet.of( + + new AWSRunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("0").imageId( + "ami-60a54009").instanceId("i-2ba64342").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z")).monitoringState( + MonitoringState.ENABLED).availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new AWSRunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("1").imageId( + "ami-60a54009").instanceId("i-2bc64242").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z")).monitoringState( + MonitoringState.ENABLED).availabilityZone(AvailabilityZone.US_EAST_1B).build(), + + new AWSRunningInstance.Builder().region(defaultRegion).groupId("default").amiLaunchIndex("2").imageId( + "ami-60a54009").instanceId("i-2be64332").instanceState(InstanceState.PENDING).instanceType( + InstanceType.M1_SMALL).keyName("example-key-name").launchTime( + dateService.iso8601DateParse("2007-08-07T11:51:50.000Z")).monitoringState( + MonitoringState.ENABLED).availabilityZone(AvailabilityZone.US_EAST_1B).build()) + + , "AIDADH4IGTRXXKCD", null, "r-47a5402e"); + + AWSRunInstancesResponseHandler handler = injector.getInstance(AWSRunInstancesResponseHandler.class); + addDefaultRegionToHandler(handler); + Reservation result = factory.create(handler).parse(is); + assertEquals(result, expected); + } + + private void addDefaultRegionToHandler(ParseSax.HandlerWithResult handler) { + GeneratedHttpRequest request = createMock(GeneratedHttpRequest.class); + expect(request.getArgs()).andReturn(ImmutableList. of()).atLeastOnce(); + replay(request); + handler.setContext(request); + } +} diff --git a/apis/ec2/src/test/resources/describe_image_attribute_productCodes.xml b/providers/aws-ec2/src/test/resources/describe_image_attribute_productCodes.xml similarity index 100% rename from apis/ec2/src/test/resources/describe_image_attribute_productCodes.xml rename to providers/aws-ec2/src/test/resources/describe_image_attribute_productCodes.xml diff --git a/apis/ec2/src/test/resources/describe_placement_groups.xml b/providers/aws-ec2/src/test/resources/describe_placement_groups.xml similarity index 100% rename from apis/ec2/src/test/resources/describe_placement_groups.xml rename to providers/aws-ec2/src/test/resources/describe_placement_groups.xml diff --git a/apis/ec2/src/test/resources/describe_reserved_instances_offerings.xml b/providers/aws-ec2/src/test/resources/describe_reserved_instances_offerings.xml similarity index 100% rename from apis/ec2/src/test/resources/describe_reserved_instances_offerings.xml rename to providers/aws-ec2/src/test/resources/describe_reserved_instances_offerings.xml diff --git a/apis/ec2/src/test/resources/monitoring.xml b/providers/aws-ec2/src/test/resources/monitoring.xml similarity index 100% rename from apis/ec2/src/test/resources/monitoring.xml rename to providers/aws-ec2/src/test/resources/monitoring.xml diff --git a/providers/aws-s3/README.txt b/providers/aws-s3/README.txt new file mode 100644 index 0000000000..d3222f6f4a --- /dev/null +++ b/providers/aws-s3/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Amazon's S3 (http://aws.amazon.com/s3/). +# +# Expects the jclouds s3 API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. diff --git a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/AWSS3PropertiesBuilder.java b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/AWSS3PropertiesBuilder.java index fe382ddbeb..92a6232cc8 100644 --- a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/AWSS3PropertiesBuilder.java +++ b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/AWSS3PropertiesBuilder.java @@ -20,10 +20,13 @@ package org.jclouds.aws.s3; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.aws.domain.Region.AP_SOUTHEAST_1; import static org.jclouds.aws.domain.Region.EU_WEST_1; import static org.jclouds.aws.domain.Region.US_EAST_1; import static org.jclouds.aws.domain.Region.US_WEST_1; +import static org.jclouds.location.reference.LocationConstants.ENDPOINT; +import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; @@ -46,15 +49,20 @@ public class AWSS3PropertiesBuilder extends org.jclouds.s3.S3PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_REGIONS, - Joiner.on(',').join(Region.US_STANDARD, Region.US_WEST_1, "EU", Region.AP_SOUTHEAST_1)); + properties.setProperty(PROPERTY_ISO3166_CODES, "US,US-CA,IE,SG"); + properties.setProperty(PROPERTY_REGIONS, Joiner.on(',').join(Region.US_STANDARD, Region.US_WEST_1, "EU", + Region.AP_SOUTHEAST_1)); properties.setProperty(PROPERTY_ENDPOINT, "https://s3.amazonaws.com"); - properties.setProperty(PROPERTY_REGION + "." + Region.US_STANDARD + ".endpoint", "https://s3.amazonaws.com"); - properties.setProperty(PROPERTY_REGION + "." + Region.US_WEST_1 + ".endpoint", - "https://s3-us-west-1.amazonaws.com"); - properties.setProperty(PROPERTY_REGION + "." + "EU" + ".endpoint", "https://s3-eu-west-1.amazonaws.com"); - properties.setProperty(PROPERTY_REGION + "." + Region.AP_SOUTHEAST_1 + ".endpoint", - "https://s3-ap-southeast-1.amazonaws.com"); + properties.setProperty(PROPERTY_REGION + "." + Region.US_STANDARD + "." + ENDPOINT, "https://s3.amazonaws.com"); + properties.setProperty(PROPERTY_REGION + "." + Region.US_STANDARD + "." + ISO3166_CODES, "US"); + properties.setProperty(PROPERTY_REGION + "." + Region.US_WEST_1 + "." + ENDPOINT, + "https://s3-us-west-1.amazonaws.com"); + properties.setProperty(PROPERTY_REGION + "." + Region.US_WEST_1 + "." + ISO3166_CODES, "US-CA"); + properties.setProperty(PROPERTY_REGION + "." + "EU" + "." + ENDPOINT, "https://s3-eu-west-1.amazonaws.com"); + properties.setProperty(PROPERTY_REGION + "." + "EU" + "." + ISO3166_CODES, "IE"); + properties.setProperty(PROPERTY_REGION + "." + Region.AP_SOUTHEAST_1 + "." + ENDPOINT, + "https://s3-ap-southeast-1.amazonaws.com"); + properties.setProperty(PROPERTY_REGION + "." + Region.AP_SOUTHEAST_1 + "." + ISO3166_CODES, "SG"); return properties; } diff --git a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3AsyncClientTest.java b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3AsyncClientTest.java index 11a184bfd2..0cea0d22c4 100644 --- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3AsyncClientTest.java +++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3AsyncClientTest.java @@ -19,6 +19,17 @@ package org.jclouds.aws.s3; +import java.io.IOException; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.util.Properties; + +import org.jclouds.http.HttpRequest; +import org.jclouds.http.functions.ReturnTrueIf2xx; +import org.jclouds.rest.RestContextFactory; +import org.jclouds.s3.S3AsyncClient; +import org.jclouds.s3.functions.ReturnFalseIfBucketAlreadyOwnedByYouOrIllegalState; +import org.jclouds.s3.options.PutBucketOptions; import org.testng.annotations.Test; /** @@ -32,4 +43,27 @@ public class AWSS3AsyncClientTest extends org.jclouds.s3.S3AsyncClientTest { this.provider = "aws-s3"; } + @Override + protected Properties getProperties() { + return RestContextFactory.getPropertiesFromResource("/rest.properties"); + } + + public void testPutBucketEu() throws ArrayIndexOutOfBoundsException, SecurityException, IllegalArgumentException, + NoSuchMethodException, IOException { + Method method = S3AsyncClient.class.getMethod("putBucketInRegion", String.class, String.class, + Array.newInstance(PutBucketOptions.class, 0).getClass()); + HttpRequest request = processor.createRequest(method, "EU", "bucket"); + + assertRequestLineEquals(request, "PUT https://bucket." + url + "/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, "Host: bucket." + url + "\n"); + assertPayloadEquals(request, + "EU", + "text/xml", false); + + assertResponseParserClassEquals(method, request, ReturnTrueIf2xx.class); + assertSaxResponseParserClassEquals(method, null); + assertExceptionParserClassEquals(method, ReturnFalseIfBucketAlreadyOwnedByYouOrIllegalState.class); + + checkFilters(request); + } } diff --git a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3ServiceIntegrationLiveTest.java b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3ServiceIntegrationLiveTest.java index c72241df84..465a46f522 100644 --- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3ServiceIntegrationLiveTest.java +++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/blobstore/integration/AWSS3ServiceIntegrationLiveTest.java @@ -19,13 +19,21 @@ package org.jclouds.aws.s3.blobstore.integration; -import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest; +import java.util.Set; + +import org.jclouds.s3.blobstore.integration.S3ServiceIntegrationLiveTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ -@Test(groups = "live", testName = "AWSS3ServiceIntegrationLiveTest") -public class AWSS3ServiceIntegrationLiveTest extends BaseServiceIntegrationTest { +@Test(groups = "live", testName = "AWSS3ServiceIntegrationLiveTest") +public class AWSS3ServiceIntegrationLiveTest extends S3ServiceIntegrationLiveTest { + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US", "US-CA", "IE", "SG"); + } } diff --git a/providers/azureblob/README.txt b/providers/azureblob/README.txt new file mode 100644 index 0000000000..b98cd153b3 --- /dev/null +++ b/providers/azureblob/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Windows Azure's Storage (http://www.microsoft.com/windowsazure/storage/default.aspx). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. diff --git a/providers/azureblob/pom.xml b/providers/azureblob/pom.xml index aaba657908..aa20937509 100644 --- a/providers/azureblob/pom.xml +++ b/providers/azureblob/pom.xml @@ -31,7 +31,7 @@ org.jclouds.provider azureblob - jcloud azureblob provider + jclouds Azure Storage provider jclouds components to access Azure Blob Service diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java index 1eeacd790d..ae96bc0975 100644 --- a/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java +++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.azureblob; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_METADATA_PREFIX; import java.util.Properties; @@ -39,6 +40,7 @@ public class AzureBlobPropertiesBuilder extends AzureStoragePropertiesBuilder { properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-ms-meta-"); properties.setProperty(PROPERTY_API_VERSION, "2009-09-19"); properties.setProperty(PROPERTY_ENDPOINT, "https://{identity}.blob.core.windows.net"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-TX,US-IL,IE-D,SG,NL-NH,HK"); return properties; } diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java index 1c55ee4d57..bf0fe95f51 100644 --- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java +++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/config/AzureBlobStoreContextModule.java @@ -19,10 +19,6 @@ package org.jclouds.azureblob.blobstore.config; -import java.util.Set; - -import javax.inject.Singleton; - import org.jclouds.azureblob.AzureBlobAsyncClient; import org.jclouds.azureblob.AzureBlobClient; import org.jclouds.azureblob.blobstore.AzureAsyncBlobStore; @@ -37,17 +33,9 @@ import org.jclouds.blobstore.attr.ConsistencyModel; import org.jclouds.blobstore.config.BlobStoreMapModule; import org.jclouds.blobstore.internal.BlobStoreContextImpl; import org.jclouds.blobstore.strategy.ContainsValueInListStrategy; -import org.jclouds.collect.Memoized; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.location.Provider; +import org.jclouds.location.config.JustProviderLocationModule; -import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableSet; import com.google.inject.AbstractModule; -import com.google.inject.Provides; import com.google.inject.Scopes; import com.google.inject.TypeLiteral; @@ -61,6 +49,7 @@ public class AzureBlobStoreContextModule extends AbstractModule { @Override protected void configure() { install(new BlobStoreMapModule()); + install(new JustProviderLocationModule()); bind(ConsistencyModel.class).toInstance(ConsistencyModel.STRICT); bind(AsyncBlobStore.class).to(AzureAsyncBlobStore.class).in(Scopes.SINGLETON); bind(BlobStore.class).to(AzureBlobStore.class).in(Scopes.SINGLETON); @@ -70,18 +59,4 @@ public class AzureBlobStoreContextModule extends AbstractModule { bind(BlobRequestSigner.class).to(AzureBlobRequestSigner.class); } - @Provides - @Singleton - @Memoized - Supplier> provideLocations(Supplier defaultLocation) { - return Suppliers.> ofInstance(ImmutableSet.of(defaultLocation.get())); - } - - @Provides - @Singleton - Supplier provideDefaultLocation(@Provider String providerName) { - return Suppliers - . ofInstance(new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null)); - } - } diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/functions/AzureBlobToBlob.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/functions/AzureBlobToBlob.java index 08cacf7602..35f77ff241 100644 --- a/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/functions/AzureBlobToBlob.java +++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/blobstore/functions/AzureBlobToBlob.java @@ -35,7 +35,7 @@ import com.google.common.base.Function; */ @Singleton public class AzureBlobToBlob implements Function { - private final Blob.Factory blobFactory; + private final Factory blobFactory; private final BlobPropertiesToBlobMetadata blobPr2BlobMd; @Inject diff --git a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobServiceIntegrationLiveTest.java b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobServiceIntegrationLiveTest.java index 9112bd6168..ba3188663a 100644 --- a/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobServiceIntegrationLiveTest.java +++ b/providers/azureblob/src/test/java/org/jclouds/azureblob/blobstore/integration/AzureBlobServiceIntegrationLiveTest.java @@ -19,13 +19,20 @@ package org.jclouds.azureblob.blobstore.integration; +import java.util.Set; + import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ @Test(groups = "live") public class AzureBlobServiceIntegrationLiveTest extends BaseServiceIntegrationTest { - + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-TX", "US-IL", "IE-D", "SG", "NL-NH", "HK"); + } } diff --git a/providers/bluelock-vcdirector/README.txt b/providers/bluelock-vcdirector/README.txt index 3eb7e8335e..17cf4cf0bc 100644 --- a/providers/bluelock-vcdirector/README.txt +++ b/providers/bluelock-vcdirector/README.txt @@ -18,7 +18,9 @@ ==== # -# The jclouds provider for BlueLock's vCloud Director platform. +# The jclouds provider for BlueLock's vCloud Director (http://www.bluelock.com/bluelock-cloud-hosting/vcloud-datacenter/) platform. +# +# Expects the jclouds vcloud API to be present on your application's classpath. # # TODO: Implementation status. # TODO: Supported features. diff --git a/providers/bluelock-vcdirector/pom.xml b/providers/bluelock-vcdirector/pom.xml index 4c5be184c2..129a3da671 100644 --- a/providers/bluelock-vcdirector/pom.xml +++ b/providers/bluelock-vcdirector/pom.xml @@ -87,6 +87,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/bluelock-vcdirector/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorPropertiesBuilder.java b/providers/bluelock-vcdirector/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorPropertiesBuilder.java index 8b86f8aeb0..4f3f2d5cd8 100644 --- a/providers/bluelock-vcdirector/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorPropertiesBuilder.java +++ b/providers/bluelock-vcdirector/src/main/java/org/jclouds/vcloud/bluelock/BlueLockVCloudDirectorPropertiesBuilder.java @@ -20,6 +20,7 @@ package org.jclouds.vcloud.bluelock; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_DEFAULT_NETWORK; import java.util.Properties; @@ -35,6 +36,7 @@ public class BlueLockVCloudDirectorPropertiesBuilder extends VCloudPropertiesBui @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-IN"); properties.setProperty(PROPERTY_ENDPOINT, "https://vcenterprise.bluelock.com/api"); properties.setProperty(PROPERTY_VCLOUD_DEFAULT_NETWORK, "internet01"); return properties; diff --git a/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudDirectorComputeServiceLiveTest.java b/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudDirectorComputeServiceLiveTest.java index 4504a7f330..75e2b5717a 100644 --- a/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudDirectorComputeServiceLiveTest.java +++ b/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudDirectorComputeServiceLiveTest.java @@ -43,7 +43,7 @@ public class BlueLockVCloudDirectorComputeServiceLiveTest extends VCloudComputeS @Override public void setServiceDefaults() { - tag = "director"; + group = "director"; } @Test diff --git a/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudDirectorTemplateBuilderLiveTest.java b/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudDirectorTemplateBuilderLiveTest.java new file mode 100644 index 0000000000..f3f9501cba --- /dev/null +++ b/providers/bluelock-vcdirector/src/test/java/org/jclouds/vcloud/bluelock/compute/BlueLockVCloudDirectorTemplateBuilderLiveTest.java @@ -0,0 +1,59 @@ +package org.jclouds.vcloud.bluelock.compute; + +import static org.jclouds.compute.util.ComputeServiceUtils.getCores; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.util.Set; + +import org.jclouds.compute.BaseTemplateBuilderLiveTest; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live") +public class BlueLockVCloudDirectorTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { + + public BlueLockVCloudDirectorTemplateBuilderLiveTest() { + provider = "bluelock-vcdirector"; + } + + @Override + protected Predicate defineUnsupportedOperatingSystems() { + return new Predicate() { + + @Override + public boolean apply(OsFamilyVersion64Bit input) { + switch (input.family) { + case UBUNTU: + return !input.version.equals(""); + default: + return true; + } + } + + }; + } + + @Override + public void testDefaultTemplateBuilder() throws IOException { + Template defaultTemplate = context.getComputeService().templateBuilder().build(); + assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), ""); + assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); + assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); + assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); + } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-IN"); + } +} \ No newline at end of file diff --git a/providers/cloudfiles-uk/README.txt b/providers/cloudfiles-uk/README.txt new file mode 100644 index 0000000000..b7be2a8ac6 --- /dev/null +++ b/providers/cloudfiles-uk/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Rackspace's UK Cloud Files (http://www.rackspacecloud.com/cloud_hosting_products/files/). +# +# Expects the jclouds cloudfiles API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUKPropertiesBuilder.java b/providers/cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUKPropertiesBuilder.java index f20e176361..f0a927ccd1 100644 --- a/providers/cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUKPropertiesBuilder.java +++ b/providers/cloudfiles-uk/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUKPropertiesBuilder.java @@ -20,6 +20,7 @@ package org.jclouds.rackspace.cloudfiles; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.util.Properties; @@ -37,6 +38,7 @@ public class CloudFilesUKPropertiesBuilder extends SwiftPropertiesBuilder { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_REGIONS, "UK"); properties.setProperty(PROPERTY_ENDPOINT, "https://lon.auth.api.rackspacecloud.com"); + properties.setProperty(PROPERTY_ISO3166_CODES, "GB-SLG"); return properties; } diff --git a/providers/cloudfiles-uk/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUKServiceIntegrationLiveTest.java b/providers/cloudfiles-uk/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUKServiceIntegrationLiveTest.java index 51f682cadb..48a3da874b 100644 --- a/providers/cloudfiles-uk/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUKServiceIntegrationLiveTest.java +++ b/providers/cloudfiles-uk/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUKServiceIntegrationLiveTest.java @@ -19,13 +19,20 @@ package org.jclouds.rackspace.cloudfiles.blobstore.integration; +import java.util.Set; + import org.jclouds.cloudfiles.blobstore.integration.CloudFilesServiceIntegrationLiveTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ @Test(groups = "live", testName = "CloudFilesUKServiceIntegrationLiveTest") public class CloudFilesUKServiceIntegrationLiveTest extends CloudFilesServiceIntegrationLiveTest { - + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("GB-SLG"); + } } diff --git a/providers/cloudfiles-us/README.txt b/providers/cloudfiles-us/README.txt new file mode 100644 index 0000000000..9b98f21ffb --- /dev/null +++ b/providers/cloudfiles-us/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Rackspace's US Cloud Files (http://www.rackspacecloud.com/cloud_hosting_products/files/). +# +# Expects the jclouds cloudfiles API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUSPropertiesBuilder.java b/providers/cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUSPropertiesBuilder.java index 2db429c1c7..a710683c67 100644 --- a/providers/cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUSPropertiesBuilder.java +++ b/providers/cloudfiles-us/src/main/java/org/jclouds/rackspace/cloudfiles/CloudFilesUSPropertiesBuilder.java @@ -20,6 +20,7 @@ package org.jclouds.rackspace.cloudfiles; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.util.Properties; @@ -37,6 +38,7 @@ public class CloudFilesUSPropertiesBuilder extends SwiftPropertiesBuilder { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_REGIONS, "US"); properties.setProperty(PROPERTY_ENDPOINT, "https://auth.api.rackspacecloud.com"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-IL,US-TX"); return properties; } diff --git a/providers/cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java b/providers/cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java index 593a343890..c4eb029890 100644 --- a/providers/cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java +++ b/providers/cloudfiles-us/src/test/java/org/jclouds/rackspace/cloudfiles/blobstore/integration/CloudFilesUSServiceIntegrationLiveTest.java @@ -19,13 +19,20 @@ package org.jclouds.rackspace.cloudfiles.blobstore.integration; +import java.util.Set; + import org.jclouds.cloudfiles.blobstore.integration.CloudFilesServiceIntegrationLiveTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ -@Test(groups = "live", testName = "CloudFilesUSServiceIntegrationLiveTest") +@Test(groups = "live", testName = "CloudFilesUSServiceIntegrationLiveTest") public class CloudFilesUSServiceIntegrationLiveTest extends CloudFilesServiceIntegrationLiveTest { - -} + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-IL", "US-TX"); + } +} \ No newline at end of file diff --git a/providers/cloudonestorage/README.txt b/providers/cloudonestorage/README.txt new file mode 100644 index 0000000000..e3d172f579 --- /dev/null +++ b/providers/cloudonestorage/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Peer1's CloudOne Storage (http://www.peer1.com/hosting/cloudone-storage.php) service. +# +# Expects the jclouds atmos API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/cloudonestorage/src/main/java/org/jclouds/cloudonestorage/CloudOneStoragePropertiesBuilder.java b/providers/cloudonestorage/src/main/java/org/jclouds/cloudonestorage/CloudOneStoragePropertiesBuilder.java index 079be57aeb..94efa2716f 100644 --- a/providers/cloudonestorage/src/main/java/org/jclouds/cloudonestorage/CloudOneStoragePropertiesBuilder.java +++ b/providers/cloudonestorage/src/main/java/org/jclouds/cloudonestorage/CloudOneStoragePropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.cloudonestorage; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -37,6 +38,7 @@ public class CloudOneStoragePropertiesBuilder extends PropertiesBuilder { protected Properties defaultProperties() { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_ENDPOINT, "https://cloudonestorage.peer1.com"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-GA,US-TX"); properties.setProperty(PROPERTY_API_VERSION, "1.3.0"); return properties; } diff --git a/providers/cloudonestorage/src/test/java/org/jclouds/cloudonestorage/blobstore/integration/CloudOneStorageServiceIntegrationLiveTest.java b/providers/cloudonestorage/src/test/java/org/jclouds/cloudonestorage/blobstore/integration/CloudOneStorageServiceIntegrationLiveTest.java index 1b87e26f08..0019a78db8 100644 --- a/providers/cloudonestorage/src/test/java/org/jclouds/cloudonestorage/blobstore/integration/CloudOneStorageServiceIntegrationLiveTest.java +++ b/providers/cloudonestorage/src/test/java/org/jclouds/cloudonestorage/blobstore/integration/CloudOneStorageServiceIntegrationLiveTest.java @@ -19,13 +19,20 @@ package org.jclouds.cloudonestorage.blobstore.integration; +import java.util.Set; + import org.jclouds.atmos.blobstore.integration.AtmosServiceIntegrationLiveTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ -@Test(groups = "live", testName = "CloudOneStorageServiceIntegrationLiveTest") +@Test(groups = "live", testName = "CloudOneStorageServiceIntegrationLiveTest") public class CloudOneStorageServiceIntegrationLiveTest extends AtmosServiceIntegrationLiveTest { - + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-GA", "US-TX"); + } } diff --git a/providers/cloudservers-uk/README.txt b/providers/cloudservers-uk/README.txt new file mode 100644 index 0000000000..5d90f15cb8 --- /dev/null +++ b/providers/cloudservers-uk/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Rackspace's UK Cloud Servers (http://www.rackspacecloud.com/cloud_hosting_products/servers/). +# +# Expects the jclouds cloudservers API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/cloudservers-uk/pom.xml b/providers/cloudservers-uk/pom.xml index 5b233d50ec..d882b4bf06 100644 --- a/providers/cloudservers-uk/pom.xml +++ b/providers/cloudservers-uk/pom.xml @@ -85,6 +85,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUKPropertiesBuilder.java b/providers/cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUKPropertiesBuilder.java index 81df7d9e66..8f32cb8481 100644 --- a/providers/cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUKPropertiesBuilder.java +++ b/providers/cloudservers-uk/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUKPropertiesBuilder.java @@ -21,7 +21,7 @@ package org.jclouds.rackspace.cloudservers; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; -import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -37,7 +37,7 @@ public class CloudServersUKPropertiesBuilder extends PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_REGIONS, "UK"); + properties.setProperty(PROPERTY_ISO3166_CODES, "GB-SLG"); properties.setProperty(PROPERTY_ENDPOINT, "https://lon.auth.api.rackspacecloud.com"); properties.setProperty(PROPERTY_API_VERSION, OpenStackAuthAsyncClient.VERSION); return properties; diff --git a/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKComputeServiceLiveTest.java b/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKComputeServiceLiveTest.java index 44c8307490..c8902508bb 100644 --- a/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKComputeServiceLiveTest.java +++ b/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKComputeServiceLiveTest.java @@ -31,7 +31,7 @@ public class CloudServersUKComputeServiceLiveTest extends CloudServersComputeSer public CloudServersUKComputeServiceLiveTest() { provider = "cloudservers-uk"; - tag = "cs"; + group = "cs"; } } diff --git a/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKTemplateBuilderLiveTest.java b/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKTemplateBuilderLiveTest.java index bcd71630f6..c103555616 100644 --- a/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKTemplateBuilderLiveTest.java +++ b/providers/cloudservers-uk/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUKTemplateBuilderLiveTest.java @@ -22,6 +22,8 @@ package org.jclouds.rackspace.cloudservers.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; +import java.util.Set; + import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; @@ -29,6 +31,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -47,12 +50,17 @@ public class CloudServersUKTemplateBuilderLiveTest extends BaseTemplateBuilderLi @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); + switch (input.family) { + case UBUNTU: + return input.version.equals("11.04") || input.version.equals("8.04") || !input.is64Bit; + case CENTOS: + return input.version.matches("5.[023]") || !input.is64Bit; + case WINDOWS: + return input.version.equals("2008") || input.version.indexOf("2003") != -1 + || (input.version.equals("2008 R2") && !input.is64Bit); + default: + return true; + } } }; @@ -64,8 +72,12 @@ public class CloudServersUKTemplateBuilderLiveTest extends BaseTemplateBuilderLi assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); - assertEquals(defaultTemplate.getLocation().getId(), "UK"); + assertEquals(defaultTemplate.getLocation().getId(), provider); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("GB-SLG"); + } } diff --git a/providers/cloudservers-us/README.txt b/providers/cloudservers-us/README.txt new file mode 100644 index 0000000000..5a845903ec --- /dev/null +++ b/providers/cloudservers-us/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Rackspace's US Cloud Servers (http://www.rackspacecloud.com/cloud_hosting_products/servers/). +# +# Expects the jclouds cloudservers API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/cloudservers-us/pom.xml b/providers/cloudservers-us/pom.xml index eda16cbe49..2f57332e49 100644 --- a/providers/cloudservers-us/pom.xml +++ b/providers/cloudservers-us/pom.xml @@ -85,6 +85,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUSPropertiesBuilder.java b/providers/cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUSPropertiesBuilder.java index 688b685b9e..d363fa6954 100644 --- a/providers/cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUSPropertiesBuilder.java +++ b/providers/cloudservers-us/src/main/java/org/jclouds/rackspace/cloudservers/CloudServersUSPropertiesBuilder.java @@ -21,7 +21,7 @@ package org.jclouds.rackspace.cloudservers; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; -import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -37,7 +37,7 @@ public class CloudServersUSPropertiesBuilder extends PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_REGIONS, "US"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-IL,US-TX"); properties.setProperty(PROPERTY_ENDPOINT, "https://auth.api.rackspacecloud.com"); properties.setProperty(PROPERTY_API_VERSION, OpenStackAuthAsyncClient.VERSION); return properties; diff --git a/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSComputeServiceLiveTest.java b/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSComputeServiceLiveTest.java index 6ba4037c67..7efb40a8aa 100644 --- a/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSComputeServiceLiveTest.java +++ b/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSComputeServiceLiveTest.java @@ -31,7 +31,7 @@ public class CloudServersUSComputeServiceLiveTest extends CloudServersComputeSer public CloudServersUSComputeServiceLiveTest() { provider = "cloudservers-us"; - tag = "cs"; + group = "cs"; } } diff --git a/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java b/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java index c58e96e237..ce5f4f90e2 100644 --- a/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java +++ b/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java @@ -22,6 +22,8 @@ package org.jclouds.rackspace.cloudservers.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; +import java.util.Set; + import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; @@ -29,6 +31,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -47,12 +50,17 @@ public class CloudServersUSTemplateBuilderLiveTest extends BaseTemplateBuilderLi @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); + switch (input.family) { + case UBUNTU: + return input.version.equals("11.04") || input.version.equals("8.04") || !input.is64Bit; + case CENTOS: + return input.version.matches("5.[023]") || !input.is64Bit; + case WINDOWS: + return input.version.equals("2008") || input.version.indexOf("2003") != -1 + || (input.version.equals("2008 R2") && !input.is64Bit); + default: + return true; + } } }; @@ -64,7 +72,12 @@ public class CloudServersUSTemplateBuilderLiveTest extends BaseTemplateBuilderLi assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04"); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); - assertEquals(defaultTemplate.getLocation().getId(), "US"); + assertEquals(defaultTemplate.getLocation().getId(), provider); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-IL", "US-TX"); + } } diff --git a/providers/cloudsigma-zrh/README.txt b/providers/cloudsigma-zrh/README.txt new file mode 100644 index 0000000000..8e25a9853c --- /dev/null +++ b/providers/cloudsigma-zrh/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for CloudSigma (http://www.cloudsigma.com/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/cloudsigma-zrh/pom.xml b/providers/cloudsigma-zrh/pom.xml index 7d7928b207..d31945b626 100644 --- a/providers/cloudsigma-zrh/pom.xml +++ b/providers/cloudsigma-zrh/pom.xml @@ -56,6 +56,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + org.jclouds jclouds-core @@ -80,7 +86,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java index 5e683d6fc1..c271e0ce7b 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaAsyncClient.java @@ -26,6 +26,7 @@ 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.cloudsigma.binders.BindCloneDriveOptionsToPlainTextString; @@ -38,18 +39,26 @@ import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.ProfileInfo; import org.jclouds.cloudsigma.domain.Server; import org.jclouds.cloudsigma.domain.ServerInfo; +import org.jclouds.cloudsigma.domain.StaticIPInfo; +import org.jclouds.cloudsigma.domain.VLANInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToProfileInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo; +import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToStaticIPInfo; +import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToVLANInfo; import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet; +import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet; +import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet; import org.jclouds.cloudsigma.functions.SplitNewlines; +import org.jclouds.cloudsigma.functions.SplitNewlinesAndReturnSecondField; import org.jclouds.cloudsigma.options.CloneDriveOptions; import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.Payload; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.ResponseParser; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; @@ -100,8 +109,8 @@ public interface CloudSigmaAsyncClient { @ResponseParser(KeyValuesDelimitedByBlankLinesToDriveInfo.class) @Path("/drives/{uuid}/clone") @MapBinder(BindCloneDriveOptionsToPlainTextString.class) - ListenableFuture cloneDrive(@PathParam("uuid") String sourceUuid, - @MapPayloadParam("name") String newName, CloneDriveOptions... options); + ListenableFuture cloneDrive(@PathParam("uuid") String sourceUuid, @PayloadParam("name") String newName, + CloneDriveOptions... options); /** * @see CloudSigmaClient#getProfileInfo @@ -242,4 +251,101 @@ public interface CloudSigmaAsyncClient { @Path("/drives/{uuid}/destroy") @ExceptionParser(ReturnVoidOnNotFoundOr404.class) ListenableFuture destroyDrive(@PathParam("uuid") String uuid); + + /** + * @see CloudSigmaClient#createVLAN + */ + @POST + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToVLANInfo.class) + @Path("/resources/vlan/create") + @Payload("name {name}\n") + @Produces(MediaType.TEXT_PLAIN) + ListenableFuture createVLAN(@PayloadParam("name") String name); + + /** + * @see CloudSigmaClient#listVLANInfo + */ + @GET + @Path("/resources/vlan/info") + @ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet.class) + ListenableFuture> listVLANInfo(); + + /** + * @see CloudSigmaClient#getVLANInfo + */ + @GET + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToVLANInfo.class) + @Path("/resources/vlan/{uuid}/info") + ListenableFuture getVLANInfo(@PathParam("uuid") String uuid); + + /** + * @see CloudSigmaClient#setVLANConfiguration + */ + @POST + @ResponseParser(KeyValuesDelimitedByBlankLinesToVLANInfo.class) + @Path("/resources/vlan/{uuid}/set") + @Payload("name {name}\n") + @Produces(MediaType.TEXT_PLAIN) + ListenableFuture renameVLAN(@PathParam("uuid") String uuid, @PayloadParam("name") String name); + + /** + * @see CloudSigmaClient#listVLANs + */ + @GET + @Path("/resources/vlan/list") + @ResponseParser(SplitNewlinesAndReturnSecondField.class) + ListenableFuture> listVLANs(); + + /** + * @see CloudSigmaClient#destroyVLAN + */ + @POST + @Path("/resources/vlan/{uuid}/destroy") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture destroyVLAN(@PathParam("uuid") String uuid); + + /** + * @see CloudSigmaClient#createStaticIP + */ + @POST + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToStaticIPInfo.class) + @Path("/resources/ip/create") + ListenableFuture createStaticIP(); + + /** + * @see CloudSigmaClient#listStaticIPInfo + */ + @GET + @Path("/resources/ip/info") + @ResponseParser(ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet.class) + ListenableFuture> listStaticIPInfo(); + + /** + * @see CloudSigmaClient#getStaticIPInfo + */ + @GET + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + @ResponseParser(KeyValuesDelimitedByBlankLinesToStaticIPInfo.class) + @Path("/resources/ip/{uuid}/info") + ListenableFuture getStaticIPInfo(@PathParam("uuid") String uuid); + + /** + * @see CloudSigmaClient#listStaticIPs + */ + @GET + @Path("/resources/ip/list") + @ResponseParser(SplitNewlinesAndReturnSecondField.class) + ListenableFuture> listStaticIPs(); + + /** + * @see CloudSigmaClient#destroyStaticIP + */ + @POST + @Path("/resources/ip/{uuid}/destroy") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture destroyStaticIP(@PathParam("uuid") String uuid); + } diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java index 7540990fc9..715dba01ca 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaClient.java @@ -28,6 +28,8 @@ import org.jclouds.cloudsigma.domain.DriveInfo; import org.jclouds.cloudsigma.domain.ProfileInfo; import org.jclouds.cloudsigma.domain.Server; import org.jclouds.cloudsigma.domain.ServerInfo; +import org.jclouds.cloudsigma.domain.StaticIPInfo; +import org.jclouds.cloudsigma.domain.VLANInfo; import org.jclouds.cloudsigma.options.CloneDriveOptions; import org.jclouds.concurrent.Timeout; @@ -40,7 +42,7 @@ import org.jclouds.concurrent.Timeout; * @author Adrian Cole */ @Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) -public interface CloudSigmaClient { +public interface CloudSigmaClient { /** * Get profile info @@ -48,14 +50,14 @@ public interface CloudSigmaClient { * @return info or null, if not found */ ProfileInfo getProfileInfo(); - + /** * list of server uuids in your account * * @return or empty set if no servers are found */ Set listServers(); - + /** * Get all servers info * @@ -220,5 +222,88 @@ public interface CloudSigmaClient { */ DriveInfo cloneDrive(String sourceUuid, String newName, CloneDriveOptions... options); + /** + * list of vlan uuids in your account + * + * @return or empty set if no vlans are found + */ + Set listVLANs(); + + /** + * Get all vlans info + * + * @return or empty set if no vlans are found + */ + Set listVLANInfo(); + + /** + * @param uuid + * what to get + * @return null, if not found + */ + VLANInfo getVLANInfo(String uuid); + + /** + * create a new vlan + * + * @param vlan + * @return newly created vlan + */ + VLANInfo createVLAN(String name); + + /** + * set vlan configuration + * + * @param uuid + * what vlan to change + * @param newName + * what the new name is + * @return new data + */ + VLANInfo renameVLAN(String uuid, String newName); + + /** + * Destroy a vlan + * + * @param uuid + * what to destroy + */ + void destroyVLAN(String uuid); + + /** + * list of ip uuids in your account + * + * @return or empty set if no ips are found + */ + Set listStaticIPs(); + + /** + * Get all ips info + * + * @return or empty set if no ips are found + */ + Set listStaticIPInfo(); + + /** + * @param uuid + * what to get + * @return null, if not found + */ + StaticIPInfo getStaticIPInfo(String uuid); + + /** + * create a new ip + * + * @return newly created ip + */ + StaticIPInfo createStaticIP(); + + /** + * Destroy a ip + * + * @param uuid + * what to destroy + */ + void destroyStaticIP(String uuid); } diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaZurichPropertiesBuilder.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaZurichPropertiesBuilder.java index b66062e3eb..fbd07b5678 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaZurichPropertiesBuilder.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/CloudSigmaZurichPropertiesBuilder.java @@ -20,6 +20,7 @@ package org.jclouds.cloudsigma; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -32,6 +33,7 @@ public class CloudSigmaZurichPropertiesBuilder extends CloudSigmaPropertiesBuild @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "CH-ZH"); properties.setProperty(PROPERTY_ENDPOINT, "https://api.cloudsigma.com"); return properties; } diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java index 24f9d0d3af..847d2586bd 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java @@ -23,7 +23,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; -import java.net.URI; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; @@ -56,9 +55,7 @@ import org.jclouds.compute.domain.internal.VolumeImpl; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.location.Provider; +import org.jclouds.location.suppliers.JustProvider; import org.jclouds.logging.Logger; import com.google.common.base.Function; @@ -75,21 +72,20 @@ import com.google.common.collect.ImmutableSet.Builder; */ @Singleton public class CloudSigmaComputeServiceAdapter implements - ComputeServiceAdapter { + ComputeServiceAdapter { private static final Predicate PREINSTALLED_DISK = Predicates.and(Predicates.notNull(), - new Predicate() { + new Predicate() { - @Override - public boolean apply(DriveInfo drive) { - return drive.getType().equals(DriveType.DISK) && drive.getDriveType().contains("preinstalled"); - } + @Override + public boolean apply(DriveInfo drive) { + return drive.getType().equals(DriveType.DISK) && drive.getDriveType().contains("preinstalled"); + } - }); + }); private final CloudSigmaClient client; private final CloudSigmaAsyncClient aclient; private final Predicate driveNotClaimed; - private final String providerName; - private final URI providerURI; + private final JustProvider locationSupplier; private final String defaultVncPassword; private final Map cache; private final ExecutorService executor; @@ -100,26 +96,25 @@ public class CloudSigmaComputeServiceAdapter implements @Inject public CloudSigmaComputeServiceAdapter(CloudSigmaClient client, CloudSigmaAsyncClient aclient, - Predicate driveNotClaimed, @Provider String providerName, @Provider URI providerURI, - @Named(CloudSigmaConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword, Map cache, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { + Predicate driveNotClaimed, JustProvider locationSupplier, + @Named(CloudSigmaConstants.PROPERTY_VNC_PASSWORD) String defaultVncPassword, Map cache, + @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { this.client = checkNotNull(client, "client"); this.aclient = checkNotNull(aclient, "aclient"); this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed"); - this.providerName = checkNotNull(providerName, "providerName"); - this.providerURI = checkNotNull(providerURI, "providerURI"); + this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); this.cache = checkNotNull(cache, "cache"); this.executor = checkNotNull(executor, "executor"); } @Override - public ServerInfo runNodeWithTagAndNameAndStoreCredentials(String tag, String name, Template template, - Map credentialStore) { + public ServerInfo createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, + Map credentialStore) { long bootSize = (long) (template.getHardware().getVolumes().get(0).getSize() * 1024 * 1024 * 1024l); logger.debug(">> imaging boot drive source(%s) bytes(%d)", template.getImage().getId(), bootSize); DriveInfo drive = client.cloneDrive(template.getImage().getId(), template.getImage().getId(), - new CloneDriveOptions().size(bootSize)); + new CloneDriveOptions().size(bootSize)); boolean success = driveNotClaimed.apply(drive); logger.debug("<< image(%s) complete(%s)", drive.getUuid(), success); if (!success) { @@ -127,7 +122,7 @@ public class CloudSigmaComputeServiceAdapter implements throw new IllegalStateException("could not image drive in time!"); } Server toCreate = Servers.small(name, drive.getUuid(), defaultVncPassword).mem(template.getHardware().getRam()) - .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())).build(); + .cpu((int) (template.getHardware().getProcessors().get(0).getSpeed())).build(); logger.debug(">> creating server"); ServerInfo from = client.createServer(toCreate); @@ -159,8 +154,8 @@ public class CloudSigmaComputeServiceAdapter implements return "sizeLessThanOrEqual(" + size + ")"; } - }).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu))) - .volumes(ImmutableList. of(new VolumeImpl(size, true, true))).build()); + }).ids(id).ram(ram).processors(ImmutableList.of(new Processor(1, cpu))).volumes( + ImmutableList. of(new VolumeImpl(size, true, true))).build()); } return hardware.build(); } @@ -171,14 +166,14 @@ public class CloudSigmaComputeServiceAdapter implements @Override public Iterable listImages() { Iterable drives = transformParallel(client.listStandardDrives(), - new Function>() { + new Function>() { - @Override - public Future apply(String input) { - return aclient.getDriveInfo(input); - } + @Override + public Future apply(String input) { + return aclient.getDriveInfo(input); + } - }, executor, null, logger, "drives"); + }, executor, null, logger, "drives"); Iterable returnVal = filter(drives, PREINSTALLED_DISK); for (DriveInfo drive : returnVal) cache.put(drive.getUuid(), drive); @@ -191,10 +186,10 @@ public class CloudSigmaComputeServiceAdapter implements return (Iterable) client.listServerInfo(); } + @SuppressWarnings("unchecked") @Override public Iterable listLocations() { - return ImmutableSet. of(new LocationImpl(LocationScope.PROVIDER, providerName, providerURI - .toASCIIString(), null)); + return (Iterable) locationSupplier.get(); } @Override diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java index 03ec5b677c..913e4bdcae 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/config/CloudSigmaComputeServiceContextModule.java @@ -52,11 +52,13 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Location; import org.jclouds.functions.IdentityFunction; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; import org.jclouds.predicates.RetryablePredicate; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Predicates; +import com.google.common.base.Supplier; import com.google.common.collect.MapMaker; import com.google.inject.Injector; import com.google.inject.Provides; @@ -101,7 +103,8 @@ public class CloudSigmaComputeServiceContextModule }).to(FindImageForId.class); bind(new TypeLiteral>() { }).to(ParseOsFamilyVersion64BitFromImageName.class); - + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZone.class); } @Provides diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java index 0d838a1b0a..6a2306fe51 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/compute/functions/ServerInfoToNodeMetadata.java @@ -20,7 +20,7 @@ package org.jclouds.cloudsigma.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import java.util.List; import java.util.Map; @@ -92,7 +92,7 @@ public class ServerInfoToNodeMetadata implements Function + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not user 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.cloudsigma.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Set; + +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +public class StaticIPInfo { + public static class Builder { + protected String ip; + protected String user; + protected String netmask; + protected Set nameservers = ImmutableSet.of(); + protected String gateway; + + public Builder ip(String ip) { + this.ip = ip; + return this; + } + + public Builder user(String user) { + this.user = user; + return this; + } + + public Builder nameservers(Iterable nameservers) { + this.nameservers = ImmutableSet.copyOf(checkNotNull(nameservers, "nameservers")); + return this; + } + + public Builder gateway(String gateway) { + this.gateway = gateway; + return this; + } + + public Builder netmask(String netmask) { + this.netmask = netmask; + return this; + } + + public StaticIPInfo build() { + return new StaticIPInfo(ip, user, netmask, nameservers, gateway); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((gateway == null) ? 0 : gateway.hashCode()); + result = prime * result + ((nameservers == null) ? 0 : nameservers.hashCode()); + result = prime * result + ((netmask == null) ? 0 : netmask.hashCode()); + result = prime * result + ((user == null) ? 0 : user.hashCode()); + result = prime * result + ((ip == null) ? 0 : ip.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; + Builder other = (Builder) obj; + if (gateway == null) { + if (other.gateway != null) + return false; + } else if (!gateway.equals(other.gateway)) + return false; + if (nameservers == null) { + if (other.nameservers != null) + return false; + } else if (!nameservers.equals(other.nameservers)) + return false; + if (netmask == null) { + if (other.netmask != null) + return false; + } else if (!netmask.equals(other.netmask)) + return false; + if (user == null) { + if (other.user != null) + return false; + } else if (!user.equals(other.user)) + return false; + if (ip == null) { + if (other.ip != null) + return false; + } else if (!ip.equals(other.ip)) + return false; + return true; + } + } + + protected final String ip; + protected final String user; + protected final String netmask; + protected final Set nameservers; + protected final String gateway; + + public StaticIPInfo(String ip, String user, String netmask, Iterable nameservers, String gateway) { + this.ip = checkNotNull(ip, "ip"); + this.user = checkNotNull(user, "user"); + this.netmask = checkNotNull(netmask, "netmask"); + this.nameservers = ImmutableSet.copyOf(checkNotNull(nameservers, "nameservers")); + this.gateway = checkNotNull(gateway, "gateway"); + } + + /** + * + * @return ip of the ip. + */ + @Nullable + public String getAddress() { + return ip; + } + + /** + * + * @return user owning the ip + */ + public String getUser() { + return user; + } + + /** + * + * @return netmask of the ip + */ + public String getNetmask() { + return netmask; + } + + /** + * + * @return nameservers of the ip + */ + public Set getNameservers() { + return nameservers; + } + + /** + * + * @return gateway of the ip + */ + public String getGateway() { + return gateway; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((gateway == null) ? 0 : gateway.hashCode()); + result = prime * result + ((nameservers == null) ? 0 : nameservers.hashCode()); + result = prime * result + ((netmask == null) ? 0 : netmask.hashCode()); + result = prime * result + ((user == null) ? 0 : user.hashCode()); + result = prime * result + ((ip == null) ? 0 : ip.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; + StaticIPInfo other = (StaticIPInfo) obj; + if (gateway == null) { + if (other.gateway != null) + return false; + } else if (!gateway.equals(other.gateway)) + return false; + if (nameservers == null) { + if (other.nameservers != null) + return false; + } else if (!nameservers.equals(other.nameservers)) + return false; + if (netmask == null) { + if (other.netmask != null) + return false; + } else if (!netmask.equals(other.netmask)) + return false; + if (user == null) { + if (other.user != null) + return false; + } else if (!user.equals(other.user)) + return false; + if (ip == null) { + if (other.ip != null) + return false; + } else if (!ip.equals(other.ip)) + return false; + return true; + } + + @Override + public String toString() { + return "[ip=" + ip + ", user=" + user + ", netmask=" + netmask + ", nameservers=" + + nameservers + ", gateway=" + gateway + "]"; + } + +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/domain/VLANInfo.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/domain/VLANInfo.java new file mode 100644 index 0000000000..15d6d2a430 --- /dev/null +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/domain/VLANInfo.java @@ -0,0 +1,166 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not user 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.cloudsigma.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Nullable; + +/** + * + * @author Adrian Cole + */ +public class VLANInfo { + public static class Builder { + protected String uuid; + protected String name; + protected String user; + + public Builder uuid(String uuid) { + this.uuid = uuid; + return this; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder user(String user) { + this.user = user; + return this; + } + + public VLANInfo build() { + return new VLANInfo(uuid, name, user); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((user == null) ? 0 : user.hashCode()); + result = prime * result + ((uuid == null) ? 0 : uuid.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; + Builder other = (Builder) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (user == null) { + if (other.user != null) + return false; + } else if (!user.equals(other.user)) + return false; + if (uuid == null) { + if (other.uuid != null) + return false; + } else if (!uuid.equals(other.uuid)) + return false; + return true; + } + } + + @Nullable + protected final String uuid; + protected final String name; + protected final String user; + + public VLANInfo(String uuid, String name, String user) { + this.uuid = checkNotNull(uuid, "uuid"); + this.name = checkNotNull(name, "name"); + this.user = checkNotNull(user, "user"); + } + + /** + * + * @return uuid of the vlan. + */ + @Nullable + public String getUuid() { + return uuid; + } + + /** + * + * @return name of the vlan + */ + public String getName() { + return name; + } + + /** + * + * @return user owning the vlan + */ + public String getUser() { + return user; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((user == null) ? 0 : user.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; + VLANInfo other = (VLANInfo) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (user == null) { + if (other.user != null) + return false; + } else if (!user.equals(other.user)) + return false; + + return true; + } + + @Override + public String toString() { + return "[uuid=" + uuid + ", name=" + name + ", user=" + user + "]"; + } + +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToStaticIPInfo.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToStaticIPInfo.java new file mode 100644 index 0000000000..32d8f9aa67 --- /dev/null +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToStaticIPInfo.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.cloudsigma.domain.StaticIPInfo; +import org.jclouds.http.HttpResponse; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class KeyValuesDelimitedByBlankLinesToStaticIPInfo implements Function { + private final ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet setParser; + + @Inject + public KeyValuesDelimitedByBlankLinesToStaticIPInfo(ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet setParser) { + this.setParser = setParser; + } + + @Override + public StaticIPInfo apply(HttpResponse response) { + Set drives = setParser.apply(response); + if (drives.size() == 0) + return null; + return Iterables.get(drives, 0); + } +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToVLANInfo.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToVLANInfo.java new file mode 100644 index 0000000000..0856c2e33e --- /dev/null +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToVLANInfo.java @@ -0,0 +1,53 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.cloudsigma.domain.VLANInfo; +import org.jclouds.http.HttpResponse; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class KeyValuesDelimitedByBlankLinesToVLANInfo implements Function { + private final ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet setParser; + + @Inject + public KeyValuesDelimitedByBlankLinesToVLANInfo(ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet setParser) { + this.setParser = setParser; + } + + @Override + public VLANInfo apply(HttpResponse response) { + Set drives = setParser.apply(response); + if (drives.size() == 0) + return null; + return Iterables.get(drives, 0); + } +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet.java new file mode 100644 index 0000000000..a754299cb4 --- /dev/null +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet.java @@ -0,0 +1,60 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.cloudsigma.domain.StaticIPInfo; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ReturnStringIf2xx; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet implements Function> { + private final ReturnStringIf2xx returnStringIf200; + private final ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter; + private final MapToStaticIPInfo mapToProfile; + + @Inject + ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet(ReturnStringIf2xx returnStringIf200, + ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter, MapToStaticIPInfo mapToProfile) { + this.returnStringIf200 = returnStringIf200; + this.mapConverter = mapConverter; + this.mapToProfile = mapToProfile; + } + + @Override + public Set apply(HttpResponse response) { + String text = returnStringIf200.apply(response); + if (text == null || text.trim().equals("")) + return ImmutableSet. of(); + return ImmutableSet.copyOf(Iterables.transform(mapConverter.apply(text), mapToProfile)); + } +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet.java new file mode 100644 index 0000000000..f87a49697c --- /dev/null +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet.java @@ -0,0 +1,60 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.cloudsigma.domain.VLANInfo; +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ReturnStringIf2xx; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet implements Function> { + private final ReturnStringIf2xx returnStringIf200; + private final ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter; + private final MapToVLANInfo mapToProfile; + + @Inject + ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet(ReturnStringIf2xx returnStringIf200, + ListOfKeyValuesDelimitedByBlankLinesToListOfMaps mapConverter, MapToVLANInfo mapToProfile) { + this.returnStringIf200 = returnStringIf200; + this.mapConverter = mapConverter; + this.mapToProfile = mapToProfile; + } + + @Override + public Set apply(HttpResponse response) { + String text = returnStringIf200.apply(response); + if (text == null || text.trim().equals("")) + return ImmutableSet. of(); + return ImmutableSet.copyOf(Iterables.transform(mapConverter.apply(text), mapToProfile)); + } +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/MapToStaticIPInfo.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/MapToStaticIPInfo.java new file mode 100644 index 0000000000..13e3fab877 --- /dev/null +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/MapToStaticIPInfo.java @@ -0,0 +1,63 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import java.util.Map; + +import javax.annotation.Resource; +import javax.inject.Singleton; + +import org.jclouds.cloudsigma.domain.StaticIPInfo; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Splitter; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class MapToStaticIPInfo implements Function, StaticIPInfo> { + + @Resource + protected Logger logger = Logger.NULL; + + @Override + public StaticIPInfo apply(Map from) { + if (from.size() == 0) + return null; + if (from.size() == 0) + return null; + StaticIPInfo.Builder builder = new StaticIPInfo.Builder(); + builder.ip(from.get("resource")); + builder.user(from.get("user")); + builder.netmask(from.get("netmask")); + builder.nameservers(Splitter.on(' ').split(from.get("nameserver"))); + builder.gateway(from.get("gateway")); + + try { + return builder.build(); + } catch (NullPointerException e) { + logger.trace("entry missing data: %s; %s", e.getMessage(), from); + return null; + } + } +} \ No newline at end of file diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindAdminPassToJsonPayload.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/MapToVLANInfo.java similarity index 50% rename from apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindAdminPassToJsonPayload.java rename to providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/MapToVLANInfo.java index 06d148b0fa..0f6953ac59 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindAdminPassToJsonPayload.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/MapToVLANInfo.java @@ -17,37 +17,43 @@ * ==================================================================== */ -package org.jclouds.cloudservers.binders; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; +package org.jclouds.cloudsigma.functions; import java.util.Map; +import javax.annotation.Resource; import javax.inject.Singleton; -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.BindToJsonPayload; +import org.jclouds.cloudsigma.domain.VLANInfo; +import org.jclouds.logging.Logger; -import com.google.common.collect.ImmutableMap; +import com.google.common.base.Function; /** * * @author Adrian Cole - * */ @Singleton -public class BindAdminPassToJsonPayload extends BindToJsonPayload { +public class MapToVLANInfo implements Function, VLANInfo> { + + @Resource + protected Logger logger = Logger.NULL; @Override - public R bindToRequest(R request, Map postParams) { - throw new IllegalStateException("Change Admin Pass is a PUT operation"); + public VLANInfo apply(Map from) { + if (from.size() == 0) + return null; + if (from.size() == 0) + return null; + VLANInfo.Builder builder = new VLANInfo.Builder(); + builder.uuid(from.get("resource")); + builder.name(from.get("name")); + builder.user(from.get("user")); + try { + return builder.build(); + } catch (NullPointerException e) { + logger.trace("entry missing data: %s; %s", e.getMessage(), from); + return null; + } } - - @Override - public R bindToRequest(R request, Object toBind) { - checkArgument(toBind instanceof String, "this binder is only valid for Strings!"); - return super.bindToRequest(request, - ImmutableMap.of("server", ImmutableMap.of("adminPass", checkNotNull(toBind, "adminPass")))); - } -} +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/SplitNewlines.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/SplitNewlines.java index b87fd5e4de..9c6ceddb51 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/SplitNewlines.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/SplitNewlines.java @@ -44,7 +44,7 @@ public class SplitNewlines implements Function> { private final ReturnStringIf2xx returnStringIf200; @Inject - SplitNewlines(ReturnStringIf2xx returnStringIf200) { + protected SplitNewlines(ReturnStringIf2xx returnStringIf200) { this.returnStringIf200 = returnStringIf200; } diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/SplitNewlinesAndReturnSecondField.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/SplitNewlinesAndReturnSecondField.java new file mode 100644 index 0000000000..0d098fdaa9 --- /dev/null +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/functions/SplitNewlinesAndReturnSecondField.java @@ -0,0 +1,67 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.http.HttpResponse; +import org.jclouds.http.functions.ReturnStringIf2xx; + +import com.google.common.base.Function; +import com.google.common.base.Predicates; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class SplitNewlinesAndReturnSecondField extends SplitNewlines { + + @Inject + SplitNewlinesAndReturnSecondField(ReturnStringIf2xx returnStringIf200) { + super(returnStringIf200); + } + + @Override + public Set apply(HttpResponse response) { + return ImmutableSet.copyOf(Iterables.filter( + Iterables.transform(super.apply(response), new Function() { + + @Override + public String apply(String arg0) { + if (arg0 == null) + return null; + Iterable parts = Splitter.on(' ').split(arg0); + if (Iterables.size(parts) == 2) + return Iterables.get(parts, 1); + else if (Iterables.size(parts) == 1) + return Iterables.get(parts, 0); + return null; + } + + }), Predicates.notNull())); + } +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/handlers/CloudSigmaErrorHandler.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/handlers/CloudSigmaErrorHandler.java index 99c499a204..91f9636602 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/handlers/CloudSigmaErrorHandler.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/handlers/CloudSigmaErrorHandler.java @@ -64,6 +64,8 @@ public class CloudSigmaErrorHandler implements HttpErrorHandler { if ((command.getCurrentRequest().getEndpoint().getPath().endsWith("/info")) || (message != null && message.indexOf("could not be found") != -1)) exception = new ResourceNotFoundException(message, exception); + else if (message != null && message.indexOf("currently in use") != -1) + exception = new IllegalStateException(message, exception); else exception = new IllegalArgumentException(message, exception); break; diff --git a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/util/Servers.java b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/util/Servers.java index e452ee798c..9234aedbcf 100644 --- a/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/util/Servers.java +++ b/providers/cloudsigma-zrh/src/main/java/org/jclouds/cloudsigma/util/Servers.java @@ -45,10 +45,28 @@ public class Servers { * @return a builder for a persistent 1Ghz 512m server with DHCP enabled network. */ public static Server.Builder small(String name, String driveUuuid, String vncPassword) { + return smallWithStaticIP(name, driveUuuid, vncPassword, "auto"); + } + + /** + * Helper to create a small persistent server + * + * @param name + * what to name the server + * @param driveUuuid + * id of the boot drive + * @param vncPassword + * password for vnc + * @param ip + * static IP + * @return a builder for a persistent 1Ghz 512m server with DHCP enabled network. + */ + public static Server.Builder smallWithStaticIP(String name, String driveUuuid, String vncPassword, String ip) { return new Server.Builder().name(name).cpu(1000).mem(512).persistent(true) .devices(ImmutableMap.of("ide:0:0", new IDEDevice.Builder(0, 0).uuid(driveUuuid).build())) .bootDeviceIds(ImmutableSet.of("ide:0:0")) - .nics(ImmutableSet.of(new NIC.Builder().model(Model.E1000).dhcp("auto").build())) + .nics(ImmutableSet.of(new NIC.Builder().model(Model.E1000).dhcp(ip).build())) .vnc(new VNC(null, vncPassword, false)); } + } \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java index 8ea9198b57..6772a832d9 100644 --- a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java +++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/CloudSigmaAsyncClientTest.java @@ -33,9 +33,14 @@ import org.jclouds.cloudsigma.domain.Server; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToDriveInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToProfileInfo; import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToServerInfo; +import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToStaticIPInfo; +import org.jclouds.cloudsigma.functions.KeyValuesDelimitedByBlankLinesToVLANInfo; import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToDriveInfoSet; import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToServerInfoSet; +import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToStaticIPInfoSet; +import org.jclouds.cloudsigma.functions.ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet; import org.jclouds.cloudsigma.functions.SplitNewlines; +import org.jclouds.cloudsigma.functions.SplitNewlinesAndReturnSecondField; import org.jclouds.cloudsigma.options.CloneDriveOptions; import org.jclouds.http.HttpRequest; import org.jclouds.http.filters.BasicAuthentication; @@ -77,6 +82,7 @@ public class CloudSigmaAsyncClientTest extends RestClientTest servers = client.listServers(); - assertNotNull(servers); - } - @Test public void testGetProfileInfo() throws Exception { ProfileInfo profile = client.getProfileInfo(); assertNotNull(profile); } + @Test + public void testListVLANs() throws Exception { + Set vlans = client.listVLANs(); + assertNotNull(vlans); + } + + @Test + public void testListVLANInfo() throws Exception { + Set vlans = client.listVLANInfo(); + assertNotNull(vlans); + } + + @Test + public void testGetVLAN() throws Exception { + for (String vlanUUID : client.listVLANs()) { + assert !"".equals(vlanUUID); + assertNotNull(client.getVLANInfo(vlanUUID)); + } + } + + @Test + public void testListStaticIPs() throws Exception { + Set ips = client.listStaticIPs(); + assertNotNull(ips); + } + + @Test + public void testListStaticIPInfo() throws Exception { + Set ips = client.listStaticIPInfo(); + assertNotNull(ips); + } + + @Test + public void testGetStaticIP() throws Exception { + for (String ipUUID : client.listStaticIPs()) { + assert !"".equals(ipUUID); + assertNotNull(client.getStaticIPInfo(ipUUID)); + } + } + + @Test + public void testListServers() throws Exception { + Set servers = client.listServers(); + assertNotNull(servers); + } + @Test public void testListServerInfo() throws Exception { Set servers = client.listServerInfo(); @@ -223,6 +265,47 @@ public class CloudSigmaClientLiveTest { drive = drive2; } + @Test + public void testCreateAndDestroyVLAN() throws Exception { + VLANInfo vlan = client.createVLAN(prefix); + String id = vlan.getUuid(); + try { + vlan = client.getVLANInfo(vlan.getUuid()); + assertEquals(vlan.getName(), prefix); + + vlan = client.renameVLAN(vlan.getUuid(), prefix + "2"); + // test that rename didn't work :) + assertEquals(vlan.getName(), prefix); + vlan = client.getVLANInfo(vlan.getUuid()); + assertEquals(vlan.getName(), prefix); + } finally { + client.destroyVLAN(id); + } + } + + @Test + public void testCreateAndDestroyStaticIP() throws Exception { + StaticIPInfo ip = client.createStaticIP(); + String id = ip.getAddress(); + try { + ip = client.getStaticIPInfo(ip.getAddress()); + assertNotNull(ip); + Logger.getAnonymousLogger().info("preparing drive"); + prepareDrive(); + + Server serverRequest = Servers.smallWithStaticIP(prefix, drive.getUuid(), vncPassword, ip.getAddress()) + .build(); + + Logger.getAnonymousLogger().info("starting server"); + server = client.createServer(serverRequest); + assertEquals(server.getNics().get(0).getDhcp(), ip.getAddress()); + } finally { + client.destroyServer(server.getUuid()); + client.destroyDrive(drive.getUuid()); + client.destroyStaticIP(id); + } + } + protected ServerInfo server; @Test(dependsOnMethods = "testSetDriveData") diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderLiveTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderLiveTest.java index b380e5e03e..66982c9005 100644 --- a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderLiveTest.java +++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/compute/CloudSigmaTemplateBuilderLiveTest.java @@ -23,6 +23,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import java.io.IOException; +import java.util.Set; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; @@ -31,6 +32,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -46,20 +48,26 @@ public class CloudSigmaTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTe @Override protected Predicate defineUnsupportedOperatingSystems() { return new Predicate() { - @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || // - (input.family == OsFamily.UBUNTU && !(input.version.matches("10.10") && input.is64Bit)) || // - (input.family == OsFamily.WINDOWS && !((input.version.equals("2008 R2") && input.is64Bit) - || (input.version.equals("2008") && !input.is64Bit) || (input.version.equals("2003")))) // - ); + switch (input.family) { + case UBUNTU: + return !input.version.equals("") && !(input.version.equals("10.10") && input.is64Bit); + case CENTOS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("5.5") && input.is64Bit); + case WINDOWS: + return !((input.version.equals("2008 R2") && input.is64Bit) + || (input.version.equals("2008") && !input.is64Bit) || input.version.equals("") || (input.version + .equals("2003"))); + default: + return true; + } } }; } - + @Override public void testDefaultTemplateBuilder() throws IOException { Template defaultTemplate = context.getComputeService().templateBuilder().build(); @@ -68,4 +76,9 @@ public class CloudSigmaTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTe assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("CH-ZH"); + } } \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToVLANInfoTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToVLANInfoTest.java new file mode 100644 index 0000000000..6d7594928f --- /dev/null +++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/KeyValuesDelimitedByBlankLinesToVLANInfoTest.java @@ -0,0 +1,50 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.testng.annotations.Test; + +import com.google.inject.Guice; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class KeyValuesDelimitedByBlankLinesToVLANInfoTest { + + private static final KeyValuesDelimitedByBlankLinesToVLANInfo FN = Guice.createInjector().getInstance( + KeyValuesDelimitedByBlankLinesToVLANInfo.class); + + public void testNone() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), null); + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))), null); + assertEquals(FN.apply(new HttpResponse(200, "", null)), null); + } + + public void testOne() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToVLANInfoTest.class + .getResourceAsStream("/vlan.txt")))), MapToVLANInfoTest.ONE); + } +} diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSetTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSetTest.java new file mode 100644 index 0000000000..11bba3b8b4 --- /dev/null +++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSetTest.java @@ -0,0 +1,52 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.cloudsigma.domain.VLANInfo; +import org.jclouds.http.HttpResponse; +import org.jclouds.io.Payloads; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Guice; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSetTest { + + private static final ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet FN = Guice.createInjector().getInstance( + ListOfKeyValuesDelimitedByBlankLinesToVLANInfoSet.class); + + public void testNone() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload(""))), ImmutableSet. of()); + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newStringPayload("\n\n"))), ImmutableSet. of()); + assertEquals(FN.apply(new HttpResponse(200, "", null)), ImmutableSet. of()); + } + + public void testOne() { + assertEquals(FN.apply(new HttpResponse(200, "", Payloads.newInputStreamPayload(MapToVLANInfoTest.class + .getResourceAsStream("/vlan.txt")))), ImmutableSet. of(MapToVLANInfoTest.ONE)); + } +} \ No newline at end of file diff --git a/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/MapToVLANInfoTest.java b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/MapToVLANInfoTest.java new file mode 100644 index 0000000000..7c6f0ef2a1 --- /dev/null +++ b/providers/cloudsigma-zrh/src/test/java/org/jclouds/cloudsigma/functions/MapToVLANInfoTest.java @@ -0,0 +1,56 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudsigma.functions; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.util.Map; + +import org.jclouds.cloudsigma.domain.VLANInfo; +import org.jclouds.util.Strings2; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; + +/** + * + * @author Adrian Cole + */ +@Test(groups = { "unit" }) +public class MapToVLANInfoTest { + public static VLANInfo ONE = new VLANInfo.Builder()// + .uuid("6e2d1f6a-03c8-422b-bc8e-d744612cf46a")// + .name("My VLAN1").user("f2e19d5c-eaa1-44e5-94aa-dc194594bd7b").build(); + private static final MapToVLANInfo MAP_TO_VLAN = new MapToVLANInfo(); + + public void testEmptyMapReturnsNull() { + assertEquals(MAP_TO_VLAN.apply(ImmutableMap. of()), null); + } + + public void test() throws IOException { + + Map input = new ListOfKeyValuesDelimitedByBlankLinesToListOfMaps().apply( + Strings2.toStringAndClose(MapToVLANInfoTest.class.getResourceAsStream("/vlan.txt"))).get(0); + + assertEquals(MAP_TO_VLAN.apply(input), ONE); + + } +} diff --git a/providers/cloudsigma-zrh/src/test/resources/vlan.txt b/providers/cloudsigma-zrh/src/test/resources/vlan.txt new file mode 100644 index 0000000000..f98a1344fc --- /dev/null +++ b/providers/cloudsigma-zrh/src/test/resources/vlan.txt @@ -0,0 +1,4 @@ +resource 6e2d1f6a-03c8-422b-bc8e-d744612cf46a +type vlan +user f2e19d5c-eaa1-44e5-94aa-dc194594bd7b +name My VLAN1 \ No newline at end of file diff --git a/providers/elastichosts-lon-b/README.txt b/providers/elastichosts-lon-b/README.txt new file mode 100644 index 0000000000..f33fb31e21 --- /dev/null +++ b/providers/elastichosts-lon-b/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for ElasticHosts' Peer1 London ElasticStack (http://www.elastichosts.com/). +# +# Expects the jclouds elasticstack API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/elastichosts-lon-b/pom.xml b/providers/elastichosts-lon-b/pom.xml index 6bd4c3652c..997b1e6dea 100644 --- a/providers/elastichosts-lon-b/pom.xml +++ b/providers/elastichosts-lon-b/pom.xml @@ -80,6 +80,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/elastichosts-lon-b/src/main/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonPropertiesBuilder.java b/providers/elastichosts-lon-b/src/main/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonPropertiesBuilder.java index bbaf002b3c..f225c67050 100644 --- a/providers/elastichosts-lon-b/src/main/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonPropertiesBuilder.java +++ b/providers/elastichosts-lon-b/src/main/java/org/jclouds/elastichosts/ElasticHostsBlueSquareLondonPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.elastichosts; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -35,6 +36,7 @@ public class ElasticHostsBlueSquareLondonPropertiesBuilder extends ElasticStackP @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "GB-LND"); properties.setProperty(PROPERTY_ENDPOINT, "https://api.lon-p.elastichosts.com"); properties.setProperty(PROPERTY_API_VERSION, "1.0"); return properties; diff --git a/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonComputeServiceLiveTest.java b/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonComputeServiceLiveTest.java index 3b79d1ece1..c172de8288 100644 --- a/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonComputeServiceLiveTest.java +++ b/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonComputeServiceLiveTest.java @@ -31,7 +31,7 @@ public class ElasticHostsBlueSquareLondonComputeServiceLiveTest extends ElasticS public ElasticHostsBlueSquareLondonComputeServiceLiveTest() { provider = "elastichosts-lon-b"; - tag = "elastichosts"; + group = "elastichosts"; } } diff --git a/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonTemplateBuilderLiveTest.java b/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonTemplateBuilderLiveTest.java index 8f8424415e..41ce845c0d 100644 --- a/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonTemplateBuilderLiveTest.java +++ b/providers/elastichosts-lon-b/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsBlueSquareLondonTemplateBuilderLiveTest.java @@ -22,6 +22,8 @@ package org.jclouds.elastichosts.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; +import java.util.Set; + import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; @@ -29,6 +31,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -47,11 +50,19 @@ public class ElasticHostsBlueSquareLondonTemplateBuilderLiveTest extends BaseTem @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || // - (input.family == OsFamily.UBUNTU && !(input.version.equals("10.04") && input.is64Bit)) || // - (input.family == OsFamily.WINDOWS && !((input.version.equals("2008") || input.version.equals("2008 R2")) && input.is64Bit)) // - ); + switch (input.family) { + case UBUNTU: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("10.04") && input.is64Bit); + case CENTOS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("5.5") && input.is64Bit); + case WINDOWS: + return !(input.version.equals("") && input.is64Bit) + && !((input.version.equals("2008 R2") && input.is64Bit) || (input.version.equals("2008") && input.is64Bit)); + default: + return true; + } } }; @@ -67,4 +78,8 @@ public class ElasticHostsBlueSquareLondonTemplateBuilderLiveTest extends BaseTem assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("GB-LND"); + } } diff --git a/providers/elastichosts-lon-p/README.txt b/providers/elastichosts-lon-p/README.txt new file mode 100644 index 0000000000..8bfc0016ca --- /dev/null +++ b/providers/elastichosts-lon-p/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for ElasticHosts' BlueSquare London ElasticStack (http://www.elastichosts.com/). +# +# Expects the jclouds elasticstack API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/elastichosts-lon-p/pom.xml b/providers/elastichosts-lon-p/pom.xml index 68d4606e5f..309b3b5729 100644 --- a/providers/elastichosts-lon-p/pom.xml +++ b/providers/elastichosts-lon-p/pom.xml @@ -80,6 +80,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/elastichosts-lon-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonPropertiesBuilder.java b/providers/elastichosts-lon-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonPropertiesBuilder.java index ea501bd324..1d3a92ec97 100644 --- a/providers/elastichosts-lon-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonPropertiesBuilder.java +++ b/providers/elastichosts-lon-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1LondonPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.elastichosts; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -35,6 +36,7 @@ public class ElasticHostsPeer1LondonPropertiesBuilder extends ElasticStackProper @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "GB-LND"); properties.setProperty(PROPERTY_ENDPOINT, "https://api.lon-p.elastichosts.com"); properties.setProperty(PROPERTY_API_VERSION, "1.0"); return properties; diff --git a/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonComputeServiceLiveTest.java b/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonComputeServiceLiveTest.java index 86c9046e13..1333c2fec5 100644 --- a/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonComputeServiceLiveTest.java +++ b/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonComputeServiceLiveTest.java @@ -31,7 +31,7 @@ public class ElasticHostsPeer1LondonComputeServiceLiveTest extends ElasticStackC public ElasticHostsPeer1LondonComputeServiceLiveTest() { provider = "elastichosts-lon-p"; - tag = "elastichosts"; + group = "elastichosts"; } } diff --git a/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonTemplateBuilderLiveTest.java b/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonTemplateBuilderLiveTest.java index 7646f8b5c4..dfc8f57bcf 100644 --- a/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonTemplateBuilderLiveTest.java +++ b/providers/elastichosts-lon-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1LondonTemplateBuilderLiveTest.java @@ -22,6 +22,8 @@ package org.jclouds.elastichosts.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; +import java.util.Set; + import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; @@ -29,6 +31,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -47,11 +50,19 @@ public class ElasticHostsPeer1LondonTemplateBuilderLiveTest extends BaseTemplate @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || // - (input.family == OsFamily.UBUNTU && !(input.version.equals("10.04") && input.is64Bit)) || // - (input.family == OsFamily.WINDOWS && !((input.version.equals("2008") || input.version.equals("2008 R2")) && input.is64Bit)) // - ); + switch (input.family) { + case UBUNTU: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("10.04") && input.is64Bit); + case CENTOS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("5.5") && input.is64Bit); + case WINDOWS: + return !(input.version.equals("") && input.is64Bit) + && !((input.version.equals("2008 R2") && input.is64Bit) || (input.version.equals("2008") && input.is64Bit)); + default: + return true; + } } }; @@ -67,4 +78,8 @@ public class ElasticHostsPeer1LondonTemplateBuilderLiveTest extends BaseTemplate assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("GB-LND"); + } } diff --git a/providers/elastichosts-sat-p/README.txt b/providers/elastichosts-sat-p/README.txt new file mode 100644 index 0000000000..941dcb8b82 --- /dev/null +++ b/providers/elastichosts-sat-p/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for ElasticHosts' Peer1 San Antonio ElasticStack (http://www.elastichosts.com/). +# +# Expects the jclouds elasticstack API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/elastichosts-sat-p/pom.xml b/providers/elastichosts-sat-p/pom.xml index ebee552ba8..6c8d35b4a0 100644 --- a/providers/elastichosts-sat-p/pom.xml +++ b/providers/elastichosts-sat-p/pom.xml @@ -31,7 +31,7 @@ org.jclouds.provider elastichosts-sat-p - jclouds ElasticHosts Peer1 London provider + jclouds ElasticHosts Peer1 San Antonio provider ElasticHosts implementation targeted to Peer1 San Antonio @@ -80,6 +80,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/elastichosts-sat-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioPropertiesBuilder.java b/providers/elastichosts-sat-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioPropertiesBuilder.java index 13327f11ce..e4b9100ed1 100644 --- a/providers/elastichosts-sat-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioPropertiesBuilder.java +++ b/providers/elastichosts-sat-p/src/main/java/org/jclouds/elastichosts/ElasticHostsPeer1SanAntonioPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.elastichosts; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -35,6 +36,7 @@ public class ElasticHostsPeer1SanAntonioPropertiesBuilder extends ElasticStackPr @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-TX"); properties.setProperty(PROPERTY_ENDPOINT, "https://api.sat-p.elastichosts.com"); properties.setProperty(PROPERTY_API_VERSION, "1.0"); return properties; diff --git a/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioComputeServiceLiveTest.java b/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioComputeServiceLiveTest.java index f10af1172b..08f71a0f87 100644 --- a/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioComputeServiceLiveTest.java +++ b/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioComputeServiceLiveTest.java @@ -31,7 +31,7 @@ public class ElasticHostsPeer1SanAntonioComputeServiceLiveTest extends ElasticSt public ElasticHostsPeer1SanAntonioComputeServiceLiveTest() { provider = "elastichosts-sat-p"; - tag = "elastichosts"; + group = "elastichosts"; } } diff --git a/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioTemplateBuilderLiveTest.java b/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioTemplateBuilderLiveTest.java index ae43a8ab2f..c85c7d8f98 100644 --- a/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioTemplateBuilderLiveTest.java +++ b/providers/elastichosts-sat-p/src/test/java/org/jclouds/elastichosts/compute/ElasticHostsPeer1SanAntonioTemplateBuilderLiveTest.java @@ -22,6 +22,8 @@ package org.jclouds.elastichosts.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; +import java.util.Set; + import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; @@ -29,6 +31,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -47,11 +50,19 @@ public class ElasticHostsPeer1SanAntonioTemplateBuilderLiveTest extends BaseTemp @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || // - (input.family == OsFamily.UBUNTU && !(input.version.equals("10.04") && input.is64Bit)) || // - (input.family == OsFamily.WINDOWS && !((input.version.equals("2008") || input.version.equals("2008 R2")) && input.is64Bit)) // - ); + switch (input.family) { + case UBUNTU: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("10.04") && input.is64Bit); + case CENTOS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("5.5") && input.is64Bit); + case WINDOWS: + return !(input.version.equals("") && input.is64Bit) + && !((input.version.equals("2008 R2") && input.is64Bit) || (input.version.equals("2008") && input.is64Bit)); + default: + return true; + } } }; @@ -67,4 +78,8 @@ public class ElasticHostsPeer1SanAntonioTemplateBuilderLiveTest extends BaseTemp assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-TX"); + } } diff --git a/providers/eucalyptus-partnercloud-ec2/README.txt b/providers/eucalyptus-partnercloud-ec2/README.txt new file mode 100644 index 0000000000..ba64cee9e4 --- /dev/null +++ b/providers/eucalyptus-partnercloud-ec2/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Eucalyptus Partner Cloud's EC2 (http://www.eucalyptus.com/resources/AmazonAWS) service. +# +# Expects the jclouds ec2 API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/eucalyptus-partnercloud-ec2/pom.xml b/providers/eucalyptus-partnercloud-ec2/pom.xml index d1c9c17be8..370e13e167 100644 --- a/providers/eucalyptus-partnercloud-ec2/pom.xml +++ b/providers/eucalyptus-partnercloud-ec2/pom.xml @@ -39,6 +39,8 @@ 2010-06-15 FIXME_IDENTITY FIXME_CREDENTIAL + + kvm @@ -86,6 +88,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + org.jclouds.driver jclouds-log4j @@ -134,6 +142,10 @@ test.eucalyptus-partnercloud-ec2.credential ${test.eucalyptus-partnercloud-ec2.credential} + + test.eucalyptus-partnercloud-ec2.virtualization-type + ${test.eucalyptus-partnercloud-ec2.virtualization-type} + diff --git a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java index 558a44af07..813e12617f 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java +++ b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudPropertiesBuilder.java @@ -20,6 +20,10 @@ package org.jclouds.epc; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; +import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.util.Properties; @@ -31,9 +35,14 @@ import org.jclouds.eucalyptus.EucalyptusPropertiesBuilder; * @author Adrian Cole */ public class EucalyptusPartnerCloudPropertiesBuilder extends EucalyptusPropertiesBuilder { + @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_REGIONS, "Eucalyptus"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-CA"); + properties.setProperty(PROPERTY_REGION + ".Eucalyptus." + ISO3166_CODES, "US-CA"); + properties.setProperty("eucalyptus-partnercloud-ec2.virtualization-type", "kvm"); properties.setProperty(PROPERTY_ENDPOINT, "http://partnercloud.eucalyptus.com:8773/services/Eucalyptus"); return properties; } diff --git a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java index b98308ac77..e840573ffc 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java +++ b/providers/eucalyptus-partnercloud-ec2/src/main/java/org/jclouds/epc/config/EucalyptusPartnerCloudComputeServiceContextModule.java @@ -27,6 +27,8 @@ import org.jclouds.ec2.compute.strategy.ReviseParsedImage; import org.jclouds.epc.strategy.EucalyptusPartnerCloudReviseParsedImage; import com.google.inject.Injector; +import com.google.inject.Key; +import com.google.inject.name.Names; /** * @@ -36,7 +38,9 @@ public class EucalyptusPartnerCloudComputeServiceContextModule extends EC2Comput @Override protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { - return template.osFamily(CENTOS).locationId("xen-cluster").osDescriptionMatches("xen"); + String virt = injector.getInstance(Key.get(String.class, Names + .named("eucalyptus-partnercloud-ec2.virtualization-type"))); + return template.osFamily(CENTOS).locationId(virt + "-cluster").osDescriptionMatches(virt); } @Override diff --git a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java index ac2adc6b76..2d5b38ebaf 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java +++ b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest.java @@ -19,12 +19,9 @@ package org.jclouds.epc.compute; -import static org.jclouds.compute.util.ComputeServiceUtils.getCores; -import static org.testng.Assert.assertEquals; +import java.util.Properties; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest; +import org.jclouds.eucalyptus.compute.EucalyptusComputeServiceLiveTest; import org.testng.annotations.Test; /** @@ -32,32 +29,25 @@ import org.testng.annotations.Test; * @author Adrian Cole */ @Test(groups = "live", sequential = true, testName = "EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest") -public class EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest { +public class EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest extends EucalyptusComputeServiceLiveTest { public EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest() { provider = "eucalyptus-partnercloud-ec2"; // security groups must be <30 characters - tag = "eu"; + group = "eu"; } @Override - @Test(enabled = false) + protected Properties setupProperties() { + Properties overrides = super.setupProperties(); + if (System.getProperties().containsKey("test.eucalyptus-partnercloud-ec2.virtualization-type")) + overrides.setProperty("eucalyptus-partnercloud-ec2.virtualization-type", System + .getProperty("test.eucalyptus-partnercloud-ec2.virtualization-type")); + return overrides; + } + + // test hangs + @Override public void testExtendedOptionsAndLogin() throws Exception { - // euc does not support monitoring } - - @Override - @Test(enabled = false) - public void testExtendedOptionsNoKeyPair() throws Exception { - // euc does not support multiple security groups - } - - @Override - protected void assertDefaultWorks() { - Template defaultTemplate = client.templateBuilder().build(); - assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); - assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); - assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); - } - } diff --git a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java index 23bce83fd2..e4b42d70a0 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java +++ b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest.java @@ -23,6 +23,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import java.io.IOException; +import java.util.Set; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; @@ -31,6 +32,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -49,11 +51,16 @@ public class EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest extends Bas @Override public boolean apply(OsFamilyVersion64Bit input) { - return input.family == OsFamily.RHEL || // - (input.family == OsFamily.CENTOS && !input.version.equals("5.3") || !input.is64Bit) || // - (input.family == OsFamily.WINDOWS && !(input.version.equals("2008") && input.is64Bit)) || // - input.family == OsFamily.UBUNTU; - + switch (input.family) { + case CENTOS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("5.3") && input.is64Bit); + case WINDOWS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("2008") && input.is64Bit); + default: + return true; + } } }; @@ -68,9 +75,13 @@ public class EucalyptusPartnerCloudEucalyptusTemplateBuilderLiveTest extends Bas assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(defaultTemplate.getImage().getUserMetadata().get("rootDeviceType"), "instance-store"); - assertEquals(defaultTemplate.getLocation().getId(), "xen-cluster"); + assertEquals(defaultTemplate.getLocation().getId(), "kvm-cluster"); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-CA"); + } } diff --git a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java index 4c9af8ba85..1300dd44fd 100644 --- a/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java +++ b/providers/eucalyptus-partnercloud-ec2/src/test/java/org/jclouds/epc/compute/strategy/EucalyptusPartnerCloudReviseParsedImageTest.java @@ -31,8 +31,8 @@ import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.ec2.compute.functions.EC2ImageParser; import org.jclouds.ec2.compute.strategy.EC2PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.ec2.domain.Image; @@ -86,7 +86,8 @@ public class EucalyptusPartnerCloudReviseParsedImageTest { .build()); } - static Location defaultLocation = new LocationImpl(LocationScope.REGION, "us-east-1", "us-east-1", null); + static Location defaultLocation = new LocationBuilder().scope(LocationScope.REGION).id("us-east-1").description( + "us-east-1").build(); public static Set convertImages(String resource) { @@ -97,7 +98,7 @@ public class EucalyptusPartnerCloudReviseParsedImageTest { Set result = DescribeImagesResponseHandlerTest.parseImages(resource); EC2ImageParser parser = new EC2ImageParser(new EC2PopulateDefaultLoginCredentialsForImageStrategy(), map, Suppliers.> ofInstance(ImmutableSet. of(defaultLocation)), Suppliers - .ofInstance(defaultLocation), "ec2", new EucalyptusPartnerCloudReviseParsedImage(map)); + .ofInstance(defaultLocation), new EucalyptusPartnerCloudReviseParsedImage(map)); return Sets.newLinkedHashSet(Iterables.filter(Iterables.transform(result, parser), Predicates.notNull())); } diff --git a/providers/eucalyptus-partnercloud-s3/README.txt b/providers/eucalyptus-partnercloud-s3/README.txt new file mode 100644 index 0000000000..8aa505c37d --- /dev/null +++ b/providers/eucalyptus-partnercloud-s3/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Eucalyptus Partner Cloud's Walrus (http://www.eucalyptus.com/resources/AmazonAWS) service. +# +# Expects the jclouds walrus API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/eucalyptus-partnercloud-s3/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudWalrusPropertiesBuilder.java b/providers/eucalyptus-partnercloud-s3/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudWalrusPropertiesBuilder.java index e1dfd9c441..cbcc160853 100644 --- a/providers/eucalyptus-partnercloud-s3/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudWalrusPropertiesBuilder.java +++ b/providers/eucalyptus-partnercloud-s3/src/main/java/org/jclouds/epc/EucalyptusPartnerCloudWalrusPropertiesBuilder.java @@ -20,6 +20,7 @@ package org.jclouds.epc; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -34,6 +35,7 @@ public class EucalyptusPartnerCloudWalrusPropertiesBuilder extends WalrusPropert @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-CA"); properties.setProperty(PROPERTY_ENDPOINT, "http://partnercloud.eucalyptus.com:8773/services/Walrus"); return properties; } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest.java index a4720f50fd..51547cd440 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest.java @@ -19,25 +19,13 @@ package org.jclouds.epc.blobstore; -import java.io.IOException; -import java.util.concurrent.ExecutionException; - -import org.jclouds.blobstore.integration.internal.BaseBlobIntegrationTest; +import org.jclouds.walrus.blobstore.WalrusBlobIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest") -public class EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest extends BaseBlobIntegrationTest { - public EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest() { - containerCount = 5; - } - - @Override - @Test(expectedExceptions = IllegalArgumentException.class) - public void testPutObjectStream() throws InterruptedException, IOException, ExecutionException { - super.testPutObjectStream(); - } +public class EucalyptusPartnerCloudWalrusBlobIntegrationLiveTest extends WalrusBlobIntegrationLiveTest { } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobLiveTest.java index 3cc03d39b3..8fb7328b54 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobLiveTest.java @@ -19,15 +19,13 @@ package org.jclouds.epc.blobstore; -import org.jclouds.blobstore.integration.internal.BaseBlobLiveTest; +import org.jclouds.walrus.blobstore.WalrusBlobLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusBlobLiveTest") -public class EucalyptusPartnerCloudWalrusBlobLiveTest extends BaseBlobLiveTest { - public EucalyptusPartnerCloudWalrusBlobLiveTest() { - containerCount = 5; - } +public class EucalyptusPartnerCloudWalrusBlobLiveTest extends WalrusBlobLiveTest { + } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest.java index 7740ca934b..7a1e6eb25b 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest.java @@ -19,15 +19,12 @@ package org.jclouds.epc.blobstore; -import org.jclouds.blobstore.integration.internal.BaseBlobMapIntegrationTest; +import org.jclouds.walrus.blobstore.WalrusBlobMapIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest") -public class EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest extends BaseBlobMapIntegrationTest { - public EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest() { - containerCount = 5; - } +public class EucalyptusPartnerCloudWalrusBlobMapIntegrationLiveTest extends WalrusBlobMapIntegrationLiveTest { } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobSignerLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobSignerLiveTest.java index 390dc18611..1f79a93061 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobSignerLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusBlobSignerLiveTest.java @@ -19,7 +19,7 @@ package org.jclouds.epc.blobstore; -import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest; +import org.jclouds.walrus.blobstore.WalrusBlobSignerLiveTest; import org.testng.annotations.Test; /** @@ -27,8 +27,6 @@ import org.testng.annotations.Test; * @author Adrian Cole */ @Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusBlobSignerLiveTest") -public class EucalyptusPartnerCloudWalrusBlobSignerLiveTest extends BaseBlobSignerLiveTest { - public EucalyptusPartnerCloudWalrusBlobSignerLiveTest() { - containerCount = 5; - } +public class EucalyptusPartnerCloudWalrusBlobSignerLiveTest extends WalrusBlobSignerLiveTest { + } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest.java index 8945d3b6dd..cc1ff07d57 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest.java @@ -19,15 +19,13 @@ package org.jclouds.epc.blobstore; -import org.jclouds.blobstore.integration.internal.BaseContainerIntegrationTest; +import org.jclouds.walrus.blobstore.WalrusContainerIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest") -public class EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest extends BaseContainerIntegrationTest { - public EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest() { - containerCount = 5; - } +public class EucalyptusPartnerCloudWalrusContainerIntegrationLiveTest extends WalrusContainerIntegrationLiveTest { + } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerLiveTest.java index ef4794091b..41f7ee6a7b 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusContainerLiveTest.java @@ -19,15 +19,13 @@ package org.jclouds.epc.blobstore; -import org.jclouds.blobstore.integration.internal.BaseContainerLiveTest; +import org.jclouds.walrus.blobstore.WalrusContainerLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusContainerLiveTest") -public class EucalyptusPartnerCloudWalrusContainerLiveTest extends BaseContainerLiveTest { - public EucalyptusPartnerCloudWalrusContainerLiveTest() { - containerCount = 5; - } +public class EucalyptusPartnerCloudWalrusContainerLiveTest extends WalrusContainerLiveTest { + } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest.java index 356a37f635..32b9e9a44c 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest.java @@ -19,15 +19,13 @@ package org.jclouds.epc.blobstore; -import org.jclouds.blobstore.integration.internal.BaseInputStreamMapIntegrationTest; +import org.jclouds.walrus.blobstore.WalrusInputStreamMapIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ @Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest") -public class EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest extends BaseInputStreamMapIntegrationTest { - public EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest() { - containerCount = 5; - } +public class EucalyptusPartnerCloudWalrusInputStreamMapIntegrationLiveTest extends WalrusInputStreamMapIntegrationLiveTest { + } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest.java index f744789c74..a216e13544 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest.java @@ -19,15 +19,21 @@ package org.jclouds.epc.blobstore; -import org.jclouds.blobstore.integration.internal.BaseServiceIntegrationTest; +import java.util.Set; + +import org.jclouds.walrus.blobstore.WalrusServiceIntegrationLiveTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ -@Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest") -public class EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest extends BaseServiceIntegrationTest { - public EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest() { - containerCount = 5; +@Test(groups = "live", testName = "EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest") +public class EucalyptusPartnerCloudWalrusServiceIntegrationLiveTest extends WalrusServiceIntegrationLiveTest { + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-CA"); } + } diff --git a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusTestInitializer.java b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusTestInitializer.java index c980b81344..757a57d623 100644 --- a/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusTestInitializer.java +++ b/providers/eucalyptus-partnercloud-s3/src/test/java/org/jclouds/epc/blobstore/EucalyptusPartnerCloudWalrusTestInitializer.java @@ -19,33 +19,18 @@ package org.jclouds.epc.blobstore; -import java.io.IOException; +import org.jclouds.walrus.blobstore.WalrusTestInitializer; -import org.jclouds.blobstore.BlobStoreContext; -import org.jclouds.blobstore.BlobStoreContextFactory; -import org.jclouds.blobstore.integration.TransientBlobStoreTestInitializer; -import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest; -import org.jclouds.logging.log4j.config.Log4JLoggingModule; - -import com.google.common.collect.ImmutableSet; -import com.google.inject.Module; /** * * @author Adrian Cole */ -public class EucalyptusPartnerCloudWalrusTestInitializer extends TransientBlobStoreTestInitializer { +public class EucalyptusPartnerCloudWalrusTestInitializer extends WalrusTestInitializer { public EucalyptusPartnerCloudWalrusTestInitializer() { provider = "eucalyptus-partnercloud-s3"; - BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true; } - @Override - protected BlobStoreContext createLiveContext(Module configurationModule, String endpoint, String apiversion, - String app, String identity, String credential) throws IOException { - return new BlobStoreContextFactory().createContext(provider, ImmutableSet.of(configurationModule, - new Log4JLoggingModule()), setupProperties(endpoint, apiversion, identity, credential)); - } } diff --git a/providers/gogrid/README.txt b/providers/gogrid/README.txt new file mode 100644 index 0000000000..7a8fec71e1 --- /dev/null +++ b/providers/gogrid/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for GoGrid (http://www.gogrid.com/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/gogrid/pom.xml b/providers/gogrid/pom.xml index ab6d58ca27..6fb9ca1587 100644 --- a/providers/gogrid/pom.xml +++ b/providers/gogrid/pom.xml @@ -53,6 +53,12 @@ jclouds-jsch ${project.version} + + com.jcraft + jsch + 0.1.44 + test + org.jclouds jclouds-compute @@ -70,7 +76,7 @@ log4j log4j - 1.2.14 + 1.2.16 test diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/GoGridPropertiesBuilder.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/GoGridPropertiesBuilder.java index 02ef3cff94..90abfa1e3c 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/GoGridPropertiesBuilder.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/GoGridPropertiesBuilder.java @@ -21,7 +21,11 @@ package org.jclouds.gogrid; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.gogrid.reference.GoGridConstants.PROPERTY_GOGRID_DEFAULT_DC; +import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONE; +import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONES; import java.util.Properties; @@ -38,6 +42,10 @@ public class GoGridPropertiesBuilder extends PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ZONES, "1,2"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-CA,US-VA"); + properties.setProperty(PROPERTY_ZONE + ".1." + ISO3166_CODES, "US-CA"); + properties.setProperty(PROPERTY_ZONE + ".2." + ISO3166_CODES, "US-VA"); properties.setProperty(PROPERTY_API_VERSION, GoGridAsyncClient.VERSION); properties.setProperty(PROPERTY_ENDPOINT, "https://api.gogrid.com/api"); properties.setProperty(PROPERTY_GOGRID_DEFAULT_DC, "1"); diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/config/GoGridBindComputeStrategiesByClass.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/config/GoGridBindComputeStrategiesByClass.java index e850f1ec5d..84b91685af 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/config/GoGridBindComputeStrategiesByClass.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/config/GoGridBindComputeStrategiesByClass.java @@ -20,14 +20,14 @@ package org.jclouds.gogrid.compute.config; import org.jclouds.compute.config.BindComputeStrategiesByClass; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.gogrid.compute.strategy.GoGridAddNodeWithTagStrategy; +import org.jclouds.gogrid.compute.strategy.FindPublicIpThenCreateNodeInGroup; import org.jclouds.gogrid.compute.strategy.GoGridDestroyNodeStrategy; import org.jclouds.gogrid.compute.strategy.GoGridGetNodeMetadataStrategy; import org.jclouds.gogrid.compute.strategy.GoGridLifeCycleStrategy; @@ -40,8 +40,8 @@ import org.jclouds.gogrid.compute.strategy.GoGridListNodesStrategy; */ public class GoGridBindComputeStrategiesByClass extends BindComputeStrategiesByClass { @Override - protected Class defineAddNodeWithTagStrategy() { - return GoGridAddNodeWithTagStrategy.class; + protected Class defineAddNodeWithTagStrategy() { + return FindPublicIpThenCreateNodeInGroup.class; } @Override diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java index 28670853c2..37c3a584b7 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/functions/ServerToNodeMetadata.java @@ -20,7 +20,7 @@ package org.jclouds.gogrid.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import java.util.Map; import java.util.NoSuchElementException; @@ -109,7 +109,7 @@ public class ServerToNodeMetadata implements Function { builder.ids(from.getId() + ""); builder.name(from.getName()); builder.location(locations.get().get(from.getDatacenter().getId() + "")); - builder.tag(parseTagFromName(from.getName())); + builder.group(parseGroupFromName(from.getName())); builder.hardware(parseHardware(from)); builder.imageId(from.getImage().getId() + ""); diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/GoGridAddNodeWithTagStrategy.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/FindPublicIpThenCreateNodeInGroup.java similarity index 93% rename from providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/GoGridAddNodeWithTagStrategy.java rename to providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/FindPublicIpThenCreateNodeInGroup.java index 221791acdd..a2a8788fb5 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/GoGridAddNodeWithTagStrategy.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/FindPublicIpThenCreateNodeInGroup.java @@ -31,7 +31,7 @@ import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Template; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.gogrid.GoGridClient; import org.jclouds.gogrid.domain.Ip; import org.jclouds.gogrid.domain.IpType; @@ -49,7 +49,7 @@ import com.google.common.collect.Iterables; * @author Oleksiy Yarmula */ @Singleton -public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy { +public class FindPublicIpThenCreateNodeInGroup implements CreateNodeWithGroupEncodedIntoName { private final GoGridClient client; private final Function sizeToRam; private final Function serverToNodeMetadata; @@ -57,7 +57,7 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy { private RetryablePredicate serverLatestJobCompletedShort; @Inject - protected GoGridAddNodeWithTagStrategy(GoGridClient client, + protected FindPublicIpThenCreateNodeInGroup(GoGridClient client, Function serverToNodeMetadata, Function sizeToRam, Timeouts timeouts) { this.client = client; @@ -71,7 +71,7 @@ public class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy { } @Override - public NodeMetadata addNodeWithTag(String tag, String name, Template template) { + public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { Server addedServer = null; boolean notStarted = true; int numOfRetries = 20; diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/suppliers/GoGridLocationSupplier.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/suppliers/GoGridLocationSupplier.java index 3aadcc038a..01e1ea92d9 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/suppliers/GoGridLocationSupplier.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/suppliers/GoGridLocationSupplier.java @@ -19,52 +19,61 @@ package org.jclouds.gogrid.compute.suppliers; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; +import java.util.Map; import java.util.Set; -import javax.annotation.Resource; import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; -import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.gogrid.GoGridClient; import org.jclouds.gogrid.domain.Option; +import org.jclouds.location.Iso3166; import org.jclouds.location.Provider; -import org.jclouds.logging.Logger; +import org.jclouds.location.suppliers.JustProvider; -import com.google.common.base.Supplier; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableSet.Builder; /** * * @author Adrian Cole */ @Singleton -public class GoGridLocationSupplier implements Supplier> { +public class GoGridLocationSupplier extends JustProvider { - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - private final String providerName; private final GoGridClient sync; + private final Map> isoCodesById; @Inject - GoGridLocationSupplier(@Provider String providerName, GoGridClient sync) { - this.providerName = providerName; - this.sync = sync; + GoGridLocationSupplier(@Iso3166 Set isoCodes, @Provider String providerName, @Provider URI endpoint, + GoGridClient sync, @Iso3166 Map> isoCodesById) { + super(isoCodes, providerName, endpoint); + this.sync = checkNotNull(sync, "sync"); + this.isoCodesById = checkNotNull(isoCodesById, "isoCodesById"); } @Override public Set get() { - final Set locations = Sets.newHashSet(); - logger.debug(">> providing locations"); - Location parent = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); - for (Option dc : sync.getServerServices().getDatacenters()) - locations.add(new LocationImpl(LocationScope.ZONE, dc.getId() + "", dc.getDescription(), parent)); - logger.debug("<< locations(%d)", locations.size()); - return locations; + Builder locations = ImmutableSet.builder(); + Set + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/openhosting-east1/src/main/java/org/jclouds/openhosting/OpenHostingEast1PropertiesBuilder.java b/providers/openhosting-east1/src/main/java/org/jclouds/openhosting/OpenHostingEast1PropertiesBuilder.java index a405313d4b..2a4498e5ff 100644 --- a/providers/openhosting-east1/src/main/java/org/jclouds/openhosting/OpenHostingEast1PropertiesBuilder.java +++ b/providers/openhosting-east1/src/main/java/org/jclouds/openhosting/OpenHostingEast1PropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.openhosting; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -35,6 +36,7 @@ public class OpenHostingEast1PropertiesBuilder extends ElasticStackPropertiesBui @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-VA"); properties.setProperty(PROPERTY_ENDPOINT, "https://api.east1.openhosting.com"); properties.setProperty(PROPERTY_API_VERSION, "1.0"); return properties; diff --git a/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1ComputeServiceLiveTest.java b/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1ComputeServiceLiveTest.java index 194eb058d2..9c3454acb0 100644 --- a/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1ComputeServiceLiveTest.java +++ b/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1ComputeServiceLiveTest.java @@ -31,7 +31,7 @@ public class OpenHostingEast1ComputeServiceLiveTest extends ElasticStackComputeS public OpenHostingEast1ComputeServiceLiveTest() { provider = "openhosting-east1"; - tag = "openhosting"; + group = "openhosting"; } } diff --git a/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1TemplateBuilderLiveTest.java b/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1TemplateBuilderLiveTest.java index 99d1075fb4..8c4fe33b93 100644 --- a/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1TemplateBuilderLiveTest.java +++ b/providers/openhosting-east1/src/test/java/org/jclouds/openhosting/compute/OpenHostingEast1TemplateBuilderLiveTest.java @@ -23,6 +23,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import java.io.IOException; +import java.util.Set; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; @@ -31,6 +32,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -49,11 +51,16 @@ public class OpenHostingEast1TemplateBuilderLiveTest extends BaseTemplateBuilder @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || // - (input.family == OsFamily.UBUNTU && !(input.version.equals("10.10") && input.is64Bit)) || // - (input.family == OsFamily.WINDOWS) // - ); + switch (input.family) { + case UBUNTU: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("10.10") && input.is64Bit); + case CENTOS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("5.5") && input.is64Bit); + default: + return true; + } } }; @@ -69,4 +76,8 @@ public class OpenHostingEast1TemplateBuilderLiveTest extends BaseTemplateBuilder assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-VA"); + } } diff --git a/providers/pom.xml b/providers/pom.xml index 9c0e54660b..1a3c32e337 100644 --- a/providers/pom.xml +++ b/providers/pom.xml @@ -37,10 +37,10 @@ slicehost cloudsigma-zrh azureblob - aws-elb aws-s3 aws-ec2 googlestorage + scaleup-storage synaptic-storage cloudonestorage eucalyptus-partnercloud-s3 diff --git a/providers/scaleup-storage/README.txt b/providers/scaleup-storage/README.txt new file mode 100644 index 0000000000..15668aabbd --- /dev/null +++ b/providers/scaleup-storage/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for ScaleUp's Secure Cloud Storage (http://www.scaleupstorage.com/). +# +# Expects the jclouds s3 API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/sandbox-providers/scaleup-storage/pom.xml b/providers/scaleup-storage/pom.xml similarity index 100% rename from sandbox-providers/scaleup-storage/pom.xml rename to providers/scaleup-storage/pom.xml diff --git a/sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStorageContextBuilder.java b/providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStorageContextBuilder.java similarity index 100% rename from sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStorageContextBuilder.java rename to providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStorageContextBuilder.java diff --git a/sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStoragePropertiesBuilder.java b/providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStoragePropertiesBuilder.java similarity index 92% rename from sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStoragePropertiesBuilder.java rename to providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStoragePropertiesBuilder.java index ebfdd1ec37..c78018ab3a 100644 --- a/sandbox-providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStoragePropertiesBuilder.java +++ b/providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/ScaleUpStoragePropertiesBuilder.java @@ -20,6 +20,7 @@ package org.jclouds.scaleup.storage; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -34,6 +35,7 @@ public class ScaleUpStoragePropertiesBuilder extends S3PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "DE"); properties.setProperty(PROPERTY_ENDPOINT, "https://scs.scaleupstorage.com"); return properties; } diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageClientLiveTest.java b/providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/blobstore/config/ScaleUpStorageBlobStoreContextModule.java similarity index 72% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageClientLiveTest.java rename to providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/blobstore/config/ScaleUpStorageBlobStoreContextModule.java index 12e755b6d7..047389ce1f 100644 --- a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageClientLiveTest.java +++ b/providers/scaleup-storage/src/main/java/org/jclouds/scaleup/storage/blobstore/config/ScaleUpStorageBlobStoreContextModule.java @@ -17,17 +17,14 @@ * ==================================================================== */ -package org.jclouds.scaleup.storage; +package org.jclouds.scaleup.storage.blobstore.config; -import org.jclouds.s3.S3ClientLiveTest; -import org.testng.annotations.Test; +import org.jclouds.s3.blobstore.config.S3BlobStoreContextModule; /** - * Tests behavior of {@code S3Client} * * @author Adrian Cole */ -@Test(groups = "live", sequential = true, testName = "ScaleUpStorageClientLiveTest") -public class ScaleUpStorageClientLiveTest extends S3ClientLiveTest { - +public class ScaleUpStorageBlobStoreContextModule extends S3BlobStoreContextModule { + } diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageAsyncClientTestDisabled.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageAsyncClientTestDisabled.java similarity index 100% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageAsyncClientTestDisabled.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageAsyncClientTestDisabled.java diff --git a/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageClientLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageClientLiveTest.java new file mode 100644 index 0000000000..bffe0998e4 --- /dev/null +++ b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/ScaleUpStorageClientLiveTest.java @@ -0,0 +1,47 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.scaleup.storage; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.s3.S3ClientLiveTest; +import org.jclouds.s3.domain.S3Object; +import org.testng.annotations.Test; + +/** + * Tests behavior of {@code S3Client} + * + * @author Adrian Cole + */ +@Test(groups = "live", sequential = true, testName = "ScaleUpStorageClientLiveTest") +public class ScaleUpStorageClientLiveTest extends S3ClientLiveTest { + // no support for content encoding + @Override + protected void assertContentEncoding(S3Object newObject, String string) { + assert (newObject.getPayload().getContentMetadata().getContentEncoding().indexOf(string) != -1); + assert (newObject.getMetadata().getContentMetadata().getContentEncoding().indexOf(string) != -1); + } + + // no support for cache control + @Override + protected void assertCacheControl(S3Object newObject, String string) { + assertEquals(newObject.getMetadata().getCacheControl(), null); + } +} diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobIntegrationLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobIntegrationLiveTest.java similarity index 54% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobIntegrationLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobIntegrationLiveTest.java index cde468de91..e5bb994c81 100644 --- a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobIntegrationLiveTest.java +++ b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobIntegrationLiveTest.java @@ -19,13 +19,40 @@ package org.jclouds.scaleup.storage.blobstore; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.blobstore.domain.Blob; +import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.s3.blobstore.integration.S3BlobIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ -@Test(groups = "live", testName = "ScaleUpStorageBlobIntegrationLiveTest") +@Test(groups = "live", testName = "ScaleUpStorageBlobIntegrationLiveTest") public class ScaleUpStorageBlobIntegrationLiveTest extends S3BlobIntegrationLiveTest { + + // no support for content language + @Override + protected void checkContentLanguage(Blob blob, String contentLanguage) { + assert blob.getPayload().getContentMetadata().getContentLanguage() == null; + assert blob.getMetadata().getContentMetadata().getContentLanguage() == null; + } + + // double range not supported + @Test(groups = { "integration", "live" }) + @Override + public void testGetTwoRanges() throws InterruptedException, IOException { + + } + + // no md5 + @Override + protected void checkMD5(BlobMetadata metadata) throws IOException { + assertEquals(metadata.getContentMetadata().getContentMD5(), null); + } + } diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobLiveTest.java similarity index 75% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobLiveTest.java index dc10ea6d9e..d81102518b 100644 --- a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobLiveTest.java +++ b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobLiveTest.java @@ -19,13 +19,20 @@ package org.jclouds.scaleup.storage.blobstore; +import static org.testng.Assert.assertEquals; + import org.jclouds.s3.blobstore.integration.S3BlobLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ -@Test(groups = "live", testName = "ScaleUpStorageBlobLiveTest") +@Test(groups = "live", testName = "ScaleUpStorageBlobLiveTest") public class ScaleUpStorageBlobLiveTest extends S3BlobLiveTest { + // no md5 + @Override + protected void checkMD5(String container, String name, byte[] md5) { + assertEquals(context.getBlobStore().blobMetadata(container, name).getContentMetadata().getContentMD5(), null); + } } diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobMapIntegrationLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobMapIntegrationLiveTest.java similarity index 100% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobMapIntegrationLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobMapIntegrationLiveTest.java diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobSignerLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobSignerLiveTest.java similarity index 100% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobSignerLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageBlobSignerLiveTest.java diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerIntegrationLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerIntegrationLiveTest.java similarity index 73% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerIntegrationLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerIntegrationLiveTest.java index 593e9e101a..55ff4ada70 100644 --- a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerIntegrationLiveTest.java +++ b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerIntegrationLiveTest.java @@ -19,13 +19,22 @@ package org.jclouds.scaleup.storage.blobstore; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.blobstore.domain.BlobMetadata; import org.jclouds.s3.blobstore.integration.S3ContainerIntegrationLiveTest; import org.testng.annotations.Test; /** * @author Adrian Cole */ -@Test(groups = "live", testName = "ScaleUpStorageContainerIntegrationLiveTest") +@Test(groups = "live", testName = "ScaleUpStorageContainerIntegrationLiveTest") public class ScaleUpStorageContainerIntegrationLiveTest extends S3ContainerIntegrationLiveTest { - + // doesn't support MD5 + @Override + protected void checkMD5(BlobMetadata metadata) throws IOException { + assertEquals(metadata.getContentMetadata().getContentMD5(), null); + } } diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerLiveTest.java similarity index 100% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageContainerLiveTest.java diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageInputStreamMapIntegrationLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageInputStreamMapIntegrationLiveTest.java similarity index 100% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageInputStreamMapIntegrationLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageInputStreamMapIntegrationLiveTest.java diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageServiceIntegrationLiveTest.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageServiceIntegrationLiveTest.java similarity index 80% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageServiceIntegrationLiveTest.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageServiceIntegrationLiveTest.java index 3297d574a8..33cd9a5175 100644 --- a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageServiceIntegrationLiveTest.java +++ b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageServiceIntegrationLiveTest.java @@ -19,13 +19,20 @@ package org.jclouds.scaleup.storage.blobstore; +import java.util.Set; + import org.jclouds.s3.blobstore.integration.S3ServiceIntegrationLiveTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ -@Test(groups = "live", testName = "ScaleUpStorageServiceIntegrationLiveTest") +@Test(groups = "live", testName = "ScaleUpStorageServiceIntegrationLiveTest") public class ScaleUpStorageServiceIntegrationLiveTest extends S3ServiceIntegrationLiveTest { - + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("DE"); + } } diff --git a/sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageTestInitializer.java b/providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageTestInitializer.java similarity index 100% rename from sandbox-providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageTestInitializer.java rename to providers/scaleup-storage/src/test/java/org/jclouds/scaleup/storage/blobstore/ScaleUpStorageTestInitializer.java diff --git a/providers/serverlove-z1-man/README.txt b/providers/serverlove-z1-man/README.txt new file mode 100644 index 0000000000..04eac7e90e --- /dev/null +++ b/providers/serverlove-z1-man/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for serverlove's ElasticStack (http://www.serverlove.com/). +# +# Expects the jclouds elasticstack API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/serverlove-z1-man/pom.xml b/providers/serverlove-z1-man/pom.xml index 5af1f8e8a6..a64f96a7d9 100644 --- a/providers/serverlove-z1-man/pom.xml +++ b/providers/serverlove-z1-man/pom.xml @@ -80,6 +80,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterComputeServiceLiveTest.java b/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterComputeServiceLiveTest.java index b25780226e..f3376ae49b 100644 --- a/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterComputeServiceLiveTest.java +++ b/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterComputeServiceLiveTest.java @@ -31,7 +31,7 @@ public class ServerloveManchesterComputeServiceLiveTest extends ElasticStackComp public ServerloveManchesterComputeServiceLiveTest() { provider = "serverlove-z1-man"; - tag = "serverlove"; + group = "serverlove"; } } diff --git a/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterTemplateBuilderLiveTest.java b/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterTemplateBuilderLiveTest.java index adc78a24c9..039143c896 100644 --- a/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterTemplateBuilderLiveTest.java +++ b/providers/serverlove-z1-man/src/test/java/org/jclouds/serverlove/compute/ServerloveManchesterTemplateBuilderLiveTest.java @@ -22,6 +22,8 @@ package org.jclouds.serverlove.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; +import java.util.Set; + import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; @@ -29,6 +31,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -47,11 +50,19 @@ public class ServerloveManchesterTemplateBuilderLiveTest extends BaseTemplateBui @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !(input.version.equals("5.5") && input.is64Bit)) || // - (input.family == OsFamily.UBUNTU && !(input.version.equals("10.04") && input.is64Bit)) || // - (input.family == OsFamily.WINDOWS && !(input.version.equals("2008 R2") && input.is64Bit)) // - ); + switch (input.family) { + case UBUNTU: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("10.04") && input.is64Bit); + case CENTOS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("5.5") && input.is64Bit); + case WINDOWS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("2008 R2") && input.is64Bit); + default: + return true; + } } }; @@ -67,4 +78,8 @@ public class ServerloveManchesterTemplateBuilderLiveTest extends BaseTemplateBui assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("GB-MAN"); + } } diff --git a/providers/skalicloud-sdg-my/README.txt b/providers/skalicloud-sdg-my/README.txt new file mode 100644 index 0000000000..79b3d29a9b --- /dev/null +++ b/providers/skalicloud-sdg-my/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for SKALI Cloud's ElasticStack (http://www.skalicloud.com/). +# +# Expects the jclouds elasticstack API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/skalicloud-sdg-my/pom.xml b/providers/skalicloud-sdg-my/pom.xml index 1899e176fd..5087644035 100644 --- a/providers/skalicloud-sdg-my/pom.xml +++ b/providers/skalicloud-sdg-my/pom.xml @@ -80,6 +80,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/skalicloud-sdg-my/src/main/java/org/jclouds/skalicloud/SkaliCloudMalaysiaPropertiesBuilder.java b/providers/skalicloud-sdg-my/src/main/java/org/jclouds/skalicloud/SkaliCloudMalaysiaPropertiesBuilder.java index a60dbfc1a3..abeca614ba 100644 --- a/providers/skalicloud-sdg-my/src/main/java/org/jclouds/skalicloud/SkaliCloudMalaysiaPropertiesBuilder.java +++ b/providers/skalicloud-sdg-my/src/main/java/org/jclouds/skalicloud/SkaliCloudMalaysiaPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.skalicloud; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -35,6 +36,7 @@ public class SkaliCloudMalaysiaPropertiesBuilder extends ElasticStackPropertiesB @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "MY-10"); properties.setProperty(PROPERTY_ENDPOINT, "https://api.sdg-my.skalicloud.com"); properties.setProperty(PROPERTY_API_VERSION, "1.0"); return properties; diff --git a/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/compute/SkaliCloudMalaysiaTemplateBuilderLiveTest.java b/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/compute/SkaliCloudMalaysiaTemplateBuilderLiveTest.java index 92d2713c98..f347c4d877 100644 --- a/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/compute/SkaliCloudMalaysiaTemplateBuilderLiveTest.java +++ b/providers/skalicloud-sdg-my/src/test/java/org/jclouds/skalicloud/compute/SkaliCloudMalaysiaTemplateBuilderLiveTest.java @@ -23,6 +23,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import java.io.IOException; +import java.util.Set; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; @@ -31,6 +32,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -49,11 +51,17 @@ public class SkaliCloudMalaysiaTemplateBuilderLiveTest extends BaseTemplateBuild @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !input.version.equals("5.5")) || // - (input.family == OsFamily.UBUNTU && !input.version.equals("10.10")) || // - (input.family == OsFamily.WINDOWS && !(input.version.equals("2008 R2") && input.is64Bit)) // - ); + switch (input.family) { + case UBUNTU: + return !input.version.equals("") && !input.version.equals("10.10"); + case CENTOS: + return !input.version.equals("") && !input.version.equals("5.5"); + case WINDOWS: + return !(input.version.equals("") && input.is64Bit) + && !(input.version.equals("2008 R2") && input.is64Bit); + default: + return true; + } } }; @@ -69,4 +77,8 @@ public class SkaliCloudMalaysiaTemplateBuilderLiveTest extends BaseTemplateBuild assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("MY-10"); + } } diff --git a/providers/slicehost/README.txt b/providers/slicehost/README.txt new file mode 100644 index 0000000000..a9d0737a29 --- /dev/null +++ b/providers/slicehost/README.txt @@ -0,0 +1,25 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Slicehost (http://www.slicehost.com/). +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/slicehost/pom.xml b/providers/slicehost/pom.xml index 294146bc99..9a4f69e9a7 100644 --- a/providers/slicehost/pom.xml +++ b/providers/slicehost/pom.xml @@ -62,7 +62,7 @@ log4j log4j - 1.2.14 + 1.2.16 test @@ -77,6 +77,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostAsyncClient.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostAsyncClient.java index 3b55c853ae..e9c71a5fa0 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostAsyncClient.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostAsyncClient.java @@ -32,7 +32,7 @@ import javax.ws.rs.QueryParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.annotations.XMLResponseParser; @@ -118,8 +118,8 @@ public interface SlicehostAsyncClient { @Path("/slices.xml") @MapBinder(BindCreateSliceToXmlPayload.class) @XMLResponseParser(SliceHandler.class) - ListenableFuture createSlice(@MapPayloadParam("name") String name, @MapPayloadParam("image_id") int imageId, - @MapPayloadParam("flavor_id") int flavorId); + ListenableFuture createSlice(@PayloadParam("name") String name, @PayloadParam("image_id") int imageId, + @PayloadParam("flavor_id") int flavorId); /** * @see SlicehostClient#rebuildSliceFromImage diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostPropertiesBuilder.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostPropertiesBuilder.java index 3fac1dcdca..f4c8842269 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostPropertiesBuilder.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/SlicehostPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.slicehost; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -35,6 +36,7 @@ public class SlicehostPropertiesBuilder extends PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-IL,US-TX,US-MO"); properties.setProperty(PROPERTY_ENDPOINT, "https://api.slicehost.com"); properties.setProperty(PROPERTY_API_VERSION, "1.4.1.1"); properties.setProperty("jclouds.ssh.max_retries", "8"); diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeStrategiesByClass.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeStrategiesByClass.java index 0e203eb781..91dd79dc81 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeStrategiesByClass.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeStrategiesByClass.java @@ -20,14 +20,14 @@ package org.jclouds.slicehost.compute.config; import org.jclouds.compute.config.BindComputeStrategiesByClass; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.slicehost.compute.strategy.SlicehostAddNodeWithTagStrategy; +import org.jclouds.slicehost.compute.strategy.SlicehostCreateNodeWithGroupEncodedIntoName; import org.jclouds.slicehost.compute.strategy.SlicehostDestroyNodeStrategy; import org.jclouds.slicehost.compute.strategy.SlicehostGetNodeMetadataStrategy; import org.jclouds.slicehost.compute.strategy.SlicehostListNodesStrategy; @@ -41,8 +41,8 @@ import org.jclouds.slicehost.compute.strategy.SlicehostLifeCycleStrategy; public class SlicehostBindComputeStrategiesByClass extends BindComputeStrategiesByClass { @Override - protected Class defineAddNodeWithTagStrategy() { - return SlicehostAddNodeWithTagStrategy.class; + protected Class defineAddNodeWithTagStrategy() { + return SlicehostCreateNodeWithGroupEncodedIntoName.class; } @Override diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeSuppliersByClass.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeSuppliersByClass.java index c5ff3e2ef4..3b18dcfc66 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeSuppliersByClass.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostBindComputeSuppliersByClass.java @@ -24,6 +24,8 @@ import java.util.Set; import org.jclouds.compute.config.BindComputeSuppliersByClass; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; +import org.jclouds.domain.Location; +import org.jclouds.location.suppliers.JustProvider; import org.jclouds.slicehost.compute.suppliers.SlicehostHardwareSupplier; import org.jclouds.slicehost.compute.suppliers.SlicehostImageSupplier; @@ -45,4 +47,9 @@ public class SlicehostBindComputeSuppliersByClass extends BindComputeSuppliersBy protected Class>> defineImageSupplier() { return SlicehostImageSupplier.class; } + + @Override + protected Class>> defineLocationSupplier() { + return JustProvider.class; + } } \ No newline at end of file diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostComputeServiceContextModule.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostComputeServiceContextModule.java index ab19328d0c..10a871b2e6 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostComputeServiceContextModule.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/config/SlicehostComputeServiceContextModule.java @@ -21,21 +21,11 @@ package org.jclouds.slicehost.compute.config; import static org.jclouds.compute.domain.OsFamily.UBUNTU; -import java.util.Set; - -import javax.inject.Singleton; - import org.jclouds.compute.config.BaseComputeServiceContextModule; import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.internal.BaseComputeService; -import org.jclouds.domain.Location; -import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; -import org.jclouds.location.Provider; -import com.google.common.collect.ImmutableSet; import com.google.inject.Injector; -import com.google.inject.Provides; /** * Configures the {@link SlicehostComputeServiceContext}; requires {@link BaseComputeService} bound. @@ -48,18 +38,6 @@ public class SlicehostComputeServiceContextModule extends BaseComputeServiceCont return template.osFamily(UBUNTU).osVersionMatches("10.04").osDescriptionMatches("^((?!MGC).)*$").os64Bit(true); } - @Provides - @Singleton - Location getLocation(@Provider String providerName) { - Location provider = new LocationImpl(LocationScope.PROVIDER, providerName, providerName, null); - return new LocationImpl(LocationScope.ZONE, "DFW1", "Dallas, TX", provider); - } - - @Provides - @Singleton - Set provideLocations(Location location) { - return ImmutableSet.of(location); - } @Override protected void configure() { diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadata.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadata.java index ed602dc4e6..eed42aa14b 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadata.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadata.java @@ -20,7 +20,7 @@ package org.jclouds.slicehost.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; -import static org.jclouds.compute.util.ComputeServiceUtils.parseTagFromName; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; import java.util.Map; import java.util.NoSuchElementException; @@ -104,7 +104,7 @@ public class SliceToNodeMetadata implements Function { builder.ids(from.getId() + ""); builder.name(from.getName()); builder.location(location.get()); - builder.tag(parseTagFromName(from.getName())); + builder.group(parseGroupFromName(from.getName())); builder.imageId(from.getImageId() + ""); builder.operatingSystem(parseOperatingSystem(from)); builder.hardware(parseHardware(from)); diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostAddNodeWithTagStrategy.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostCreateNodeWithGroupEncodedIntoName.java similarity index 83% rename from providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostAddNodeWithTagStrategy.java rename to providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostCreateNodeWithGroupEncodedIntoName.java index 4c3e94f0c6..5151f819b6 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostAddNodeWithTagStrategy.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostCreateNodeWithGroupEncodedIntoName.java @@ -28,7 +28,7 @@ import javax.inject.Singleton; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.Template; -import org.jclouds.compute.strategy.AddNodeWithTagStrategy; +import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.domain.Credentials; import org.jclouds.slicehost.SlicehostClient; import org.jclouds.slicehost.domain.Slice; @@ -40,13 +40,13 @@ import com.google.common.base.Function; * @author Adrian Cole */ @Singleton -public class SlicehostAddNodeWithTagStrategy implements AddNodeWithTagStrategy { +public class SlicehostCreateNodeWithGroupEncodedIntoName implements CreateNodeWithGroupEncodedIntoName { protected final SlicehostClient client; protected final Map credentialStore; protected final Function sliceToNodeMetadata; @Inject - protected SlicehostAddNodeWithTagStrategy(SlicehostClient client, Map credentialStore, + protected SlicehostCreateNodeWithGroupEncodedIntoName(SlicehostClient client, Map credentialStore, Function sliceToNodeMetadata) { this.client = checkNotNull(client, "client"); this.credentialStore = checkNotNull(credentialStore, "credentialStore"); @@ -54,7 +54,7 @@ public class SlicehostAddNodeWithTagStrategy implements AddNodeWithTagStrategy { } @Override - public NodeMetadata addNodeWithTag(String tag, String name, Template template) { + public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { Slice from = client.createSlice(name, Integer.parseInt(template.getImage().getProviderId()), Integer.parseInt(template.getHardware().getProviderId())); credentialStore.put("node#" + from.getId(), new Credentials("root", from.getRootPassword())); diff --git a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/SlicehostTemplateBuilderLiveTest.java b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/SlicehostTemplateBuilderLiveTest.java index 5e348c75c2..c1bff655c4 100644 --- a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/SlicehostTemplateBuilderLiveTest.java +++ b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/SlicehostTemplateBuilderLiveTest.java @@ -23,6 +23,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import java.io.IOException; +import java.util.Set; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; @@ -31,6 +32,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -49,11 +51,23 @@ public class SlicehostTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes @Override public boolean apply(OsFamilyVersion64Bit input) { - return (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.is64Bit && input.version.equals("2008 R2"))// - && !(!input.is64Bit && input.version.equals("2008 SP2")))); + switch (input.family) { + case UBUNTU: + return !input.version.equals("") && !(input.version.equals("10.04") || input.version.endsWith(".10")); + case RHEL: + return !(input.version.equals("") && input.is64Bit); + case CENTOS: + return !input.version.equals("") && input.version.matches("5.[23]") + || (input.version.equals("5.0") && !input.is64Bit); + case WINDOWS: + return !input.version.equals("") + && input.version.startsWith("2008") + && !(input.version.startsWith("2008 R2") && input.is64Bit || input.version + .startsWith("2008 SP2") + && !input.is64Bit) || input.version.indexOf("2003") != -1; + default: + return true; + } } }; @@ -67,4 +81,9 @@ public class SlicehostTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTes assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); assertEquals(getCores(defaultTemplate.getHardware()), 0.25d); } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-IL", "US-TX", "US-MO"); + } } \ No newline at end of file diff --git a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/FlavorToHardwareTest.java b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/FlavorToHardwareTest.java index 7e64ae0f2d..df6d8f8cc7 100644 --- a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/FlavorToHardwareTest.java +++ b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/FlavorToHardwareTest.java @@ -29,8 +29,8 @@ import org.jclouds.compute.domain.Processor; import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.VolumeBuilder; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.slicehost.domain.Flavor; import org.jclouds.slicehost.xml.FlavorHandlerTest; import org.testng.annotations.Test; @@ -42,7 +42,7 @@ import com.google.common.collect.ImmutableList; */ @Test(groups = "unit") public class FlavorToHardwareTest { - Location provider = new LocationImpl(LocationScope.ZONE, "dallas", "description", null); + Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build(); @Test public void test() throws UnknownHostException { diff --git a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadataTest.java b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadataTest.java index 845f42eb30..553973a7ff 100644 --- a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadataTest.java +++ b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SliceToNodeMetadataTest.java @@ -38,8 +38,8 @@ import org.jclouds.compute.domain.Volume; import org.jclouds.compute.domain.VolumeBuilder; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.slicehost.compute.config.SlicehostComputeServiceDependenciesModule; import org.jclouds.slicehost.domain.Slice; import org.jclouds.slicehost.xml.SliceHandlerTest; @@ -55,7 +55,7 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit") public class SliceToNodeMetadataTest { - Location provider = new LocationImpl(LocationScope.ZONE, "dallas", "description", null); + Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build(); @Test public void testApplyWhereImageAndHardwareNotFoundButCredentialsFound() throws UnknownHostException { @@ -72,7 +72,7 @@ public class SliceToNodeMetadataTest { NodeMetadata metadata = parser.apply(slice); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).tag("jclouds") + ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).group("jclouds") .imageId("2").id("1").providerId("1").name("jclouds-foo").location(provider).credentials(creds) .userMetadata(ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); } @@ -91,7 +91,7 @@ public class SliceToNodeMetadataTest { NodeMetadata metadata = parser.apply(slice); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).tag("jclouds") + ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).group("jclouds") .imageId("2").id("1").providerId("1").name("jclouds-foo").location(provider).userMetadata( ImmutableMap.of("Server Label", "Web Head 1", "Image Version", "2.1")).build()); } @@ -110,7 +110,7 @@ public class SliceToNodeMetadataTest { NodeMetadata metadata = parser.apply(slice); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).tag("jclouds") + ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).group("jclouds") .imageId("2").operatingSystem( new OperatingSystemBuilder().family(OsFamily.CENTOS).description("CentOS 5.2").version("5.2") .is64Bit(true).build()).id("1").providerId("1").name("jclouds-foo").location(provider) @@ -130,7 +130,7 @@ public class SliceToNodeMetadataTest { NodeMetadata metadata = parser.apply(slice); assertEquals(metadata, new NodeMetadataBuilder().state(NodeState.PENDING).publicAddresses( - ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).tag("jclouds") + ImmutableSet.of("174.143.212.229")).privateAddresses(ImmutableSet.of("10.176.164.199")).group("jclouds") .imageId("2").hardware( new HardwareBuilder().ids("1").name("256 slice").processors( ImmutableList.of(new Processor(0.25, 1.0))).ram(256).volumes( diff --git a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SlicehostImageToImageTest.java b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SlicehostImageToImageTest.java index 49d9f0f77d..fddefcc0bb 100644 --- a/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SlicehostImageToImageTest.java +++ b/providers/slicehost/src/test/java/org/jclouds/slicehost/compute/functions/SlicehostImageToImageTest.java @@ -31,8 +31,8 @@ import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.domain.Credentials; import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; -import org.jclouds.domain.internal.LocationImpl; import org.jclouds.json.Json; import org.jclouds.json.config.GsonModule; import org.jclouds.slicehost.xml.ImageHandlerTest; @@ -45,31 +45,24 @@ import com.google.inject.Guice; */ @Test(groups = "unit") public class SlicehostImageToImageTest { - Location provider = new LocationImpl(LocationScope.ZONE, "dallas", "description", null); + Location provider = new LocationBuilder().scope(LocationScope.ZONE).id("dallas").description("description").build(); @Test public void test() throws UnknownHostException { - assertEquals( - convertImage(), - new ImageBuilder() - .name("CentOS 5.2") - .operatingSystem( - new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.2").description("CentOS 5.2") - .is64Bit(true).build()).description("CentOS 5.2") - .defaultCredentials(new Credentials("root", null)).ids("2").build()); + assertEquals(convertImage(), new ImageBuilder().name("CentOS 5.2").operatingSystem( + new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.2").description("CentOS 5.2").is64Bit( + true).build()).description("CentOS 5.2").defaultCredentials(new Credentials("root", null)).ids( + "2").build()); } @Test public void test32() throws UnknownHostException { - assertEquals( - convertImage("/test_get_image32.xml"), - new ImageBuilder() - .name("Ubuntu 10.10 (maverick) 32-bit") - .operatingSystem( - new OperatingSystemBuilder().family(OsFamily.UBUNTU).version("10.10") - .description("Ubuntu 10.10 (maverick) 32-bit").build()) - .description("Ubuntu 10.10 (maverick) 32-bit").defaultCredentials(new Credentials("root", null)) - .ids("70").build()); + assertEquals(convertImage("/test_get_image32.xml"), new ImageBuilder().name("Ubuntu 10.10 (maverick) 32-bit") + .operatingSystem( + new OperatingSystemBuilder().family(OsFamily.UBUNTU).version("10.10").description( + "Ubuntu 10.10 (maverick) 32-bit").build()).description( + "Ubuntu 10.10 (maverick) 32-bit").defaultCredentials(new Credentials("root", null)).ids("70") + .build()); } public static Image convertImage() { @@ -80,9 +73,9 @@ public class SlicehostImageToImageTest { org.jclouds.slicehost.domain.Image image = ImageHandlerTest.parseImage(resource); SlicehostImageToImage parser = new SlicehostImageToImage(new SlicehostImageToOperatingSystem( - new BaseComputeServiceContextModule() { - }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule()) - .getInstance(Json.class)))); + new BaseComputeServiceContextModule() { + }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice + .createInjector(new GsonModule()).getInstance(Json.class)))); return parser.apply(image); } diff --git a/providers/synaptic-storage/README.txt b/providers/synaptic-storage/README.txt new file mode 100644 index 0000000000..621bff3a68 --- /dev/null +++ b/providers/synaptic-storage/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for AT&T's Synaptic Storage as a Service (https://www.synaptic.att.com/staas/). +# +# Expects the jclouds atmos API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# TODO: Usage example. \ No newline at end of file diff --git a/providers/synaptic-storage/src/main/java/org/jclouds/synaptic/storage/SynapticStoragePropertiesBuilder.java b/providers/synaptic-storage/src/main/java/org/jclouds/synaptic/storage/SynapticStoragePropertiesBuilder.java index 797676c0e8..092c65938e 100644 --- a/providers/synaptic-storage/src/main/java/org/jclouds/synaptic/storage/SynapticStoragePropertiesBuilder.java +++ b/providers/synaptic-storage/src/main/java/org/jclouds/synaptic/storage/SynapticStoragePropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.synaptic.storage; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import java.util.Properties; @@ -37,6 +38,7 @@ public class SynapticStoragePropertiesBuilder extends PropertiesBuilder { protected Properties defaultProperties() { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_ENDPOINT, "https://storage.synaptic.att.com"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-VA,US-TX"); properties.setProperty(PROPERTY_API_VERSION, "1.3.0"); return properties; } diff --git a/providers/synaptic-storage/src/test/java/org/jclouds/synaptic/storage/blobstore/integration/SynapticStorageServiceIntegrationLiveTest.java b/providers/synaptic-storage/src/test/java/org/jclouds/synaptic/storage/blobstore/integration/SynapticStorageServiceIntegrationLiveTest.java index 35ac34415b..a6b72e2fa0 100644 --- a/providers/synaptic-storage/src/test/java/org/jclouds/synaptic/storage/blobstore/integration/SynapticStorageServiceIntegrationLiveTest.java +++ b/providers/synaptic-storage/src/test/java/org/jclouds/synaptic/storage/blobstore/integration/SynapticStorageServiceIntegrationLiveTest.java @@ -19,13 +19,20 @@ package org.jclouds.synaptic.storage.blobstore.integration; +import java.util.Set; + import org.jclouds.atmos.blobstore.integration.AtmosServiceIntegrationLiveTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableSet; + /** * @author Adrian Cole */ -@Test(groups = "live", testName = "SynapticStorageServiceIntegrationLiveTest") +@Test(groups = "live", testName = "SynapticStorageServiceIntegrationLiveTest") public class SynapticStorageServiceIntegrationLiveTest extends AtmosServiceIntegrationLiveTest { - + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-VA", "US-TX"); + } } diff --git a/providers/trmk-ecloud/README.txt b/providers/trmk-ecloud/README.txt index 350d911547..22b3ad8c7f 100644 --- a/providers/trmk-ecloud/README.txt +++ b/providers/trmk-ecloud/README.txt @@ -18,8 +18,10 @@ ==== # -# The jclouds provider for Terremark's vCloud Express (http://vcloudexpress.terremark.com/) platform. +# The jclouds provider for Terremark's Enterprise Cloud (http://www.terremark.com/services/cloudcomputing/theenterprisecloud.aspx) platform. +# +# Expects the jclouds vcloudexpress API to be present on your application's classpath. # # TODO: Implementation status. # TODO: Supported features. -# See http://code.google.com/p/jclouds/wiki/QuickStartTerremark for example usage. \ No newline at end of file +# See http://code.google.com/p/jclouds/wiki/QuickStartTerremarkECloud for example usage. \ No newline at end of file diff --git a/providers/trmk-ecloud/pom.xml b/providers/trmk-ecloud/pom.xml index eef065ac0d..c62513f404 100644 --- a/providers/trmk-ecloud/pom.xml +++ b/providers/trmk-ecloud/pom.xml @@ -36,7 +36,7 @@ https://services.enterprisecloud.terremark.com/api - 0.8b-ext2.6 + 0.8b-ext2.7 FIXME FIXME @@ -94,6 +94,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClient.java b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClient.java index d0fb756a07..da4e29bed0 100644 --- a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClient.java +++ b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClient.java @@ -40,7 +40,7 @@ import javax.ws.rs.Produces; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; @@ -112,8 +112,8 @@ public interface TerremarkECloudAsyncClient extends TerremarkVCloudAsyncClient { @MapBinder(AddInternetServiceOptions.class) @Override ListenableFuture addInternetServiceToExistingIp(@EndpointParam URI existingIpId, - @MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol, - @MapPayloadParam("port") int port, AddInternetServiceOptions... options); + @PayloadParam("name") String serviceName, @PayloadParam("protocol") Protocol protocol, + @PayloadParam("port") int port, AddInternetServiceOptions... options); /** * @see TerremarkVCloudExpressClient#getInternetServicesOnPublicIP @@ -174,8 +174,8 @@ public interface TerremarkECloudAsyncClient extends TerremarkVCloudAsyncClient { @XMLResponseParser(KeyPairHandler.class) @MapBinder(BindCreateKeyToXmlPayload.class) ListenableFuture generateKeyPairInOrg( - @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, @MapPayloadParam("name") String name, - @MapPayloadParam("isDefault") boolean makeDefault); + @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, @PayloadParam("name") String name, + @PayloadParam("isDefault") boolean makeDefault); /** * @see TerremarkECloudClient#getKeyPair diff --git a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudClient.java b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudClient.java index a317c1921a..f8e1bf97f1 100644 --- a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudClient.java +++ b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudClient.java @@ -44,6 +44,8 @@ public interface TerremarkECloudClient extends TerremarkVCloudClient { * * @param vDCId * @return + * @throws org.jclouds.rest.InsufficientResourcesException + * if there's no additional ips available */ PublicIpAddress activatePublicIpInVDC(URI vDCId); diff --git a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudPropertiesBuilder.java b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudPropertiesBuilder.java index a6fc4a6514..5c4b2e308b 100644 --- a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudPropertiesBuilder.java +++ b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.vcloud.terremark; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.vcloud.reference.VCloudConstants.PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED; import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_NAME; import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_VERSION; @@ -36,10 +37,11 @@ public class TerremarkECloudPropertiesBuilder extends TerremarkVCloudPropertiesB @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_API_VERSION, "0.8b-ext2.6"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-FL,NL-NH"); + properties.setProperty(PROPERTY_API_VERSION, "0.8b-ext2.7"); properties.setProperty(PROPERTY_ENDPOINT, "https://services.enterprisecloud.terremark.com/api"); properties.setProperty(PROPERTY_TERREMARK_EXTENSION_NAME, "eCloudExtensions"); - properties.setProperty(PROPERTY_TERREMARK_EXTENSION_VERSION, "2.6"); + properties.setProperty(PROPERTY_TERREMARK_EXTENSION_VERSION, "2.7"); // for some reason the centos template is very slow to deploy properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED, 720l * 1000l + ""); return properties; diff --git a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkECloudComputeServiceContextModule.java b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkECloudComputeServiceContextModule.java index b3386085aa..25c5138557 100644 --- a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkECloudComputeServiceContextModule.java +++ b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/compute/config/TerremarkECloudComputeServiceContextModule.java @@ -22,6 +22,8 @@ package org.jclouds.vcloud.terremark.compute.config; import static org.jclouds.compute.domain.OsFamily.CENTOS; import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.vcloud.compute.functions.ParseOsFromVAppTemplateName; +import org.jclouds.vcloud.terremark.compute.functions.TerremarkECloudParseOsFromVAppTemplateName; import org.jclouds.vcloud.terremark.suppliers.InternetServiceAndPublicIpAddressSupplier; import org.jclouds.vcloud.terremark.suppliers.TerremarkECloudInternetServiceAndPublicIpAddressSupplier; @@ -32,6 +34,14 @@ import com.google.inject.Injector; */ public class TerremarkECloudComputeServiceContextModule extends TerremarkVCloudComputeServiceContextModule { + @Override + protected void configure() { + bind(InternetServiceAndPublicIpAddressSupplier.class).to( + TerremarkECloudInternetServiceAndPublicIpAddressSupplier.class); + bind(ParseOsFromVAppTemplateName.class).to(TerremarkECloudParseOsFromVAppTemplateName.class); + super.configure(); + } + // as of 6-nov-2010 only centos has ssh key injection in the images. // ssh key injection in ubuntu is targeted for dec-2010 or sooner @Override @@ -39,10 +49,4 @@ public class TerremarkECloudComputeServiceContextModule extends TerremarkVCloudC return template.osFamily(CENTOS).os64Bit(true); } - @Override - protected void configure() { - bind(InternetServiceAndPublicIpAddressSupplier.class).to( - TerremarkECloudInternetServiceAndPublicIpAddressSupplier.class); - super.configure(); - } } diff --git a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/compute/functions/TerremarkECloudParseOsFromVAppTemplateName.java b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/compute/functions/TerremarkECloudParseOsFromVAppTemplateName.java new file mode 100644 index 0000000000..06cf7cf131 --- /dev/null +++ b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/compute/functions/TerremarkECloudParseOsFromVAppTemplateName.java @@ -0,0 +1,73 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.terremark.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.compute.util.ComputeServiceUtils.parseOsFamilyOrUnrecognized; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.OperatingSystemBuilder; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.util.ComputeServiceUtils; +import org.jclouds.vcloud.compute.functions.ParseOsFromVAppTemplateName; + +/** + * @author Adrian Cole + */ +@Singleton +public class TerremarkECloudParseOsFromVAppTemplateName extends ParseOsFromVAppTemplateName { + // CentOS 5 (x64) + public static final Pattern OS_PATTERN = Pattern.compile("^-?([^ ]*) ([0-9.]+)( R[1-9])? ?.*"); + + @Inject + protected TerremarkECloudParseOsFromVAppTemplateName(Map> osVersionMap) { + super(osVersionMap); + } + + @Override + public OperatingSystem apply(String from) { + checkNotNull(from, "vapp template name"); + OperatingSystemBuilder builder = new OperatingSystemBuilder(); + builder.description(from); + if (from.equals("-Windows 2003 Std. R2 SQL 2005 Std. (x64)")) + System.out.print(';'); + builder.is64Bit(from.indexOf("64") != -1); + from = from.replace("Red Hat Enterprise Linux", "RHEL").replace("Sun Solaris", "SOLARIS").replace( + " Server", "").replace("Std. ", ""); + Matcher matcher = OS_PATTERN.matcher(from); + if (matcher.find()) { + OsFamily osFamily = parseOsFamilyOrUnrecognized(matcher.group(1)); + builder.family(osFamily); + String version = (matcher.group(3) != null) ? matcher.group(2) + matcher.group(3) : matcher.group(2); + builder.version(ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, version, osVersionMap)); + } else { + OsFamily osFamily = parseOsFamilyOrUnrecognized(from); + builder.family(osFamily); + } + return builder.build(); + } +} \ No newline at end of file diff --git a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/suppliers/TerremarkECloudInternetServiceAndPublicIpAddressSupplier.java b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/suppliers/TerremarkECloudInternetServiceAndPublicIpAddressSupplier.java index 7154b57445..d19d6c6cd5 100644 --- a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/suppliers/TerremarkECloudInternetServiceAndPublicIpAddressSupplier.java +++ b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/suppliers/TerremarkECloudInternetServiceAndPublicIpAddressSupplier.java @@ -31,14 +31,13 @@ import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.http.HttpResponseException; import org.jclouds.logging.Logger; +import org.jclouds.rest.InsufficientResourcesException; import org.jclouds.vcloud.domain.VCloudExpressVApp; import org.jclouds.vcloud.terremark.TerremarkECloudClient; import org.jclouds.vcloud.terremark.domain.InternetService; import org.jclouds.vcloud.terremark.domain.Protocol; import org.jclouds.vcloud.terremark.domain.PublicIpAddress; -import org.jclouds.vcloud.terremark.suppliers.InternetServiceAndPublicIpAddressSupplier; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -64,28 +63,22 @@ public class TerremarkECloudInternetServiceAndPublicIpAddressSupplier implements public Entry getNewInternetServiceAndIp(VCloudExpressVApp vApp, int port, Protocol protocol) { logger.debug(">> creating InternetService in vDC %s:%s:%d", vApp.getVDC().getName(), protocol, port); - // http://support.theenterprisecloud.com/kb/default.asp?id=706&Lang=1&SID= - // response with a 500 error code means we should look for an existing public ip to - // use InternetService is = null; PublicIpAddress ip = null; try { ip = client.activatePublicIpInVDC(vApp.getVDC().getHref()); - } catch (HttpResponseException e) { - if (e.getResponse().getStatusCode() == 500) { - logger.warn(">> no more ip addresses available, looking for one to re-use"); - for (PublicIpAddress existingIp : client.getPublicIpsAssociatedWithVDC(vApp.getVDC().getHref())) { - Set services = client.getInternetServicesOnPublicIp(existingIp.getId()); - if (services.size() == 0) { - ip = existingIp; - break; - } + } catch (InsufficientResourcesException e) { + logger.warn(">> no more ip addresses available, looking for one to re-use"); + for (PublicIpAddress existingIp : client.getPublicIpsAssociatedWithVDC(vApp.getVDC().getHref())) { + Set services = client.getInternetServicesOnPublicIp(existingIp.getId()); + if (services.size() == 0) { + ip = existingIp; + break; } - if (ip == null) - throw e; - } else { - throw e; } + if (ip == null) + throw e; + } is = client.addInternetServiceToExistingIp(ip.getId(), vApp.getName() + "-" + port, protocol, port, withDescription(String.format("port %d access to serverId: %s name: %s", port, vApp.getName(), vApp diff --git a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClientTest.java b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClientTest.java index 09784f608b..72ced2e021 100644 --- a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClientTest.java +++ b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudAsyncClientTest.java @@ -285,7 +285,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTestnametrueeggs", + "nametrueeggs", "application/vnd.tmrk.vCloud.nodeService+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, NodeHandler.class); @@ -399,7 +399,7 @@ public class TerremarkECloudAsyncClientTest extends RestClientTestnametrue", + "nametrue", "application/vnd.tmrk.vCloud.nodeService+xml", false); assertResponseParserClassEquals(method, request, ParseSax.class); assertSaxResponseParserClassEquals(method, NodeHandler.class); diff --git a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudClientLiveTestDisabled.java b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudClientLiveTestDisabled.java index 97c4051ec6..948926ad93 100644 --- a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudClientLiveTestDisabled.java +++ b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudClientLiveTestDisabled.java @@ -21,34 +21,32 @@ package org.jclouds.vcloud.terremark; import static org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions.Builder.processorCount; -import java.net.URI; -import java.util.Map; import java.util.Map.Entry; import org.jclouds.domain.Credentials; import org.jclouds.net.IPSocket; import org.jclouds.ssh.SshClient; +import org.jclouds.vcloud.domain.VCloudExpressVApp; import org.jclouds.vcloud.terremark.domain.InternetService; import org.jclouds.vcloud.terremark.domain.Protocol; import org.jclouds.vcloud.terremark.domain.PublicIpAddress; import org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions; +import org.jclouds.vcloud.terremark.suppliers.TerremarkECloudInternetServiceAndPublicIpAddressSupplier; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; - /** * Tests behavior of {@code TerremarkVCloudClient} * * @author Adrian Cole */ -@Test(groups = "live", enabled = false, sequential = true) +@Test(groups = "live", enabled = true, sequential = true) public class TerremarkECloudClientLiveTestDisabled extends TerremarkClientLiveTest { @BeforeClass void setProvider() { this.provider = "trmk-ecloud"; this.itemName = "Ubuntu 8.04 LTS (x86)"; + expectedOs = "Ubuntu Linux (32-bit)"; } @Override @@ -62,13 +60,9 @@ public class TerremarkECloudClientLiveTestDisabled extends TerremarkClientLiveTe } @Override - protected Entry getNewInternetServiceAndIpForSSH(URI vdc) { - PublicIpAddress ip = TerremarkECloudClient.class.cast(tmClient).activatePublicIpInVDC( - tmClient.findVDCInOrgNamed(null, null).getHref()); - InternetService is = tmClient.addInternetServiceToExistingIp(ip.getId(), "SSH", Protocol.TCP, 22); - Map result = ImmutableMap. of(is, ip); - Entry entry = Iterables.getOnlyElement(result.entrySet()); - return entry; + protected Entry getNewInternetServiceAndIpForSSH(VCloudExpressVApp vApp) { + return new TerremarkECloudInternetServiceAndPublicIpAddressSupplier(TerremarkECloudClient.class.cast(tmClient)) + .getNewInternetServiceAndIp(vApp, 22, Protocol.TCP); } } diff --git a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudComputeServiceLiveTest.java b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudComputeServiceLiveTest.java index 5a6fe2e759..b4bdc74cf4 100644 --- a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudComputeServiceLiveTest.java +++ b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudComputeServiceLiveTest.java @@ -52,7 +52,7 @@ public class TerremarkECloudComputeServiceLiveTest extends BaseComputeServiceLiv @Override public void setServiceDefaults() { - tag = "te"; + group = "te"; } @Test diff --git a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudTemplateBuilderLiveTest.java b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudTemplateBuilderLiveTest.java index 7d4a6675a6..6111bf97c4 100644 --- a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudTemplateBuilderLiveTest.java +++ b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkECloudTemplateBuilderLiveTest.java @@ -23,6 +23,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import java.io.IOException; +import java.util.Set; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; @@ -31,6 +32,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -49,12 +51,23 @@ public class TerremarkECloudTemplateBuilderLiveTest extends BaseTemplateBuilderL @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL) || // - (input.family == OsFamily.CENTOS && !input.version.equals("5.5")) || // - (input.family == OsFamily.UBUNTU &&( !input.version.equals("10.04")&&!input.version.equals("8.04"))) || // - (input.family == OsFamily.WINDOWS && (input.version.equals("2008 SP2") || input.version.equals("2008 R2")))); + switch (input.family) { + case RHEL: + return !input.version.equals("") && !input.version.matches("5.[50]"); + case SOLARIS: + return !input.is64Bit; + case CENTOS: + return !input.version.equals("") && !input.version.matches("5.[50]"); + case UBUNTU: + return !input.version.equals("") && !input.version.equals("10.04") && !input.version.equals("8.04"); + case WINDOWS: + return !input.version.equals("") && !input.version.equals("2003 R2") // + && !(input.version.equals("2008") && !input.is64Bit) // + && !(input.version.matches("2008( R2)?") && input.is64Bit); + default: + return true; + } } - }; } @@ -65,7 +78,10 @@ public class TerremarkECloudTemplateBuilderLiveTest extends BaseTemplateBuilderL assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.CENTOS); assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); - } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-FL", "NL-NH"); + } } \ No newline at end of file diff --git a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/functions/TerremarkECloudParseOsFromVAppTemplateNameTest.java b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/functions/TerremarkECloudParseOsFromVAppTemplateNameTest.java new file mode 100644 index 0000000000..e0d0bb3ef4 --- /dev/null +++ b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/compute/functions/TerremarkECloudParseOsFromVAppTemplateNameTest.java @@ -0,0 +1,169 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.vcloud.terremark.compute.functions; + +import static org.testng.Assert.assertEquals; + +import java.io.InputStream; +import java.util.Map; +import java.util.Set; + +import org.jclouds.compute.domain.OperatingSystemBuilder; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.http.functions.ParseSax; +import org.jclouds.http.functions.ParseSax.Factory; +import org.jclouds.http.functions.config.SaxParserModule; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import org.jclouds.vcloud.xml.CatalogHandler; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.TypeLiteral; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "TerremarkECloudParseOsFromVAppTemplateNameTest") +public class TerremarkECloudParseOsFromVAppTemplateNameTest { + + public Set parseNames(String resource) { + InputStream is = getClass().getResourceAsStream(resource); + Injector injector = Guice.createInjector(new SaxParserModule()); + Factory factory = injector.getInstance(ParseSax.Factory.class); + return factory.create(injector.getInstance(CatalogHandler.class)).parse(is).keySet(); + } + + public void test() { + + TerremarkECloudParseOsFromVAppTemplateName function = new TerremarkECloudParseOsFromVAppTemplateName(Guice + .createInjector(new GsonModule()).getInstance(Json.class).>> fromJson( + new ComputeServiceConstants.ReferenceData().osVersionMapJson, + new TypeLiteral>>() { + }.getType())); + Set names = parseNames("/catalog-ecloud.xml"); + assertEquals(Sets.newLinkedHashSet(Iterables.transform(names, function)), ImmutableSet.of( + + // CentOS 5 (x64) + new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.0").description("CentOS 5 (x64)") + .is64Bit(true).build(), + // CentOS 5 (x86) + new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.0").description("CentOS 5 (x86)") + .is64Bit(false).build(), + // CentOS 5.5 x32 + new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.5").description("CentOS 5.5 x32") + .is64Bit(false).build(), + // CentOS 5.5 x64 + new OperatingSystemBuilder().family(OsFamily.CENTOS).version("5.5").description("CentOS 5.5 x64") + .is64Bit(true).build(), + // Red Hat Enterprise Linux 5 (x64) + new OperatingSystemBuilder().family(OsFamily.RHEL).version("5.0").description( + "Red Hat Enterprise Linux 5 (x64)").is64Bit(true).build(), + // Red Hat Enterprise Linux 5 (x86) + new OperatingSystemBuilder().family(OsFamily.RHEL).version("5.0").description( + "Red Hat Enterprise Linux 5 (x86)").is64Bit(false).build(), + // Red Hat Enterprise Linux 5.5 x32 + new OperatingSystemBuilder().family(OsFamily.RHEL).version("5.5").description( + "Red Hat Enterprise Linux 5.5 x32").is64Bit(false).build(), + // Red Hat Enterprise Linux 5.5 x64 + new OperatingSystemBuilder().family(OsFamily.RHEL).version("5.5").description( + "Red Hat Enterprise Linux 5.5 x64").is64Bit(true).build(), + // Sun Solaris 10 (x64) + new OperatingSystemBuilder().family(OsFamily.SOLARIS).version("10").description("Sun Solaris 10 (x64)") + .is64Bit(true).build(), + // Ubuntu 8.04 LTS (x64) + new OperatingSystemBuilder().family(OsFamily.UBUNTU).version("8.04") + .description("Ubuntu 8.04 LTS (x64)").is64Bit(true).build(), + // Ubuntu 8.04 LTS (x86) + new OperatingSystemBuilder().family(OsFamily.UBUNTU).version("8.04") + .description("Ubuntu 8.04 LTS (x86)").is64Bit(false).build(), + // Ubuntu Server 10.04 x32 + new OperatingSystemBuilder().family(OsFamily.UBUNTU).version("10.04").description( + "Ubuntu Server 10.04 x32").is64Bit(false).build(), + // Ubuntu Server 10.04 x64 + new OperatingSystemBuilder().family(OsFamily.UBUNTU).version("10.04").description( + "Ubuntu Server 10.04 x64").is64Bit(true).build(), + // -Windows 2003 Std. R2 SQL 2005 Std. (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2003 R2").description( + "-Windows 2003 Std. R2 SQL 2005 Std. (x64)").is64Bit(true).build(), + // -Windows 2003 Std. R2 SQL 2008 Std. (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2003 R2").description( + "-Windows 2003 Std. R2 SQL 2008 Std. (x64)").is64Bit(true).build(), + // -Windows 2008 R2 Std wSQL 2008 R2 Std (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008 R2").description( + "-Windows 2008 R2 Std wSQL 2008 R2 Std (x64)").is64Bit(true).build(), + // -Windows 2008 R2 Std wSQL 2008 R2 Web (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008 R2").description( + "-Windows 2008 R2 Std wSQL 2008 R2 Web (x64)").is64Bit(true).build(), + // -Windows 2008 Std wSQL 2008 Std (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows 2008 Std wSQL 2008 Std (x64)").is64Bit(true).build(), + // -Windows 2008 Std wSQL 2008 Web (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows 2008 Std wSQL 2008 Web (x64)").is64Bit(true).build(), + // -Windows Server 2003 R2 Enterprise Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2003 R2").description( + "-Windows Server 2003 R2 Enterprise Edition (x64)").is64Bit(true).build(), + // -Windows Server 2003 R2 Enterprise Edition (x86) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2003 R2").description( + "-Windows Server 2003 R2 Enterprise Edition (x86)").is64Bit(false).build(), + // -Windows Server 2003 R2 Standard Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2003 R2").description( + "-Windows Server 2003 R2 Standard Edition (x64)").is64Bit(true).build(), + // -Windows Server 2003 R2 Standard Edition (x86) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2003 R2").description( + "-Windows Server 2003 R2 Standard Edition (x86)").is64Bit(false).build(), + // -Windows Server 2008 Enterprise Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows Server 2008 Enterprise Edition (x64)").is64Bit(true).build(), + // -Windows Server 2008 Enterprise Edition (x86) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows Server 2008 Enterprise Edition (x86)").is64Bit(false).build(), + // -Windows Server 2008 R2 Enterprise Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008 R2").description( + "-Windows Server 2008 R2 Enterprise Edition (x64)").is64Bit(true).build(), + // -Windows Server 2008 R2 Standard Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008 R2").description( + "-Windows Server 2008 R2 Standard Edition (x64)").is64Bit(true).build(), + // -Windows Server 2008 R2 Web Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008 R2").description( + "-Windows Server 2008 R2 Web Edition (x64)").is64Bit(true).build(), + // -Windows Server 2008 Standard Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows Server 2008 Standard Edition (x64)").is64Bit(true).build(), + // -Windows Server 2008 Standard Edition (x86) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows Server 2008 Standard Edition (x86)").is64Bit(false).build(), + // -Windows Server 2008 Web Edition (x64) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows Server 2008 Web Edition (x64)").is64Bit(true).build(), + // -Windows Server 2008 Web Edition (x86) + new OperatingSystemBuilder().family(OsFamily.WINDOWS).version("2008").description( + "-Windows Server 2008 Web Edition (x86)").is64Bit(false).build() + + )); + + } +} diff --git a/providers/trmk-ecloud/src/test/resources/catalog-ecloud.xml b/providers/trmk-ecloud/src/test/resources/catalog-ecloud.xml new file mode 100755 index 0000000000..8f8adbf5d7 --- /dev/null +++ b/providers/trmk-ecloud/src/test/resources/catalog-ecloud.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/providers/trmk-vcloudexpress/README.txt b/providers/trmk-vcloudexpress/README.txt new file mode 100644 index 0000000000..203175da77 --- /dev/null +++ b/providers/trmk-vcloudexpress/README.txt @@ -0,0 +1,27 @@ +==== + + Copyright (C) 2010 Cloud Conscious, LLC. + + ==================================================================== + 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. + ==================================================================== +==== + +# +# The jclouds provider for Terremark's vCloud Express (http://vcloudexpress.terremark.com/) platform. +# +# Expects the jclouds vcloudexpress API to be present on your application's classpath. +# +# TODO: Implementation status. +# TODO: Supported features. +# See http://code.google.com/p/jclouds/wiki/QuickStartTerremark for example usage. \ No newline at end of file diff --git a/providers/trmk-vcloudexpress/pom.xml b/providers/trmk-vcloudexpress/pom.xml index dea99828da..d9a365b3f0 100644 --- a/providers/trmk-vcloudexpress/pom.xml +++ b/providers/trmk-vcloudexpress/pom.xml @@ -94,6 +94,12 @@ ${project.version} test + + com.jcraft + jsch + 0.1.44 + test + log4j log4j diff --git a/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressAsyncClient.java b/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressAsyncClient.java index de527cd7bf..71745ea960 100644 --- a/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressAsyncClient.java +++ b/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressAsyncClient.java @@ -36,7 +36,7 @@ import javax.ws.rs.Produces; import org.jclouds.rest.annotations.EndpointParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.MapBinder; -import org.jclouds.rest.annotations.MapPayloadParam; +import org.jclouds.rest.annotations.PayloadParam; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.XMLResponseParser; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; @@ -76,8 +76,8 @@ public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncC @MapBinder(AddInternetServiceOptions.class) ListenableFuture addInternetServiceToVDC( @EndpointParam(parser = VDCURIToInternetServicesEndpoint.class) URI vDCId, - @MapPayloadParam("name") String serviceName, @MapPayloadParam("protocol") Protocol protocol, - @MapPayloadParam("port") int port, AddInternetServiceOptions... options); + @PayloadParam("name") String serviceName, @PayloadParam("protocol") Protocol protocol, + @PayloadParam("port") int port, AddInternetServiceOptions... options); /** * @see TerremarkVCloudExpressClient#findKeyPairInOrgNamed @@ -117,8 +117,8 @@ public interface TerremarkVCloudExpressAsyncClient extends TerremarkVCloudAsyncC @XMLResponseParser(KeyPairHandler.class) @MapBinder(BindCreateKeyToXmlPayload.class) ListenableFuture generateKeyPairInOrg( - @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, @MapPayloadParam("name") String name, - @MapPayloadParam("isDefault") boolean makeDefault); + @EndpointParam(parser = OrgURIToKeysListEndpoint.class) URI org, @PayloadParam("name") String name, + @PayloadParam("isDefault") boolean makeDefault); /** * @see TerremarkVCloudExpressClient#getKeyPair diff --git a/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressPropertiesBuilder.java b/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressPropertiesBuilder.java index b14b69da3e..9a1f282ba6 100644 --- a/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressPropertiesBuilder.java +++ b/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressPropertiesBuilder.java @@ -21,6 +21,7 @@ package org.jclouds.vcloud.terremark; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_ENDPOINT; +import static org.jclouds.Constants.PROPERTY_ISO3166_CODES; import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_NAME; import static org.jclouds.vcloud.terremark.reference.TerremarkConstants.PROPERTY_TERREMARK_EXTENSION_VERSION; @@ -36,6 +37,7 @@ public class TerremarkVCloudExpressPropertiesBuilder extends TerremarkVCloudProp protected Properties defaultProperties() { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_API_VERSION, "0.8a-ext1.6"); + properties.setProperty(PROPERTY_ISO3166_CODES, "US-FL"); properties.setProperty(PROPERTY_TERREMARK_EXTENSION_NAME, "vCloudExpressExtensions"); properties.setProperty(PROPERTY_TERREMARK_EXTENSION_VERSION, "1.6"); properties.setProperty(PROPERTY_ENDPOINT, "https://services.vcloudexpress.terremark.com/api"); diff --git a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressClientLiveTest.java b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressClientLiveTest.java index a01b730154..9901ecb592 100644 --- a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressClientLiveTest.java +++ b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressClientLiveTest.java @@ -23,8 +23,6 @@ import static org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTempl import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; -import java.net.URI; -import java.util.Map; import java.util.Set; import java.util.Map.Entry; import java.util.concurrent.ExecutionException; @@ -33,18 +31,17 @@ import java.util.concurrent.TimeoutException; import org.jclouds.domain.Credentials; import org.jclouds.net.IPSocket; import org.jclouds.ssh.SshClient; +import org.jclouds.vcloud.domain.VCloudExpressVApp; import org.jclouds.vcloud.terremark.domain.InternetService; import org.jclouds.vcloud.terremark.domain.KeyPair; import org.jclouds.vcloud.terremark.domain.Protocol; import org.jclouds.vcloud.terremark.domain.PublicIpAddress; import org.jclouds.vcloud.terremark.domain.TerremarkOrg; import org.jclouds.vcloud.terremark.options.TerremarkInstantiateVAppTemplateOptions; +import org.jclouds.vcloud.terremark.suppliers.TerremarkVCloudExpressInternetServiceAndPublicIpAddressSupplier; import org.testng.annotations.AfterTest; import org.testng.annotations.Test; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; - /** * Tests behavior of {@code TerremarkVCloudClient} * @@ -53,16 +50,6 @@ import com.google.common.collect.Iterables; @Test(groups = "live", sequential = true) public class TerremarkVCloudExpressClientLiveTest extends TerremarkClientLiveTest { - @Override - protected Entry getNewInternetServiceAndIpForSSH(URI vdc) { - InternetService is = TerremarkVCloudExpressClient.class.cast(tmClient).addInternetServiceToVDC( - tmClient.findVDCInOrgNamed(null, null).getHref(), "SSH", Protocol.TCP, 22); - PublicIpAddress ip = is.getPublicIpAddress(); - Map result = ImmutableMap. of(is, ip); - Entry entry = Iterables.getOnlyElement(result.entrySet()); - return entry; - } - KeyPair key; @Test @@ -114,4 +101,10 @@ public class TerremarkVCloudExpressClientLiveTest extends TerremarkClientLiveTes protected TerremarkInstantiateVAppTemplateOptions createInstantiateOptions() { return processorCount(1).memory(512).sshKeyFingerprint(key.getFingerPrint()); } + + @Override + protected Entry getNewInternetServiceAndIpForSSH(VCloudExpressVApp vApp) { + return new TerremarkVCloudExpressInternetServiceAndPublicIpAddressSupplier(TerremarkVCloudExpressClient.class + .cast(tmClient)).getNewInternetServiceAndIp(vApp, 22, Protocol.TCP); + } } diff --git a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressComputeServiceLiveTest.java b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressComputeServiceLiveTest.java index 5887f2e4c1..3184af9fa4 100644 --- a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressComputeServiceLiveTest.java +++ b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressComputeServiceLiveTest.java @@ -52,7 +52,7 @@ public class TerremarkVCloudExpressComputeServiceLiveTest extends BaseComputeSer @Override public void setServiceDefaults() { - tag = "vcx"; + group = "vcx"; } @Test diff --git a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressTemplateBuilderLiveTest.java b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressTemplateBuilderLiveTest.java index 573d37206f..d38f57d425 100644 --- a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressTemplateBuilderLiveTest.java +++ b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/compute/TerremarkVCloudExpressTemplateBuilderLiveTest.java @@ -23,6 +23,7 @@ import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import java.io.IOException; +import java.util.Set; import org.jclouds.compute.BaseTemplateBuilderLiveTest; import org.jclouds.compute.domain.OsFamily; @@ -31,6 +32,7 @@ import org.jclouds.compute.domain.os.OsFamilyVersion64Bit; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; /** * @@ -46,14 +48,22 @@ public class TerremarkVCloudExpressTemplateBuilderLiveTest extends BaseTemplateB @Override protected Predicate defineUnsupportedOperatingSystems() { return new Predicate() { - @Override public boolean apply(OsFamilyVersion64Bit input) { - return ((input.family == OsFamily.RHEL || input.family == OsFamily.CENTOS) || // - (input.family == OsFamily.UBUNTU && !input.version.equals("9.10")) || // - (input.family == OsFamily.WINDOWS && (input.version.equals("2008 SP2") || input.version.equals("2008 R2")))); + switch (input.family) { + case RHEL: + return !input.version.equals("") && !input.version.equals("5.0"); + case CENTOS: + return !input.version.equals("") && !input.version.matches("5.0"); + case UBUNTU: + return !input.version.equals("") && !(input.version.equals("9.04") || input.version.equals("9.10")); + case WINDOWS: + return !input.version.equals("") && !input.version.equals("2003") // + && !input.version.equals("2008"); + default: + return true; + } } - }; } @@ -66,4 +76,8 @@ public class TerremarkVCloudExpressTemplateBuilderLiveTest extends BaseTemplateB assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); } + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-FL"); + } } \ No newline at end of file diff --git a/sandbox-apis/byon/src/test/resources/test1.yaml b/sandbox-apis/byon/src/test/resources/test1.yaml deleted file mode 100644 index 4a611af553..0000000000 --- a/sandbox-apis/byon/src/test/resources/test1.yaml +++ /dev/null @@ -1,15 +0,0 @@ -nodes: - cluster-1: - id: cluster-1 - description: xyz - hostname: cluster-1.mydomain.com - os_arch: x86 - os_family: rhel - os_name: redhat - os_version: 5.3 - group: hadoop - tags: - - vanilla - username: myUser - credential: ZmFuY3lmb290 - sudo_password: c3Vkbw== \ No newline at end of file diff --git a/sandbox-apis/cloudstack/pom.xml b/sandbox-apis/cloudstack/pom.xml new file mode 100644 index 0000000000..25ed745e4e --- /dev/null +++ b/sandbox-apis/cloudstack/pom.xml @@ -0,0 +1,135 @@ + + + + 4.0.0 + + org.jclouds + jclouds-project + 1.0-SNAPSHOT + ../../project/pom.xml + + org.jclouds.api + cloudstack + jclouds cloudstack core + jclouds components to access cloudstack + + + + + jclouds-rimu-snapshots-nexus + https://oss.sonatype.org/content/repositories/snapshots + + true + + + + + + http://localhost:8080/client/api + 2.2 + FIXME_apiKey + FIXME_secretKey + + + + org.jclouds + jclouds-core + ${project.version} + + + org.jclouds + jclouds-core + ${project.version} + test-jar + test + + + org.jclouds.driver + jclouds-jsch + ${project.version} + test + + + com.jcraft + jsch + 0.1.44 + test + + + log4j + log4j + 1.2.16 + test + + + org.jclouds.driver + jclouds-log4j + ${project.version} + test + + + + + live + + + + org.apache.maven.plugins + maven-surefire-plugin + + + integration + integration-test + + test + + + + + test.cloudstack.endpoint + ${test.cloudstack.endpoint} + + + test.cloudstack.apiversion + ${test.cloudstack.apiversion} + + + test.cloudstack.identity + ${test.cloudstack.identity} + + + test.cloudstack.credential + ${test.cloudstack.credential} + + + + + + + + + + + diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackAsyncClient.java new file mode 100644 index 0000000000..58d9667b3a --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackAsyncClient.java @@ -0,0 +1,82 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack; + +import org.jclouds.cloudstack.features.AsyncJobAsyncClient; +import org.jclouds.cloudstack.features.NetworkAsyncClient; +import org.jclouds.cloudstack.features.OfferingAsyncClient; +import org.jclouds.cloudstack.features.SecurityGroupAsyncClient; +import org.jclouds.cloudstack.features.TemplateAsyncClient; +import org.jclouds.cloudstack.features.VirtualMachineAsyncClient; +import org.jclouds.cloudstack.features.ZoneAsyncClient; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides asynchronous access to CloudStack via their REST API. + *

+ * + * @see CloudStackClient + * @see + * @author Adrian Cole + */ +public interface CloudStackAsyncClient { + + /** + * Provides asynchronous access to Zone features. + */ + @Delegate + ZoneAsyncClient getZoneClient(); + + /** + * Provides asynchronous access to Template features. + */ + @Delegate + TemplateAsyncClient getTemplateClient(); + + /** + * Provides asynchronous access to Service, Disk, and Network Offering features. + */ + @Delegate + OfferingAsyncClient getOfferingClient(); + + /** + * Provides asynchronous access to Network features. + */ + @Delegate + NetworkAsyncClient getNetworkClient(); + + /** + * Provides asynchronous access to VirtualMachine features. + */ + @Delegate + VirtualMachineAsyncClient getVirtualMachineClient(); + + /** + * Provides asynchronous access to SecurityGroup features. + */ + @Delegate + SecurityGroupAsyncClient getSecurityGroupClient(); + + /** + * Provides asynchronous access to AsyncJob features. + */ + @Delegate + AsyncJobAsyncClient getAsyncJobClient(); +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackClient.java new file mode 100644 index 0000000000..140241d4a9 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackClient.java @@ -0,0 +1,85 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack; + +import java.util.concurrent.TimeUnit; + +import org.jclouds.cloudstack.features.AsyncJobClient; +import org.jclouds.cloudstack.features.NetworkClient; +import org.jclouds.cloudstack.features.OfferingClient; +import org.jclouds.cloudstack.features.SecurityGroupClient; +import org.jclouds.cloudstack.features.TemplateClient; +import org.jclouds.cloudstack.features.VirtualMachineClient; +import org.jclouds.cloudstack.features.ZoneClient; +import org.jclouds.concurrent.Timeout; +import org.jclouds.rest.annotations.Delegate; + +/** + * Provides synchronous access to CloudStack. + *

+ * + * @see CloudStackAsyncClient + * @see + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface CloudStackClient { + /** + * Provides synchronous access to Zone features. + */ + @Delegate + ZoneClient getZoneClient(); + + /** + * Provides synchronous access to Template features. + */ + @Delegate + TemplateClient getTemplateClient(); + + /** + * Provides synchronous access to Service, Disk, and Network Offering features. + */ + @Delegate + OfferingClient getOfferingClient(); + + /** + * Provides synchronous access to Network features. + */ + @Delegate + NetworkClient getNetworkClient(); + + /** + * Provides synchronous access to VirtualMachine features. + */ + @Delegate + VirtualMachineClient getVirtualMachineClient(); + + /** + * Provides synchronous access to SecurityGroup features. + */ + @Delegate + SecurityGroupClient getSecurityGroupClient(); + + /** + * Provides synchronous access to AsyncJob features. + */ + @Delegate + AsyncJobClient getAsyncJobClient(); +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackContextBuilder.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackContextBuilder.java new file mode 100644 index 0000000000..396b368eba --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackContextBuilder.java @@ -0,0 +1,45 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack; + +import java.util.List; +import java.util.Properties; + +import org.jclouds.cloudstack.config.CloudStackRestClientModule; +import org.jclouds.rest.RestContextBuilder; + +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +public class CloudStackContextBuilder extends + RestContextBuilder { + + public CloudStackContextBuilder(Properties props) { + super(CloudStackClient.class, CloudStackAsyncClient.class, props); + } + + protected void addClientModule(List modules) { + modules.add(new CloudStackRestClientModule()); + } + +} diff --git a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesPropertiesBuilder.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackPropertiesBuilder.java similarity index 64% rename from apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesPropertiesBuilder.java rename to sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackPropertiesBuilder.java index ee457e7855..f9cc073cde 100644 --- a/apis/cloudfiles/src/main/java/org/jclouds/cloudfiles/CloudFilesPropertiesBuilder.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/CloudStackPropertiesBuilder.java @@ -17,30 +17,28 @@ * ==================================================================== */ -package org.jclouds.cloudfiles; +package org.jclouds.cloudstack; -import static org.jclouds.Constants.PROPERTY_ENDPOINT; -import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; +import static org.jclouds.Constants.PROPERTY_API_VERSION; import java.util.Properties; -import org.jclouds.openstack.swift.SwiftPropertiesBuilder; +import org.jclouds.PropertiesBuilder; /** - * Builds properties used in CloudFiles Connections + * Builds properties used in cloudstack Clients * * @author Adrian Cole */ -public class CloudFilesPropertiesBuilder extends SwiftPropertiesBuilder { +public class CloudStackPropertiesBuilder extends PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); - properties.setProperty(PROPERTY_REGIONS, "US"); - properties.setProperty(PROPERTY_ENDPOINT, "https://auth.api.rackspacecloud.com"); + properties.setProperty(PROPERTY_API_VERSION, "2.2"); return properties; } - public CloudFilesPropertiesBuilder(Properties properties) { + public CloudStackPropertiesBuilder(Properties properties) { super(properties); } diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java new file mode 100644 index 0000000000..1dfda6af99 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/config/CloudStackRestClientModule.java @@ -0,0 +1,89 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.config; + +import java.util.Map; + +import org.jclouds.cloudstack.CloudStackAsyncClient; +import org.jclouds.cloudstack.CloudStackClient; +import org.jclouds.cloudstack.features.AsyncJobAsyncClient; +import org.jclouds.cloudstack.features.AsyncJobClient; +import org.jclouds.cloudstack.features.NetworkAsyncClient; +import org.jclouds.cloudstack.features.NetworkClient; +import org.jclouds.cloudstack.features.OfferingAsyncClient; +import org.jclouds.cloudstack.features.OfferingClient; +import org.jclouds.cloudstack.features.SecurityGroupAsyncClient; +import org.jclouds.cloudstack.features.SecurityGroupClient; +import org.jclouds.cloudstack.features.TemplateAsyncClient; +import org.jclouds.cloudstack.features.TemplateClient; +import org.jclouds.cloudstack.features.VirtualMachineAsyncClient; +import org.jclouds.cloudstack.features.VirtualMachineClient; +import org.jclouds.cloudstack.features.ZoneAsyncClient; +import org.jclouds.cloudstack.features.ZoneClient; +import org.jclouds.cloudstack.handlers.CloudStackErrorHandler; +import org.jclouds.http.HttpErrorHandler; +import org.jclouds.http.RequiresHttp; +import org.jclouds.http.annotation.ClientError; +import org.jclouds.http.annotation.Redirection; +import org.jclouds.http.annotation.ServerError; +import org.jclouds.json.config.GsonModule.DateAdapter; +import org.jclouds.json.config.GsonModule.Iso8601DateAdapter; +import org.jclouds.rest.ConfiguresRestClient; +import org.jclouds.rest.config.RestClientModule; + +import com.google.common.collect.ImmutableMap; + +/** + * Configures the cloudstack connection. + * + * @author Adrian Cole + */ +@RequiresHttp +@ConfiguresRestClient +public class CloudStackRestClientModule extends RestClientModule { + + public static final Map, Class> DELEGATE_MAP = ImmutableMap., Class> builder()// + .put(ZoneClient.class, ZoneAsyncClient.class)// + .put(TemplateClient.class, TemplateAsyncClient.class)// + .put(OfferingClient.class, OfferingAsyncClient.class)// + .put(NetworkClient.class, NetworkAsyncClient.class)// + .put(VirtualMachineClient.class, VirtualMachineAsyncClient.class)// + .put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)// + .put(AsyncJobClient.class, AsyncJobAsyncClient.class)// + .build(); + + public CloudStackRestClientModule() { + super(CloudStackClient.class, CloudStackAsyncClient.class, DELEGATE_MAP); + } + + @Override + protected void configure() { + bind(DateAdapter.class).to(Iso8601DateAdapter.class); + super.configure(); + } + + @Override + protected void bindErrorHandlers() { + bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(CloudStackErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(CloudStackErrorHandler.class); + bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(CloudStackErrorHandler.class); + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/AsyncCreateResponse.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/AsyncCreateResponse.java new file mode 100644 index 0000000000..b89b447204 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/AsyncCreateResponse.java @@ -0,0 +1,55 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class AsyncCreateResponse { + private long id; + @SerializedName("jobid") + private long jobId; + + /** + * present only for serializer + * + */ + AsyncCreateResponse() { + + } + + /** + * @return id of the resource being created + */ + public long getId() { + return id; + } + + /** + * @return id of the job in progress + */ + public long getJobId() { + return jobId; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/AsyncJob.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/AsyncJob.java new file mode 100644 index 0000000000..5c9c0e89c6 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/AsyncJob.java @@ -0,0 +1,242 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import java.util.Date; +import java.util.Map; + +import com.google.common.collect.ImmutableMap; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class AsyncJob { + @SerializedName("accountid") + private long accountId = -1; + private String cmd; + private Date created; + @SerializedName("jobid") + private long id = -1; + @SerializedName("jobinstanceid") + private long instanceId = -1; + @SerializedName("jobinstancetype") + private String instanceType; + @SerializedName("jobprocstatus") + private int progress = -1; + @SerializedName("jobresult") + private Map result = ImmutableMap.of(); + @SerializedName("jobresultcode") + private int resultCode = -1; + @SerializedName("jobresulttype") + private String resultType; + @SerializedName("jobstatus") + private int status = -1; + @SerializedName("userid") + private int userId = -1; + + public AsyncJob(int accountId, String cmd, Date created, long id, long instanceId, String instanceType, + int progress, Map result, int resultCode, String resultType, int status, int userId) { + this.accountId = accountId; + this.cmd = cmd; + this.created = created; + this.id = id; + this.instanceId = instanceId; + this.instanceType = instanceType; + this.progress = progress; + this.result = result; + this.resultCode = resultCode; + this.resultType = resultType; + this.status = status; + this.userId = userId; + } + + /** + * present only for serializer + * + */ + AsyncJob() { + + } + + /** + * @return the account that executed the async command + */ + public long getAccountId() { + return accountId; + } + + /** + * @return the async command executed + */ + public String getCmd() { + return cmd; + } + + /** + * @return the created date of the job + */ + public Date getCreated() { + return created; + } + + /** + * @return async job ID + */ + public long getId() { + return id; + } + + /** + * @return the unique ID of the instance/entity object related to the job + */ + public long getInstanceId() { + return instanceId; + } + + /** + * @return the instance/entity object related to the job + */ + public String getInstanceType() { + return instanceType; + } + + /** + * @return the progress information of the PENDING job + */ + public int getProgress() { + return progress; + } + + /** + * @return the result reason + */ + public Map getResult() { + return result; + } + + /** + * @return the result code for the job + */ + public int getResultCode() { + return resultCode; + } + + /** + * @return the result type + */ + public String getResultType() { + return resultType; + } + + /** + * @return the current job status-should be 0 for PENDING + */ + public int getStatus() { + return status; + } + + /** + * @return the user that executed the async command + */ + public int getUserId() { + return userId; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (int) (accountId ^ (accountId >>> 32)); + result = prime * result + ((cmd == null) ? 0 : cmd.hashCode()); + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + (int) (instanceId ^ (instanceId >>> 32)); + result = prime * result + ((instanceType == null) ? 0 : instanceType.hashCode()); + result = prime * result + progress; + result = prime * result + ((this.result == null) ? 0 : this.result.hashCode()); + result = prime * result + resultCode; + result = prime * result + ((resultType == null) ? 0 : resultType.hashCode()); + result = prime * result + status; + result = prime * result + userId; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + AsyncJob other = (AsyncJob) obj; + if (accountId != other.accountId) + return false; + if (cmd == null) { + if (other.cmd != null) + return false; + } else if (!cmd.equals(other.cmd)) + return false; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (id != other.id) + return false; + if (instanceId != other.instanceId) + return false; + if (instanceType == null) { + if (other.instanceType != null) + return false; + } else if (!instanceType.equals(other.instanceType)) + return false; + if (progress != other.progress) + return false; + if (result == null) { + if (other.result != null) + return false; + } else if (!result.equals(other.result)) + return false; + if (resultCode != other.resultCode) + return false; + if (resultType == null) { + if (other.resultType != null) + return false; + } else if (!resultType.equals(other.resultType)) + return false; + if (status != other.status) + return false; + if (userId != other.userId) + return false; + return true; + } + + @Override + public String toString() { + return "[accountId=" + accountId + ", cmd=" + cmd + ", created=" + created + ", id=" + id + ", instanceId=" + + instanceId + ", instanceType=" + instanceType + ", progress=" + progress + ", result=" + result + + ", resultCode=" + resultCode + ", resultType=" + resultType + ", status=" + status + ", userId=" + userId + + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/DiskOffering.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/DiskOffering.java new file mode 100644 index 0000000000..b42611e49a --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/DiskOffering.java @@ -0,0 +1,211 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import java.util.Date; +import java.util.Set; + +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class DiskOffering { + private long id; + private String name; + @SerializedName("displaytext") + private String displayText; + private Date created; + private String domain; + @SerializedName("domainid") + private long domainId; + @SerializedName("disksize") + private int diskSize; + @SerializedName("iscustomized") + private boolean customized; + private String tags; + + public DiskOffering(long id, String name, String displayText, Date created, String domain, long domainId, + int diskSize, boolean customized, Set tags) { + this.id = id; + this.name = name; + this.displayText = displayText; + this.created = created; + this.domain = domain; + this.domainId = domainId; + this.diskSize = diskSize; + this.customized = customized; + this.tags = Joiner.on(',').join(tags); + } + + /** + * present only for serializer + * + */ + DiskOffering() { + + } + + /** + * + * @return the id of the disk offering + */ + public long getId() { + return id; + } + + /** + * + * @return the name of the disk offering + */ + + public String getName() { + return name; + } + + /** + * + * @return an alternate display text of the disk offering. + */ + public String getDisplayText() { + return displayText; + } + + /** + * + * @return the date this disk offering was created + */ + public Date getCreated() { + return created; + } + + /** + * + * @return Domain name for the offering + */ + public String getDomain() { + return domain; + } + + /** + * + * @return the domain id of the disk offering + */ + public long getDomainId() { + return domainId; + } + + /** + * + * @return the size of the disk offering in GB + */ + public int getDiskSize() { + return diskSize; + } + + /** + * + * @return the ha support in the disk offering + */ + public boolean isCustomized() { + return customized; + } + + /** + * + * @return the tags for the disk offering + */ + public Set getTags() { + return tags != null ? ImmutableSet.copyOf(Splitter.on(',').split(tags)) : ImmutableSet. of(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + (customized ? 1231 : 1237); + result = prime * result + diskSize; + result = prime * result + ((displayText == null) ? 0 : displayText.hashCode()); + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + (int) (domainId ^ (domainId >>> 32)); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((tags == null) ? 0 : tags.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; + DiskOffering other = (DiskOffering) obj; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (customized != other.customized) + return false; + if (diskSize != other.diskSize) + return false; + if (displayText == null) { + if (other.displayText != null) + return false; + } else if (!displayText.equals(other.displayText)) + return false; + if (domain == null) { + if (other.domain != null) + return false; + } else if (!domain.equals(other.domain)) + return false; + if (domainId != other.domainId) + return false; + if (id != other.id) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (tags == null) { + if (other.tags != null) + return false; + } else if (!tags.equals(other.tags)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", name=" + name + ", displayText=" + displayText + ", created=" + created + ", diskSize=" + + diskSize + ", iscustomized=" + customized + ", domain=" + domain + ", domainId=" + domainId + + ", tags=" + tags + "]"; + } + +} diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindServerNameToJsonPayload.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java similarity index 50% rename from apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindServerNameToJsonPayload.java rename to sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java index 0519e131b5..da12fc5461 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/binders/BindServerNameToJsonPayload.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/GuestIPType.java @@ -17,37 +17,42 @@ * ==================================================================== */ -package org.jclouds.cloudservers.binders; +package org.jclouds.cloudstack.domain; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import java.util.Map; - -import javax.inject.Singleton; - -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.binders.BindToJsonPayload; - -import com.google.common.collect.ImmutableMap; +import com.google.common.base.CaseFormat; /** * * @author Adrian Cole - * + * @see NetworkOfferingClient#listNetworkOfferings */ -@Singleton -public class BindServerNameToJsonPayload extends BindToJsonPayload { +public enum GuestIPType { + + /** + * guest IP address will be issued by Dhcp server in the guest virtual network. Dhcp role is + * played by domain router. + */ + VIRTUAL, + /** + * traffic directly to the network and VMs created here are assigned an IP directly from the + * network as configured + */ + DIRECT, + + UNRECOGNIZED; @Override - public R bindToRequest(R request, Map postParams) { - throw new IllegalStateException("Change Server Name is a PUT operation"); + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); } - @Override - public R bindToRequest(R request, Object toBind) { - checkArgument(toBind instanceof String, "this binder is only valid for Strings!"); - return super.bindToRequest(request, ImmutableMap.of("server", ImmutableMap.of("name", checkNotNull( - toBind, "name")))); + public static GuestIPType fromValue(String type) { + try { + return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } } } diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/IngressRule.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/IngressRule.java new file mode 100644 index 0000000000..7782a3e931 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/IngressRule.java @@ -0,0 +1,192 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class IngressRule { + private String account; + @SerializedName("cidr") + private String CIDR; + @SerializedName("endport") + private int endPort; + @SerializedName("icmpcode") + private int ICMPCode; + @SerializedName("icmptype") + private int ICMPType; + private String protocol; + @SerializedName("ruleid") + private long id; + @SerializedName("securitygroupname") + private String securityGroupName; + @SerializedName("startport") + private int startPort; + + // for serialization + IngressRule() { + + } + + public IngressRule(String account, String cIDR, int endPort, int iCMPCode, int iCMPType, String protocol, long id, + String securityGroupName, int startPort) { + this.account = account; + this.CIDR = cIDR; + this.endPort = endPort; + this.ICMPCode = iCMPCode; + this.ICMPType = iCMPType; + this.protocol = protocol; + this.id = id; + this.securityGroupName = securityGroupName; + this.startPort = startPort; + } + + /** + * @return account owning the ingress rule + */ + public String getAccount() { + return account; + } + + /** + * @return the CIDR notation for the base IP address of the ingress rule + */ + public String getCIDR() { + return CIDR; + } + + /** + * @return the ending IP of the ingress rule + */ + public int getEndPort() { + return endPort; + } + + /** + * @return the code for the ICMP message response + */ + public int getICMPCode() { + return ICMPCode; + } + + /** + * @return the type of the ICMP message response + */ + public int getICMPType() { + return ICMPType; + } + + /** + * @return the protocol of the ingress rule + */ + public String getProtocol() { + return protocol; + } + + /** + * @return the id of the ingress rule + */ + public long getId() { + return id; + } + + /** + * @return security group name + */ + public String getSecurityGroupName() { + return securityGroupName; + } + + /** + * @return the starting IP of the ingress rule + */ + public int getStartPort() { + return startPort; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((CIDR == null) ? 0 : CIDR.hashCode()); + result = prime * result + ICMPCode; + result = prime * result + ICMPType; + result = prime * result + ((account == null) ? 0 : account.hashCode()); + result = prime * result + endPort; + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((protocol == null) ? 0 : protocol.hashCode()); + result = prime * result + ((securityGroupName == null) ? 0 : securityGroupName.hashCode()); + result = prime * result + startPort; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + IngressRule other = (IngressRule) obj; + if (CIDR == null) { + if (other.CIDR != null) + return false; + } else if (!CIDR.equals(other.CIDR)) + return false; + if (ICMPCode != other.ICMPCode) + return false; + if (ICMPType != other.ICMPType) + return false; + if (account == null) { + if (other.account != null) + return false; + } else if (!account.equals(other.account)) + return false; + if (endPort != other.endPort) + return false; + if (id != other.id) + return false; + if (protocol == null) { + if (other.protocol != null) + return false; + } else if (!protocol.equals(other.protocol)) + return false; + if (securityGroupName == null) { + if (other.securityGroupName != null) + return false; + } else if (!securityGroupName.equals(other.securityGroupName)) + return false; + if (startPort != other.startPort) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", securityGroupName=" + securityGroupName + ", account=" + account + ", startPort=" + + startPort + ", endPort=" + endPort + ", protocol=" + protocol + ", CIDR=" + CIDR + ", ICMPCode=" + + ICMPCode + ", ICMPType=" + ICMPType + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NIC.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NIC.java new file mode 100644 index 0000000000..586389f788 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NIC.java @@ -0,0 +1,212 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import java.net.URI; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class NIC { + private long id; + @SerializedName("broadcasturi") + private URI broadcastURI; + private String gateway; + @SerializedName("ipaddress") + private String IPAddress; + @SerializedName("isdefault") + private boolean isDefault; + @SerializedName("isolationuri") + private URI isolationURI; + private String netmask; + @SerializedName("networkid") + private long networkId; + @SerializedName("traffictype") + private TrafficType trafficType; + @SerializedName("type") + private GuestIPType guestIPType; + + /** + * present only for serializer + * + */ + NIC() { + + } + + public NIC(long id, URI broadcastURI, String gateway, String iPAddress, boolean isDefault, URI isolationURI, + String netmask, long networkId, TrafficType trafficType, GuestIPType guestIPType) { + this.id = id; + this.broadcastURI = broadcastURI; + this.gateway = gateway; + this.IPAddress = iPAddress; + this.isDefault = isDefault; + this.isolationURI = isolationURI; + this.netmask = netmask; + this.networkId = networkId; + this.trafficType = trafficType; + this.guestIPType = guestIPType; + } + + /** + * the ID of the nic + */ + public long getId() { + return id; + } + + /** + * the broadcast uri of the nic + */ + public URI getBroadcastURI() { + return broadcastURI; + } + + /** + * the gateway of the nic + */ + public String getGateway() { + return gateway; + } + + /** + * the ip address of the nic + */ + public String getIPAddress() { + return IPAddress; + } + + /** + * true if nic is default, false otherwise + */ + public boolean isDefault() { + return isDefault; + } + + /** + * the isolation uri of the nic + */ + public URI getIsolationURI() { + return isolationURI; + } + + /** + * the netmask of the nic + */ + public String getNetmask() { + return netmask; + } + + /** + * the ID of the corresponding network + */ + public long getNetworkId() { + return networkId; + } + + /** + * the traffic type of the nic + */ + public TrafficType getTrafficType() { + return trafficType; + } + + /** + * the type of the nic + */ + public GuestIPType getGuestIPType() { + return guestIPType; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((IPAddress == null) ? 0 : IPAddress.hashCode()); + result = prime * result + ((broadcastURI == null) ? 0 : broadcastURI.hashCode()); + result = prime * result + ((gateway == null) ? 0 : gateway.hashCode()); + result = prime * result + ((guestIPType == null) ? 0 : guestIPType.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + (isDefault ? 1231 : 1237); + result = prime * result + ((isolationURI == null) ? 0 : isolationURI.hashCode()); + result = prime * result + ((netmask == null) ? 0 : netmask.hashCode()); + result = prime * result + (int) (networkId ^ (networkId >>> 32)); + result = prime * result + ((trafficType == null) ? 0 : trafficType.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; + NIC other = (NIC) obj; + if (IPAddress == null) { + if (other.IPAddress != null) + return false; + } else if (!IPAddress.equals(other.IPAddress)) + return false; + if (broadcastURI == null) { + if (other.broadcastURI != null) + return false; + } else if (!broadcastURI.equals(other.broadcastURI)) + return false; + if (gateway == null) { + if (other.gateway != null) + return false; + } else if (!gateway.equals(other.gateway)) + return false; + if (guestIPType != other.guestIPType) + return false; + if (id != other.id) + return false; + if (isDefault != other.isDefault) + return false; + if (isolationURI == null) { + if (other.isolationURI != null) + return false; + } else if (!isolationURI.equals(other.isolationURI)) + return false; + if (netmask == null) { + if (other.netmask != null) + return false; + } else if (!netmask.equals(other.netmask)) + return false; + if (networkId != other.networkId) + return false; + if (trafficType != other.trafficType) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", broadcastURI=" + broadcastURI + ", gateway=" + gateway + ", IPAddress=" + IPAddress + + ", isDefault=" + isDefault + ", isolationURI=" + isolationURI + ", netmask=" + netmask + ", networkId=" + + networkId + ", trafficType=" + trafficType + ", guestIPType=" + guestIPType + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Network.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Network.java new file mode 100644 index 0000000000..2c2cd443e8 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Network.java @@ -0,0 +1,546 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; +import java.util.List; +import java.util.Set; + +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableList.Builder; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class Network { + private long id; + private String account; + @SerializedName("broadcastdomaintype") + private String broadcastDomainType; + @SerializedName("broadcasturi") + private URI broadcastURI; + @SerializedName("displaytext") + private String displayText; + @SerializedName("dns1") + private String DNS1; + @SerializedName("dns2") + private String DNS2; + private String domain; + @Nullable + @SerializedName("domainid") + private long domainId; + @SerializedName("endip") + private String endIP; + private String gateway; + @SerializedName("isdefault") + private boolean isDefault; + @SerializedName("isshared") + private boolean isShared; + @SerializedName("issystem") + private boolean isSystem; + private String netmask; + @SerializedName("networkdomain") + private String networkDomain; + @SerializedName("networkofferingavailability") + private String networkOfferingAvailability; + @SerializedName("networkofferingdisplaytext") + private String networkOfferingDisplayText; + @SerializedName("networkofferingid") + private long networkOfferingId; + @SerializedName("networkofferingname") + private String networkOfferingName; + private String related; + @SerializedName("startip") + private String startIP; + private String name; + private String state; + @SerializedName("type") + private GuestIPType guestIPType; + @SerializedName("vlan") + private String VLAN; + @SerializedName("traffictype") + private TrafficType trafficType; + @SerializedName("zoneid") + private long zoneId; + @SerializedName("service") + private Set services = ImmutableSet. of(); + + /** + * present only for serializer + * + */ + Network() { + + } + + public Network(long id, String account, String broadcastDomainType, URI broadcastURI, String displayText, + List DNS, String domain, long domainId, String endIP, String gateway, boolean isDefault, + boolean isShared, boolean isSystem, String netmask, String networkDomain, String networkOfferingAvailability, + String networkOfferingDisplayText, long networkOfferingId, String networkOfferingName, String related, + String startIP, String name, String state, GuestIPType type, String vLAN, TrafficType trafficType, + long zoneId, Set services) { + this.id = id; + this.account = account; + this.broadcastDomainType = broadcastDomainType; + this.broadcastURI = broadcastURI; + this.displayText = displayText; + this.DNS1 = checkNotNull(DNS, "DNS").size() > 0 ? DNS.get(0) : null; + this.DNS2 = DNS.size() > 1 ? DNS.get(1) : null; + this.domain = domain; + this.domainId = domainId; + this.endIP = endIP; + this.gateway = gateway; + this.isDefault = isDefault; + this.isShared = isShared; + this.isSystem = isSystem; + this.netmask = netmask; + this.networkDomain = networkDomain; + this.networkOfferingAvailability = networkOfferingAvailability; + this.networkOfferingDisplayText = networkOfferingDisplayText; + this.networkOfferingId = networkOfferingId; + this.networkOfferingName = networkOfferingName; + this.related = related; + this.startIP = startIP; + this.name = name; + this.state = state; + this.guestIPType = type; + this.VLAN = vLAN; + this.trafficType = trafficType; + this.zoneId = zoneId; + this.services = ImmutableSet.copyOf(checkNotNull(services, "services")); + } + + /** + * + * @return network id + */ + public long getId() { + return id; + } + + /** + * + * @return the name of the account to which the template beLongs + */ + public String getAccount() { + return account; + } + + /** + * + * @return Broadcast domain type of the network + */ + public String getBroadcastDomainType() { + return broadcastDomainType; + } + + /** + * + * @return broadcast uri of the network + */ + public URI getBroadcastURI() { + return broadcastURI; + } + + /** + * + * @return the display text of the zone + */ + public String getDisplayText() { + return displayText; + } + + /** + * + * @return the external DNS for the network + */ + public List getDNS() { + Builder builder = ImmutableList.builder(); + if (DNS1 != null && !"".equals(DNS1)) + builder.add(DNS1); + if (DNS2 != null && !"".equals(DNS2)) + builder.add(DNS2); + return builder.build(); + } + + /** + * + * @return Domain name for the Vms in the zone + */ + public String getDomain() { + return domain; + } + + /** + * + * @return the ID of the containing domain, null for public zones + */ + @Nullable + public long getDomainId() { + return domainId; + } + + /** + * + * @return the end ip of the network + */ + public String getEndIP() { + return endIP; + } + + /** + * + * @return the network's gateway + */ + public String getGateway() { + return gateway; + } + + /** + * + * @return true if network offering is default, false otherwise + */ + public boolean isDefault() { + return isDefault; + } + + /** + * + * @return true if network offering is shared, false otherwise + */ + public boolean isShared() { + return isShared; + } + + /** + * + * @return true if network offering is system, false otherwise + */ + public boolean isSystem() { + return isSystem; + } + + /** + * + * @return network name + */ + public String getName() { + return name; + } + + /** + * + * @return the GuestIPType of the network + */ + public GuestIPType getGuestIPType() { + return guestIPType; + } + + /** + * + * @return state of the network + */ + public String getState() { + return state; + } + + /** + * + * @return the vlan range of the zone + */ + public String getVLAN() { + return VLAN; + } + + /** + * + * @return the traffic type for this network offering + */ + public TrafficType getTrafficType() { + return trafficType; + } + + /** + * + * @return the network's netmask + */ + public String getNetmask() { + return netmask; + } + + /** + * + * @return the network domain + */ + public String getNetworkDomain() { + return networkDomain; + } + + /** + * + * @return availability of the network offering the network is created from + */ + public String getNetworkOfferingAvailability() { + return networkOfferingAvailability; + } + + /** + * + * @return display text of the network offering the network is created from + */ + public String getNetworkOfferingDisplayText() { + return networkOfferingDisplayText; + } + + /** + * + * @return network offering id the network is created from + */ + public long getNetworkOfferingId() { + return networkOfferingId; + } + + /** + * + * @return name of the network offering the network is created from + */ + public String getNetworkOfferingName() { + return networkOfferingName; + } + + /** + * + * @return related to what other network configuration + */ + public String getRelated() { + return related; + } + + /** + * + * @return the start ip of the network + */ + public String getStartIP() { + return startIP; + } + + /** + * + * @return zone id of the network + */ + public long getZoneId() { + return zoneId; + } + + /** + * + * @return the list of services + */ + public Set getServices() { + return services; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((DNS1 == null) ? 0 : DNS1.hashCode()); + result = prime * result + ((DNS2 == null) ? 0 : DNS2.hashCode()); + result = prime * result + ((VLAN == null) ? 0 : VLAN.hashCode()); + result = prime * result + ((account == null) ? 0 : account.hashCode()); + result = prime * result + ((broadcastDomainType == null) ? 0 : broadcastDomainType.hashCode()); + result = prime * result + ((broadcastURI == null) ? 0 : broadcastURI.hashCode()); + result = prime * result + ((displayText == null) ? 0 : displayText.hashCode()); + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + (int) (domainId ^ (domainId >>> 32)); + result = prime * result + ((endIP == null) ? 0 : endIP.hashCode()); + result = prime * result + ((gateway == null) ? 0 : gateway.hashCode()); + result = prime * result + ((guestIPType == null) ? 0 : guestIPType.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + (isDefault ? 1231 : 1237); + result = prime * result + (isShared ? 1231 : 1237); + result = prime * result + (isSystem ? 1231 : 1237); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((netmask == null) ? 0 : netmask.hashCode()); + result = prime * result + ((networkDomain == null) ? 0 : networkDomain.hashCode()); + result = prime * result + ((networkOfferingAvailability == null) ? 0 : networkOfferingAvailability.hashCode()); + result = prime * result + ((networkOfferingDisplayText == null) ? 0 : networkOfferingDisplayText.hashCode()); + result = prime * result + (int) (networkOfferingId ^ (networkOfferingId >>> 32)); + result = prime * result + ((networkOfferingName == null) ? 0 : networkOfferingName.hashCode()); + result = prime * result + ((related == null) ? 0 : related.hashCode()); + result = prime * result + ((services == null) ? 0 : services.hashCode()); + result = prime * result + ((startIP == null) ? 0 : startIP.hashCode()); + result = prime * result + ((state == null) ? 0 : state.hashCode()); + result = prime * result + ((trafficType == null) ? 0 : trafficType.hashCode()); + result = prime * result + (int) (zoneId ^ (zoneId >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Network other = (Network) obj; + if (DNS1 == null) { + if (other.DNS1 != null) + return false; + } else if (!DNS1.equals(other.DNS1)) + return false; + if (DNS2 == null) { + if (other.DNS2 != null) + return false; + } else if (!DNS2.equals(other.DNS2)) + return false; + if (VLAN == null) { + if (other.VLAN != null) + return false; + } else if (!VLAN.equals(other.VLAN)) + return false; + if (account == null) { + if (other.account != null) + return false; + } else if (!account.equals(other.account)) + return false; + if (broadcastDomainType == null) { + if (other.broadcastDomainType != null) + return false; + } else if (!broadcastDomainType.equals(other.broadcastDomainType)) + return false; + if (broadcastURI == null) { + if (other.broadcastURI != null) + return false; + } else if (!broadcastURI.equals(other.broadcastURI)) + return false; + if (displayText == null) { + if (other.displayText != null) + return false; + } else if (!displayText.equals(other.displayText)) + return false; + if (domain == null) { + if (other.domain != null) + return false; + } else if (!domain.equals(other.domain)) + return false; + if (domainId != other.domainId) + return false; + if (endIP == null) { + if (other.endIP != null) + return false; + } else if (!endIP.equals(other.endIP)) + return false; + if (gateway == null) { + if (other.gateway != null) + return false; + } else if (!gateway.equals(other.gateway)) + return false; + if (guestIPType != other.guestIPType) + return false; + if (id != other.id) + return false; + if (isDefault != other.isDefault) + return false; + if (isShared != other.isShared) + return false; + if (isSystem != other.isSystem) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (netmask == null) { + if (other.netmask != null) + return false; + } else if (!netmask.equals(other.netmask)) + return false; + if (networkDomain == null) { + if (other.networkDomain != null) + return false; + } else if (!networkDomain.equals(other.networkDomain)) + return false; + if (networkOfferingAvailability == null) { + if (other.networkOfferingAvailability != null) + return false; + } else if (!networkOfferingAvailability.equals(other.networkOfferingAvailability)) + return false; + if (networkOfferingDisplayText == null) { + if (other.networkOfferingDisplayText != null) + return false; + } else if (!networkOfferingDisplayText.equals(other.networkOfferingDisplayText)) + return false; + if (networkOfferingId != other.networkOfferingId) + return false; + if (networkOfferingName == null) { + if (other.networkOfferingName != null) + return false; + } else if (!networkOfferingName.equals(other.networkOfferingName)) + return false; + if (related == null) { + if (other.related != null) + return false; + } else if (!related.equals(other.related)) + return false; + if (services == null) { + if (other.services != null) + return false; + } else if (!services.equals(other.services)) + return false; + if (startIP == null) { + if (other.startIP != null) + return false; + } else if (!startIP.equals(other.startIP)) + return false; + if (state == null) { + if (other.state != null) + return false; + } else if (!state.equals(other.state)) + return false; + if (trafficType != other.trafficType) + return false; + if (zoneId != other.zoneId) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", state=" + state + ", name=" + name + ", displayText=" + displayText + ", guestIPType=" + + guestIPType + ", trafficType=" + trafficType + ", DNS=" + getDNS() + ", VLAN=" + VLAN + ", account=" + + account + ", startIP=" + startIP + ", endIP=" + endIP + ", netmask=" + netmask + ", gateway=" + gateway + + ", broadcastDomainType=" + broadcastDomainType + ", broadcastURI=" + broadcastURI + ", services=" + + services + ", domain=" + domain + ", domainId=" + domainId + ", isDefault=" + isDefault + ", isShared=" + + isShared + ", isSystem=" + isSystem + ", related=" + related + ", zoneId=" + zoneId + ", networkDomain=" + + networkDomain + ", networkOfferingAvailability=" + networkOfferingAvailability + + ", networkOfferingDisplayText=" + networkOfferingDisplayText + ", networkOfferingId=" + networkOfferingId + + ", networkOfferingName=" + networkOfferingName + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkOffering.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkOffering.java new file mode 100644 index 0000000000..78e49d3f16 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkOffering.java @@ -0,0 +1,233 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import java.util.Date; +import java.util.Set; + +import javax.annotation.Nullable; + +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class NetworkOffering { + private long id; + private String name; + @SerializedName("displaytext") + private String displayText; + private Date created; + private String availability; + @SerializedName("maxconnections") + private Integer maxConnections; + @SerializedName("isdefault") + private boolean isDefault; + @SerializedName("specifyvlan") + private boolean supportsVLAN; + @SerializedName("traffictype") + private TrafficType trafficType; + private String tags; + + public NetworkOffering(long id, String name, String displayText, @Nullable Date created, String availability, + boolean supportsVLAN, @Nullable Integer maxConnections, boolean isDefault, TrafficType trafficType, + Set tags) { + this.id = id; + this.name = name; + this.displayText = displayText; + this.created = created; + this.availability = availability; + this.supportsVLAN = supportsVLAN; + this.maxConnections = maxConnections; + this.isDefault = isDefault; + this.trafficType = trafficType; + this.tags = Joiner.on(',').join(tags); + } + + /** + * present only for serializer + * + */ + NetworkOffering() { + + } + + /** + * + * @return the id of the network offering + */ + public long getId() { + return id; + } + + /** + * + * @return the name of the network offering + */ + + public String getName() { + return name; + } + + /** + * + * @return an alternate display text of the network offering. + */ + public String getDisplayText() { + return displayText; + } + + /** + * + * @return the date this network offering was created + */ + @Nullable + public Date getCreated() { + return created; + } + + /** + * + * @return Availability name for the offering + */ + public String getAvailability() { + return availability; + } + + /** + * + * @return true if network offering supports vlans, false otherwise + */ + public boolean supportsVLAN() { + return supportsVLAN; + } + + /** + * + * @return the max number of concurrent connection the network offering supports + */ + @Nullable + public Integer getMaxConnections() { + return maxConnections; + } + + /** + * + * @return true if network offering is default, false otherwise + */ + public boolean isDefault() { + return isDefault; + } + + /** + * + * @return the traffic type for this network offering + */ + public TrafficType getTrafficType() { + return trafficType; + } + + /** + * + * @return the tags for the network offering + */ + public Set getTags() { + return tags != null ? ImmutableSet.copyOf(Splitter.on(',').split(tags)) : ImmutableSet. of(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((availability == null) ? 0 : availability.hashCode()); + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + ((displayText == null) ? 0 : displayText.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + (isDefault ? 1231 : 1237); + result = prime * result + ((maxConnections == null) ? 0 : maxConnections.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + (supportsVLAN ? 1231 : 1237); + result = prime * result + ((tags == null) ? 0 : tags.hashCode()); + result = prime * result + ((trafficType == null) ? 0 : trafficType.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; + NetworkOffering other = (NetworkOffering) obj; + if (availability == null) { + if (other.availability != null) + return false; + } else if (!availability.equals(other.availability)) + return false; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (displayText == null) { + if (other.displayText != null) + return false; + } else if (!displayText.equals(other.displayText)) + return false; + if (id != other.id) + return false; + if (isDefault != other.isDefault) + return false; + if (maxConnections == null) { + if (other.maxConnections != null) + return false; + } else if (!maxConnections.equals(other.maxConnections)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (supportsVLAN != other.supportsVLAN) + return false; + if (tags == null) { + if (other.tags != null) + return false; + } else if (!tags.equals(other.tags)) + return false; + if (trafficType != other.trafficType) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", name=" + name + ", displayText=" + displayText + ", created=" + created + + ", maxConnections=" + maxConnections + ", trafficType=" + trafficType + ", isDefault=" + isDefault + + ", availability=" + availability + ", supportsVLAN=" + supportsVLAN + ", tags=" + tags + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkService.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkService.java new file mode 100644 index 0000000000..a1c4e6079e --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkService.java @@ -0,0 +1,150 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Set; + +import com.google.common.collect.ImmutableSet; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class NetworkService { + public static class Capability { + + private String name; + private String value; + + Capability() { + + } + + public Capability(String name, String value) { + this.name = checkNotNull(name, "name"); + this.value = checkNotNull(value, "value"); + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((value == null) ? 0 : value.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; + NetworkService.Capability other = (NetworkService.Capability) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + + @Override + public String toString() { + return "[name=" + name + ", value=" + value + "]"; + } + + } + + private String name; + @SerializedName("capability") + private Set capabilities = ImmutableSet.of(); + + NetworkService() { + + } + + public NetworkService(String name, Set capabilities) { + this.name = checkNotNull(name, "name"); + this.capabilities = ImmutableSet.copyOf(checkNotNull(capabilities, "capabilities")); + } + + public String getName() { + return name; + } + + public Set getCapabilities() { + return capabilities; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode()); + result = prime * result + ((name == null) ? 0 : name.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; + NetworkService other = (NetworkService) obj; + if (capabilities == null) { + if (other.capabilities != null) + return false; + } else if (!capabilities.equals(other.capabilities)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "[name=" + name + ", capabilities=" + capabilities + "]"; + } +} \ No newline at end of file diff --git a/sandbox-apis/libvirt/src/main/java/org/jclouds/libvirt/Datacenter.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java similarity index 57% rename from sandbox-apis/libvirt/src/main/java/org/jclouds/libvirt/Datacenter.java rename to sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java index ee0042e445..2be5914dd8 100644 --- a/sandbox-apis/libvirt/src/main/java/org/jclouds/libvirt/Datacenter.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkType.java @@ -17,40 +17,36 @@ * ==================================================================== */ -package org.jclouds.libvirt; +package org.jclouds.cloudstack.domain; -import com.google.common.base.Objects; +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.cloudstack.features.TemplateClient; + +import com.google.common.base.CaseFormat; /** - * This would be replaced with the real java object related to the underlying data center * * @author Adrian Cole + * @see TemplateClient#listZones */ -public class Datacenter { +public enum NetworkType { + BASIC, - public int id; - public String name; + ADVANCED, - public Datacenter(int id, String name) { - this.id = id; - this.name = name; - } - - @Override - public int hashCode() { - return Objects.hashCode(id, name); - } - - @Override - public boolean equals(Object that) { - if (that == null) - return false; - return Objects.equal(this.toString(), that.toString()); - } + UNRECOGNIZED; @Override public String toString() { - return Objects.toStringHelper(this).add("id", id).add("name", name).toString(); + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); } + public static NetworkType fromValue(String type) { + try { + return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } } diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/SecurityGroup.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/SecurityGroup.java new file mode 100644 index 0000000000..2883998d33 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/SecurityGroup.java @@ -0,0 +1,181 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Set; + +import com.google.common.collect.ImmutableSet; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class SecurityGroup { + private long id; + private String account; + private String name; + private String description; + private String domain; + @SerializedName("domainid") + private long domainId; + @SerializedName("ingressrule") + private Set ingressRules = ImmutableSet.of(); + + public SecurityGroup(long id, String account, String name, String description, String domain, long domainId, + Set ingressRules) { + this.id = id; + this.account = account; + this.name = name; + this.description = description; + this.domain = domain; + this.domainId = domainId; + this.ingressRules = ImmutableSet.copyOf(checkNotNull(ingressRules, "ingressRules")); + } + + /** + * present only for serializer + * + */ + SecurityGroup() { + + } + + /** + * + * @return the id of the security group + */ + public long getId() { + return id; + } + + /** + * + * @return the name of the security group + */ + + public String getName() { + return name; + } + + /** + * + * @return an alternate display text of the security group. + */ + public String getDescription() { + return description; + } + + /** + * + * @return Domain name for the security group + */ + public String getDomain() { + return domain; + } + + /** + * + * @return the domain id of the security group + */ + public long getDomainId() { + return domainId; + } + + /** + * + * @return the account owning the security group + */ + public String getAccount() { + return account; + } + + /** + * + * @return the list of ingress rules associated with the security group + */ + public Set getIngressRules() { + return ingressRules; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((account == null) ? 0 : account.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + (int) (domainId ^ (domainId >>> 32)); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((ingressRules == null) ? 0 : ingressRules.hashCode()); + result = prime * result + ((name == null) ? 0 : name.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; + SecurityGroup other = (SecurityGroup) obj; + if (account == null) { + if (other.account != null) + return false; + } else if (!account.equals(other.account)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (domain == null) { + if (other.domain != null) + return false; + } else if (!domain.equals(other.domain)) + return false; + if (domainId != other.domainId) + return false; + if (id != other.id) + return false; + if (ingressRules == null) { + if (other.ingressRules != null) + return false; + } else if (!ingressRules.equals(other.ingressRules)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", account=" + account + ", name=" + name + ", description=" + description + ", domain=" + + domain + ", domainId=" + domainId + ", ingressRules=" + ingressRules + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/ServiceOffering.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/ServiceOffering.java new file mode 100644 index 0000000000..48a98bfe4c --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/ServiceOffering.java @@ -0,0 +1,252 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import java.util.Date; +import java.util.Set; + +import com.google.common.base.Joiner; +import com.google.common.base.Splitter; +import com.google.common.collect.ImmutableSet; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class ServiceOffering { + private long id; + private String name; + @SerializedName("displaytext") + private String displayText; + private Date created; + private String domain; + @SerializedName("domainid") + private long domainId; + @SerializedName("cpunumber") + private int cpuNumber; + @SerializedName("cpuspeed") + private int cpuSpeed; + private int memory; + @SerializedName("offerha") + private boolean haSupport; + @SerializedName("storagetype") + private StorageType storageType; + private String tags; + + public ServiceOffering(long id, String name, String displayText, Date created, String domain, long domainId, + int cpuNumber, int cpuSpeed, int memory, boolean haSupport, StorageType storageType, Set tags) { + this.id = id; + this.name = name; + this.displayText = displayText; + this.created = created; + this.domain = domain; + this.domainId = domainId; + this.cpuNumber = cpuNumber; + this.cpuSpeed = cpuSpeed; + this.memory = memory; + this.haSupport = haSupport; + this.storageType = storageType; + this.tags = Joiner.on(',').join(tags); + } + + /** + * present only for serializer + * + */ + ServiceOffering() { + + } + + /** + * + * @return the id of the service offering + */ + public long getId() { + return id; + } + + /** + * + * @return the name of the service offering + */ + + public String getName() { + return name; + } + + /** + * + * @return an alternate display text of the service offering. + */ + public String getDisplayText() { + return displayText; + } + + /** + * + * @return the date this service offering was created + */ + public Date getCreated() { + return created; + } + + /** + * + * @return Domain name for the offering + */ + public String getDomain() { + return domain; + } + + /** + * + * @return the domain id of the service offering + */ + public long getDomainId() { + return domainId; + } + + /** + * + * @return the number of CPU + */ + public int getCpuNumber() { + return cpuNumber; + } + + /** + * + * @return the clock rate CPU speed in Mhz + */ + public int getCpuSpeed() { + return cpuSpeed; + } + + /** + * + * @return the memory in MB + */ + public int getMemory() { + return memory; + } + + /** + * + * @return the ha support in the service offering + */ + public boolean supportsHA() { + return haSupport; + } + + /** + * + * @return the storage type for this service offering + */ + public StorageType getStorageType() { + return storageType; + } + + /** + * + * @return the tags for the service offering + */ + public Set getTags() { + return tags != null ? ImmutableSet.copyOf(Splitter.on(',').split(tags)) : ImmutableSet. of(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + cpuNumber; + result = prime * result + cpuSpeed; + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + ((displayText == null) ? 0 : displayText.hashCode()); + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + (int) (domainId ^ (domainId >>> 32)); + result = prime * result + (haSupport ? 1231 : 1237); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + memory; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((storageType == null) ? 0 : storageType.hashCode()); + result = prime * result + ((tags == null) ? 0 : tags.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; + ServiceOffering other = (ServiceOffering) obj; + if (cpuNumber != other.cpuNumber) + return false; + if (cpuSpeed != other.cpuSpeed) + return false; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (displayText == null) { + if (other.displayText != null) + return false; + } else if (!displayText.equals(other.displayText)) + return false; + if (domain == null) { + if (other.domain != null) + return false; + } else if (!domain.equals(other.domain)) + return false; + if (domainId != other.domainId) + return false; + if (haSupport != other.haSupport) + return false; + if (id != other.id) + return false; + if (memory != other.memory) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (storageType != other.storageType) + return false; + if (tags == null) { + if (other.tags != null) + return false; + } else if (!tags.equals(other.tags)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", name=" + name + ", displayText=" + displayText + ", created=" + created + ", cpuNumber=" + + cpuNumber + ", cpuSpeed=" + cpuSpeed + ", memory=" + memory + ", storageType=" + storageType + + ", haSupport=" + haSupport + ", domain=" + domain + ", domainId=" + domainId + ", tags=" + tags + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java new file mode 100644 index 0000000000..65897eaee9 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/StorageType.java @@ -0,0 +1,52 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import org.jclouds.cloudstack.features.OfferingClient; + +import com.google.common.base.CaseFormat; + +/** + * + * @author Adrian Cole + * @see OfferingClient#listServiceOfferings + */ +public enum StorageType { + LOCAL, + + SHARED, + + UNRECOGNIZED; + + @Override + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()); + } + + public static StorageType fromValue(String type) { + try { + return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Template.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Template.java new file mode 100644 index 0000000000..ed7f6ad0cb --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Template.java @@ -0,0 +1,517 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import java.util.Date; +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class Template { + + public enum Type { + + USER, BUILTIN, UNRECOGNIZED; + + public static Type fromValue(String type) { + try { + return valueOf(checkNotNull(type, "type")); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + } + + public enum Format { + + VHD, QCOW2, OVA, UNRECOGNIZED; + + public static Format fromValue(String format) { + try { + return valueOf(checkNotNull(format, "format")); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + } + + private long id; + @SerializedName("displaytext") + private String displayText; + private String domain; + @SerializedName("domainid") + private long domainId; + private String account; + @SerializedName("accountid") + private long accountId; + @SerializedName("zonename") + private String zone; + @SerializedName("zoneid") + private long zoneId; + @SerializedName("ostypename") + private String OSType; + @SerializedName("ostypeid") + private long OSTypeId; + private String name; + @SerializedName("templatetype") + private Type type; + private String status; + private Format format; + private String hypervisor; + private Long size; + private Date created; + private Date removed; + @SerializedName("crossZones") + private boolean crossZones; + @SerializedName("bootable") + private boolean bootable; + @SerializedName("isextractable") + private boolean extractable; + @SerializedName("isfeatured") + private boolean featured; + @SerializedName("ispublic") + private boolean ispublic; + @SerializedName("isready") + private boolean ready; + @SerializedName("passwordenabled") + private boolean passwordEnabled; + @Nullable + @SerializedName("jobid") + private Long jobId; + @SerializedName("jobstatus") + private String jobStatus; + + public Template(long id, String displayText, String domain, long domainId, String account, long accountId, + String zone, long zoneId, String oSType, long oSTypeId, String name, Type type, String status, + Format format, String hypervisor, Long size, Date created, Date removed, boolean crossZones, + boolean bootable, boolean extractable, boolean featured, boolean ispublic, boolean ready, + boolean passwordEnabled, Long jobId, String jobStatus) { + this.id = id; + this.displayText = displayText; + this.domain = domain; + this.domainId = domainId; + this.account = account; + this.accountId = accountId; + this.zone = zone; + this.zoneId = zoneId; + this.OSType = oSType; + this.OSTypeId = oSTypeId; + this.name = name; + this.type = type; + this.status = status; + this.format = format; + this.hypervisor = hypervisor; + this.size = size; + this.created = created; + this.removed = removed; + this.crossZones = crossZones; + this.bootable = bootable; + this.extractable = extractable; + this.featured = featured; + this.ispublic = ispublic; + this.ready = ready; + this.passwordEnabled = passwordEnabled; + this.jobId = jobId; + this.jobStatus = jobStatus; + } + + /** + * present only for serializer + * + */ + Template() { + + } + + /** + * + * @return Template id + */ + public long getId() { + return id; + } + + /** + * + * @return the display text of the template + */ + public String getDisplayText() { + return displayText; + } + + /** + * + * @return the name of the domain to which the template beLongs + */ + public String getDomain() { + return domain; + } + + /** + * + * @return the ID of the domain to which the template beLongs + */ + public long getDomainId() { + return domainId; + } + + /** + * + * @return the name of the account to which the template beLongs + */ + public String getAccount() { + return account; + } + + /** + * + * @return the ID of the account to which the template beLongs + */ + public long getAccountId() { + return accountId; + } + + /** + * + * @return the name of the zone to which the template beLongs + */ + public String getZone() { + return zone; + } + + /** + * + * @return the ID of the zone to which the template beLongs + */ + public long getZoneId() { + return zoneId; + } + + /** + * + * @return the name of the OS type to which the template beLongs + */ + public String getOSType() { + return OSType; + } + + /** + * + * @return the ID of the OS type to which the template beLongs + */ + public long getOSTypeId() { + return OSTypeId; + } + + /** + * + * @return Template name + */ + public String getName() { + return name; + } + + /** + * + * @return + */ + public String getStatus() { + return status; + } + + /** + * + * @return the format of the template. + */ + public Format getFormat() { + return format; + } + + /** + * + * @return the hypervisor on which the template runs + */ + public String getHypervisor() { + return hypervisor; + } + + /** + * + * @return the size of the template in kilobytes + */ + public Long getSize() { + return size; + } + + /** + * + * @return the type of the template + */ + public Type getType() { + return type; + } + + /** + * + * @return the date this template was created + */ + public Date getCreated() { + return created; + } + + /** + * + * @return the date this template was removed + */ + public Date getRemoved() { + return removed; + } + + /** + * + * @return true if the template is managed across all Zones, false otherwise + */ + public boolean isCrossZones() { + return crossZones; + } + + /** + * + * @return true if the ISO is bootable, false otherwise + */ + public boolean isBootable() { + return bootable; + } + + /** + * + * @return true if the template is extractable, false otherwise + */ + public boolean isExtractable() { + return extractable; + } + + /** + * + * @return true if this template is a featured template, false otherwise + */ + public boolean isFeatured() { + return featured; + } + + /** + * + * @return true if this template is a public template, false otherwise + */ + public boolean isPublic() { + return ispublic; + } + + /** + * + * @return true if the template is ready to be deployed from, false otherwise + */ + public boolean isReady() { + return ready; + } + + /** + * + * @return true if the reset password feature is enabled, false otherwise + */ + public boolean isPasswordEnabled() { + return passwordEnabled; + } + + /** + * + * @return shows the current pending asynchronous job ID, or null if current pending jobs are + * acting on the template + */ + @Nullable + public Long getJobId() { + return jobId; + } + + /** + * + * @return shows the current pending asynchronous job status + */ + public String getJobStatus() { + return jobStatus; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((OSType == null) ? 0 : OSType.hashCode()); + result = prime * result + (int) (OSTypeId ^ (OSTypeId >>> 32)); + result = prime * result + ((account == null) ? 0 : account.hashCode()); + result = prime * result + (int) (accountId ^ (accountId >>> 32)); + result = prime * result + (bootable ? 1231 : 1237); + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + (crossZones ? 1231 : 1237); + result = prime * result + ((displayText == null) ? 0 : displayText.hashCode()); + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + (int) (domainId ^ (domainId >>> 32)); + result = prime * result + (extractable ? 1231 : 1237); + result = prime * result + (featured ? 1231 : 1237); + result = prime * result + ((format == null) ? 0 : format.hashCode()); + result = prime * result + ((hypervisor == null) ? 0 : hypervisor.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + (ispublic ? 1231 : 1237); + result = prime * result + ((jobId == null) ? 0 : jobId.hashCode()); + result = prime * result + ((jobStatus == null) ? 0 : jobStatus.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + (passwordEnabled ? 1231 : 1237); + result = prime * result + (ready ? 1231 : 1237); + result = prime * result + ((removed == null) ? 0 : removed.hashCode()); + result = prime * result + ((size == null) ? 0 : size.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((zone == null) ? 0 : zone.hashCode()); + result = prime * result + (int) (zoneId ^ (zoneId >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Template other = (Template) obj; + if (OSType == null) { + if (other.OSType != null) + return false; + } else if (!OSType.equals(other.OSType)) + return false; + if (OSTypeId != other.OSTypeId) + return false; + if (account == null) { + if (other.account != null) + return false; + } else if (!account.equals(other.account)) + return false; + if (accountId != other.accountId) + return false; + if (bootable != other.bootable) + return false; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (crossZones != other.crossZones) + return false; + if (displayText == null) { + if (other.displayText != null) + return false; + } else if (!displayText.equals(other.displayText)) + return false; + if (domain == null) { + if (other.domain != null) + return false; + } else if (!domain.equals(other.domain)) + return false; + if (domainId != other.domainId) + return false; + if (extractable != other.extractable) + return false; + if (featured != other.featured) + return false; + if (format != other.format) + return false; + if (hypervisor == null) { + if (other.hypervisor != null) + return false; + } else if (!hypervisor.equals(other.hypervisor)) + return false; + if (id != other.id) + return false; + if (ispublic != other.ispublic) + return false; + if (jobId == null) { + if (other.jobId != null) + return false; + } else if (!jobId.equals(other.jobId)) + return false; + if (jobStatus == null) { + if (other.jobStatus != null) + return false; + } else if (!jobStatus.equals(other.jobStatus)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (passwordEnabled != other.passwordEnabled) + return false; + if (ready != other.ready) + return false; + if (removed == null) { + if (other.removed != null) + return false; + } else if (!removed.equals(other.removed)) + return false; + if (size == null) { + if (other.size != null) + return false; + } else if (!size.equals(other.size)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + if (type != other.type) + return false; + if (zone == null) { + if (other.zone != null) + return false; + } else if (!zone.equals(other.zone)) + return false; + if (zoneId != other.zoneId) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", name=" + name + ", displayText=" + displayText + ", format=" + format + ", type=" + type + + ", hypervisor=" + hypervisor + ", size=" + size + ", status=" + status + ", created=" + created + + ", removed=" + removed + ", OSType=" + OSType + ", OSTypeId=" + OSTypeId + ", account=" + account + + ", accountId=" + accountId + ", domain=" + domain + ", domainId=" + domainId + ", zone=" + zone + + ", zoneId=" + zoneId + ", ready=" + ready + ", bootable=" + bootable + ", crossZones=" + crossZones + + ", extractable=" + extractable + ", featured=" + featured + ", ispublic=" + ispublic + + ", passwordEnabled=" + passwordEnabled + ", jobId=" + jobId + ", jobStatus=" + jobStatus + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java new file mode 100644 index 0000000000..8d03221228 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TemplateFilter.java @@ -0,0 +1,57 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import org.jclouds.cloudstack.features.TemplateClient; + +import com.google.common.base.CaseFormat; + +/** + * + * @author Adrian Cole + * @see TemplateClient#listTemplates + */ +public enum TemplateFilter { + /** + * templates that are featured and are public + */ + FEATURED, + /** + * templates that have been registered/created by the owner + */ + SELF, + /** + * templates that have been registered/created by the owner that can be used to deploy a new VM + */ + SELF_EXECUTABLE, + /** + * all templates that can be used to deploy a new VM + */ + EXECUTABLE, + /** + * templates that are public + */ + COMMUNITY; + + @Override + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()); + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java new file mode 100644 index 0000000000..f19d5f3266 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/TrafficType.java @@ -0,0 +1,67 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.CaseFormat; + +/** + * + * @author Adrian Cole + * @see NetworkOfferingClient#listNetworkOfferings + */ +public enum TrafficType { + + /** + * traffic to the public internet + */ + PUBLIC, + /** + * VM-to-VM traffic and VMs are assigned a virtual IP created by CloudStack + */ + GUEST, + /** + * System network that only Admin can view, and only when isSystem is specified. + */ + STORAGE, + /** + * System network that only Admin can view, and only when isSystem is specified. + */ + MANAGEMENT, + /** + * System network that only Admin can view, and only when isSystem is specified. + */ + CONTROL, + + UNRECOGNIZED; + @Override + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); + } + + public static TrafficType fromValue(String type) { + try { + return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/VirtualMachine.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/VirtualMachine.java new file mode 100644 index 0000000000..a7ca285e32 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/VirtualMachine.java @@ -0,0 +1,711 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Date; +import java.util.Set; + +import javax.annotation.Nullable; + +import com.google.common.base.CaseFormat; +import com.google.common.collect.ImmutableSet; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class VirtualMachine { + public static enum State { + STARTING, RUNNING, STOPPING, STOPPED, DESTROYED, EXPUNGING, MIGRATING, ERROR, UNKNOWN, SHUTDOWNED, UNRECOGNIZED; + @Override + public String toString() { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()); + } + + public static State fromValue(String state) { + try { + return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(state, "state"))); + } catch (IllegalArgumentException e) { + return UNRECOGNIZED; + } + } + + } + + private long id; + private String account; + @SerializedName("cpunumber") + private long cpuCount; + @SerializedName("cpuspeed") + private long cpuSpeed; + @SerializedName("cpuused") + private String cpuUsed; + @SerializedName("displayname") + private String displayName; + private Date created; + private String domain; + @SerializedName("domainid") + private long domainId; + @SerializedName("forvirtualnetwork") + private boolean usesVirtualNetwork; + private String group; + @SerializedName("groupid") + private long groupId; + @SerializedName("guestosid") + private long guestOSId; + @SerializedName("haenable") + private boolean HAEnabled; + @SerializedName("hostid") + private long hostId; + private String hostname; + @SerializedName("ipaddress") + private String IPAddress; + @SerializedName("isodisplaytext") + private String ISODisplayText; + @SerializedName("isoid") + private long ISOId; + @SerializedName("isoname") + private String ISOName; + @SerializedName("jobid") + @Nullable + private Long jobId; + @SerializedName("jobstatus") + @Nullable + private String jobStatus; + private long memory; + private String name; + @SerializedName("networkkbsread") + private Long networkKbsRead; + @SerializedName("networkkbswrite") + private Long networkKbsWrite; + @Nullable + private String password; + @SerializedName("passwordenabled") + private boolean passwordEnabled; + @SerializedName("rootdeviceid") + private long rootDeviceId; + @SerializedName("rootdevicetype") + private String rootDeviceType; + @SerializedName("serviceofferingid") + private long serviceOfferingId; + @SerializedName("serviceofferingname") + private String serviceOfferingName; + private State state; + @SerializedName("templatedisplaytext") + private String templateDisplayText; + @SerializedName("templateid") + private long templateId; + @SerializedName("templatename") + private String templateName; + @SerializedName("zoneid") + private long zoneId; + @SerializedName("zonename") + private String zoneName; + @SerializedName("nic") + private Set nics = ImmutableSet. of(); + private String hypervisor; + @SerializedName("securitygroup") + private Set securityGroups = ImmutableSet. of(); + + public VirtualMachine(long id, String account, long cpuCount, long cpuSpeed, long cpuUsed, String displayName, + Date created, String domain, long domainId, boolean usesVirtualNetwork, String group, long groupId, + long guestOSId, boolean hAEnabled, long hostId, String hostname, String iPAddress, String iSODisplayText, + long iSOId, String iSOName, Long jobId, String jobStatus, long memory, String name, Long networkKbsRead, + Long networkKbsWrite, String password, boolean passwordEnabled, long rootDeviceId, String rootDeviceType, + Set securityGroups, long serviceOfferingId, String serviceOfferingName, State state, + String templateDisplayText, long templateId, String templateName, long zoneId, String zoneName, + Set nics, String hypervisor) { + this.id = id; + this.account = account; + this.cpuCount = cpuCount; + this.cpuSpeed = cpuSpeed; + this.cpuUsed = cpuUsed + ""; + this.displayName = displayName; + this.created = created; + this.domain = domain; + this.domainId = domainId; + this.usesVirtualNetwork = usesVirtualNetwork; + this.group = group; + this.groupId = groupId; + this.guestOSId = guestOSId; + this.HAEnabled = hAEnabled; + this.hostId = hostId; + this.hostname = hostname; + this.IPAddress = iPAddress; + this.ISODisplayText = iSODisplayText; + this.ISOId = iSOId; + this.ISOName = iSOName; + this.jobId = jobId; + this.jobStatus = jobStatus; + this.memory = memory; + this.name = name; + this.networkKbsRead = networkKbsRead; + this.networkKbsWrite = networkKbsWrite; + this.password = password; + this.passwordEnabled = passwordEnabled; + this.rootDeviceId = rootDeviceId; + this.rootDeviceType = rootDeviceType; + this.securityGroups =ImmutableSet.copyOf(checkNotNull(securityGroups, "securityGroups")); + this.serviceOfferingId = serviceOfferingId; + this.serviceOfferingName = serviceOfferingName; + this.state = state; + this.templateDisplayText = templateDisplayText; + this.templateId = templateId; + this.templateName = templateName; + this.zoneId = zoneId; + this.zoneName = zoneName; + this.nics = nics; + this.hypervisor = hypervisor; + } + + /** + * present only for serializer + * + */ + VirtualMachine() { + } + + /** + * @return the ID of the virtual machine + */ + public long getId() { + return id; + } + + /** + * @return the account associated with the virtual machine + */ + public String getAccount() { + return account; + } + + /** + * @return the number of cpu this virtual machine is running with + */ + public long getCpuCount() { + return cpuCount; + } + + /** + * @return the speed of each cpu + */ + public long getCpuSpeed() { + return cpuSpeed; + } + + /** + * @return the amount of the vm's CPU currently used + */ + public float getCpuUsed() { + return cpuUsed != null ? Float.parseFloat(cpuUsed.substring(9, cpuUsed.length() - 1)) : 0.0f; + } + + /** + * @return user generated name. The name of the virtual machine is returned if no displayname + * exists. + */ + public String getDisplayName() { + return displayName; + } + + /** + * @return the date when this virtual machine was created + */ + public Date getCreated() { + return created; + } + + /** + * @return the name of the domain in which the virtual machine exists + */ + public String getDomain() { + return domain; + } + + /** + * @return the ID of the domain in which the virtual machine exists + */ + public long getDomainId() { + return domainId; + } + + /** + * @return the virtual network for the service offering + */ + public boolean isUsesVirtualNetwork() { + return usesVirtualNetwork; + } + + /** + * @return the group name of the virtual machine + */ + public String getGroup() { + return group; + } + + /** + * @return the group ID of the virtual machine + */ + public long getGroupId() { + return groupId; + } + + /** + * @return Os type ID of the virtual machine + */ + public long getGuestOSId() { + return guestOSId; + } + + /** + * @return true if high-availability is enabled, false otherwise + */ + public boolean isHAEnabled() { + return HAEnabled; + } + + /** + * @return the ID of the host for the virtual machine + */ + public long getHostId() { + return hostId; + } + + /** + * @return the name of the host for the virtual machine + */ + public String getHostname() { + return hostname; + } + + /** + * @return the ip address of the virtual machine + */ + public String getIPAddress() { + return IPAddress; + } + + /** + * @return an alternate display text of the ISO attached to the virtual machine + */ + public String getISODisplayText() { + return ISODisplayText; + } + + /** + * @return the ID of the ISO attached to the virtual machine + */ + public long getISOId() { + return ISOId; + } + + /** + * @return the name of the ISO attached to the virtual machine + */ + public String getISOName() { + return ISOName; + } + + /** + * @return shows the current pending asynchronous job ID. This tag is not returned if no current + * pending jobs are acting on the virtual machine + */ + @Nullable + public Long getJobId() { + return jobId; + } + + /** + * @return shows the current pending asynchronous job status + */ + @Nullable + public String getJobStatus() { + return jobStatus; + } + + /** + * @return the memory allocated for the virtual machine + */ + public long getMemory() { + return memory; + } + + /** + * @return the name of the virtual machine + */ + public String getName() { + return name; + } + + /** + * @return the incoming network traffic on the vm + */ + public Long getNetworkKbsRead() { + return networkKbsRead; + } + + /** + * @return the outgoing network traffic on the host + */ + public Long getNetworkKbsWrite() { + return networkKbsWrite; + } + + /** + * @return the password (if exists) of the virtual machine + */ + @Nullable + public String getPassword() { + return password; + } + + /** + * @return true if the password rest feature is enabled, false otherwise + */ + public boolean isPasswordEnabled() { + return passwordEnabled; + } + + /** + * @return device ID of the root volume + */ + public long getRootDeviceId() { + return rootDeviceId; + } + + /** + * @return device type of the root volume + */ + public String getRootDeviceType() { + return rootDeviceType; + } + + /** + * @return list of security groups associated with the virtual machine + */ + public Set getSecurityGroups() { + return securityGroups; + } + + /** + * @return the ID of the service offering of the virtual machine + */ + public long getServiceOfferingId() { + return serviceOfferingId; + } + + /** + * @return the name of the service offering of the virtual machine + */ + public String getServiceOfferingName() { + return serviceOfferingName; + } + + /** + * @return the state of the virtual machine + */ + public State getState() { + return state; + } + + /** + * @return an alternate display text of the template for the virtual machine + */ + public String getTemplateDisplayText() { + return templateDisplayText; + } + + /** + * @return the ID of the template for the virtual machine. A -1 is returned if the virtual + * machine was created from an ISO file. + */ + public long getTemplateId() { + return templateId; + } + + /** + * @return the name of the template for the virtual machine + */ + public String getTemplateName() { + return templateName; + } + + /** + * @return the ID of the availablility zone for the virtual machine + */ + public long getZoneId() { + return zoneId; + } + + /** + * @return the name of the availability zone for the virtual machine + */ + public String getZoneName() { + return zoneName; + } + + /** + * @return the list of nics associated with vm + */ + public Set getNICs() { + return nics; + } + + /** + * @return type of the hypervisor + */ + public String getHypervisor() { + return hypervisor; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (HAEnabled ? 1231 : 1237); + result = prime * result + ((IPAddress == null) ? 0 : IPAddress.hashCode()); + result = prime * result + ((ISODisplayText == null) ? 0 : ISODisplayText.hashCode()); + result = prime * result + (int) (ISOId ^ (ISOId >>> 32)); + result = prime * result + ((ISOName == null) ? 0 : ISOName.hashCode()); + result = prime * result + ((account == null) ? 0 : account.hashCode()); + result = prime * result + (int) (cpuCount ^ (cpuCount >>> 32)); + result = prime * result + (int) (cpuSpeed ^ (cpuSpeed >>> 32)); + result = prime * result + ((cpuUsed == null) ? 0 : cpuUsed.hashCode()); + result = prime * result + ((created == null) ? 0 : created.hashCode()); + result = prime * result + ((displayName == null) ? 0 : displayName.hashCode()); + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + (int) (domainId ^ (domainId >>> 32)); + result = prime * result + ((group == null) ? 0 : group.hashCode()); + result = prime * result + (int) (groupId ^ (groupId >>> 32)); + result = prime * result + (int) (guestOSId ^ (guestOSId >>> 32)); + result = prime * result + (int) (hostId ^ (hostId >>> 32)); + result = prime * result + ((hostname == null) ? 0 : hostname.hashCode()); + result = prime * result + ((hypervisor == null) ? 0 : hypervisor.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((jobId == null) ? 0 : jobId.hashCode()); + result = prime * result + ((jobStatus == null) ? 0 : jobStatus.hashCode()); + result = prime * result + (int) (memory ^ (memory >>> 32)); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((networkKbsRead == null) ? 0 : networkKbsRead.hashCode()); + result = prime * result + ((networkKbsWrite == null) ? 0 : networkKbsWrite.hashCode()); + result = prime * result + ((nics == null) ? 0 : nics.hashCode()); + result = prime * result + ((password == null) ? 0 : password.hashCode()); + result = prime * result + (passwordEnabled ? 1231 : 1237); + result = prime * result + (int) (rootDeviceId ^ (rootDeviceId >>> 32)); + result = prime * result + ((rootDeviceType == null) ? 0 : rootDeviceType.hashCode()); + result = prime * result + ((securityGroups == null) ? 0 : securityGroups.hashCode()); + result = prime * result + (int) (serviceOfferingId ^ (serviceOfferingId >>> 32)); + result = prime * result + ((serviceOfferingName == null) ? 0 : serviceOfferingName.hashCode()); + result = prime * result + ((state == null) ? 0 : state.hashCode()); + result = prime * result + ((templateDisplayText == null) ? 0 : templateDisplayText.hashCode()); + result = prime * result + (int) (templateId ^ (templateId >>> 32)); + result = prime * result + ((templateName == null) ? 0 : templateName.hashCode()); + result = prime * result + (usesVirtualNetwork ? 1231 : 1237); + result = prime * result + (int) (zoneId ^ (zoneId >>> 32)); + result = prime * result + ((zoneName == null) ? 0 : zoneName.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; + VirtualMachine other = (VirtualMachine) obj; + if (HAEnabled != other.HAEnabled) + return false; + if (IPAddress == null) { + if (other.IPAddress != null) + return false; + } else if (!IPAddress.equals(other.IPAddress)) + return false; + if (ISODisplayText == null) { + if (other.ISODisplayText != null) + return false; + } else if (!ISODisplayText.equals(other.ISODisplayText)) + return false; + if (ISOId != other.ISOId) + return false; + if (ISOName == null) { + if (other.ISOName != null) + return false; + } else if (!ISOName.equals(other.ISOName)) + return false; + if (account == null) { + if (other.account != null) + return false; + } else if (!account.equals(other.account)) + return false; + if (cpuCount != other.cpuCount) + return false; + if (cpuSpeed != other.cpuSpeed) + return false; + if (cpuUsed == null) { + if (other.cpuUsed != null) + return false; + } else if (!cpuUsed.equals(other.cpuUsed)) + return false; + if (created == null) { + if (other.created != null) + return false; + } else if (!created.equals(other.created)) + return false; + if (displayName == null) { + if (other.displayName != null) + return false; + } else if (!displayName.equals(other.displayName)) + return false; + if (domain == null) { + if (other.domain != null) + return false; + } else if (!domain.equals(other.domain)) + return false; + if (domainId != other.domainId) + return false; + if (group == null) { + if (other.group != null) + return false; + } else if (!group.equals(other.group)) + return false; + if (groupId != other.groupId) + return false; + if (guestOSId != other.guestOSId) + return false; + if (hostId != other.hostId) + return false; + if (hostname == null) { + if (other.hostname != null) + return false; + } else if (!hostname.equals(other.hostname)) + return false; + if (hypervisor == null) { + if (other.hypervisor != null) + return false; + } else if (!hypervisor.equals(other.hypervisor)) + return false; + if (id != other.id) + return false; + if (jobId == null) { + if (other.jobId != null) + return false; + } else if (!jobId.equals(other.jobId)) + return false; + if (jobStatus == null) { + if (other.jobStatus != null) + return false; + } else if (!jobStatus.equals(other.jobStatus)) + return false; + if (memory != other.memory) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (networkKbsRead == null) { + if (other.networkKbsRead != null) + return false; + } else if (!networkKbsRead.equals(other.networkKbsRead)) + return false; + if (networkKbsWrite == null) { + if (other.networkKbsWrite != null) + return false; + } else if (!networkKbsWrite.equals(other.networkKbsWrite)) + return false; + if (nics == null) { + if (other.nics != null) + return false; + } else if (!nics.equals(other.nics)) + return false; + if (password == null) { + if (other.password != null) + return false; + } else if (!password.equals(other.password)) + return false; + if (passwordEnabled != other.passwordEnabled) + return false; + if (rootDeviceId != other.rootDeviceId) + return false; + if (rootDeviceType == null) { + if (other.rootDeviceType != null) + return false; + } else if (!rootDeviceType.equals(other.rootDeviceType)) + return false; + if (securityGroups == null) { + if (other.securityGroups != null) + return false; + } else if (!securityGroups.equals(other.securityGroups)) + return false; + if (serviceOfferingId != other.serviceOfferingId) + return false; + if (serviceOfferingName == null) { + if (other.serviceOfferingName != null) + return false; + } else if (!serviceOfferingName.equals(other.serviceOfferingName)) + return false; + if (state != other.state) + return false; + if (templateDisplayText == null) { + if (other.templateDisplayText != null) + return false; + } else if (!templateDisplayText.equals(other.templateDisplayText)) + return false; + if (templateId != other.templateId) + return false; + if (templateName == null) { + if (other.templateName != null) + return false; + } else if (!templateName.equals(other.templateName)) + return false; + if (usesVirtualNetwork != other.usesVirtualNetwork) + return false; + if (zoneId != other.zoneId) + return false; + if (zoneName == null) { + if (other.zoneName != null) + return false; + } else if (!zoneName.equals(other.zoneName)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", account=" + account + ", cpuCount=" + cpuCount + ", cpuSpeed=" + cpuSpeed + ", cpuUsed=" + + cpuUsed + ", displayName=" + displayName + ", created=" + created + ", domain=" + domain + ", domainId=" + + domainId + ", usesVirtualNetwork=" + usesVirtualNetwork + ", group=" + group + ", groupId=" + groupId + + ", guestOSId=" + guestOSId + ", HAEnabled=" + HAEnabled + ", hostId=" + hostId + ", hostname=" + hostname + + ", IPAddress=" + IPAddress + ", ISODisplayText=" + ISODisplayText + ", ISOId=" + ISOId + ", ISOName=" + + ISOName + ", jobId=" + jobId + ", jobStatus=" + jobStatus + ", memory=" + memory + ", name=" + name + + ", networkKbsRead=" + networkKbsRead + ", networkKbsWrite=" + networkKbsWrite + ", password=" + password + + ", passwordEnabled=" + passwordEnabled + ", rootDeviceId=" + rootDeviceId + ", rootDeviceType=" + + rootDeviceType + ", securityGroups=" + securityGroups + ", serviceOfferingId=" + serviceOfferingId + + ", serviceOfferingName=" + serviceOfferingName + ", state=" + state + ", templateDisplayText=" + + templateDisplayText + ", templateId=" + templateId + ", templateName=" + templateName + ", zoneId=" + + zoneId + ", zoneName=" + zoneName + ", nics=" + nics + ", hypervisor=" + hypervisor + "]"; + } + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Zone.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Zone.java new file mode 100644 index 0000000000..bd0b02314d --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/Zone.java @@ -0,0 +1,297 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.domain; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; + +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; +import com.google.gson.annotations.SerializedName; + +/** + * + * @author Adrian Cole + */ +public class Zone { + private long id; + private String description; + @SerializedName("displaytext") + private String displayText; + @SerializedName("dns1") + private String DNS1; + @SerializedName("dns2") + private String DNS2; + private String domain; + @Nullable + @SerializedName("domainid") + private long domainId; + @SerializedName("guestcidraddress") + private String guestCIDRAddress; + @SerializedName("internaldns1") + private String internalDNS1; + @SerializedName("internaldns2") + private String internalDNS2; + private String name; + @SerializedName("networktype") + private NetworkType networkType; + private String status; + @SerializedName("vlan") + private String VLAN; + + /** + * present only for serializer + * + */ + Zone() { + + } + + public Zone(long id, String description, String displayText, List DNS, String domain, long domainId, + String guestCIDRAddress, List internalDNS, String name, NetworkType networkType, String status, + String vLAN) { + this.id = id; + this.description = description; + this.displayText = displayText; + this.DNS1 = checkNotNull(DNS, "DNS").size() > 0 ? DNS.get(0) : null; + this.DNS2 = DNS.size() > 1 ? DNS.get(1) : null; + this.domain = domain; + this.domainId = domainId; + this.guestCIDRAddress = guestCIDRAddress; + this.internalDNS1 = checkNotNull(internalDNS, "internalDNS").size() > 0 ? internalDNS.get(0) : null; + this.internalDNS2 = internalDNS.size() > 1 ? internalDNS.get(1) : null; + this.name = name; + this.networkType = networkType; + this.status = status; + this.VLAN = vLAN; + } + + /** + * + * @return Zone id + */ + public long getId() { + return id; + } + + /** + * + * @return Zone description + */ + public String getDescription() { + return description; + } + + /** + * + * @return the display text of the zone + */ + public String getDisplayText() { + return displayText; + } + + /** + * + * @return the external DNS for the Zone + */ + public List getDNS() { + Builder builder = ImmutableList.builder(); + if (DNS1 != null && !"".equals(DNS1)) + builder.add(DNS1); + if (DNS2 != null && !"".equals(DNS2)) + builder.add(DNS2); + return builder.build(); + } + + /** + * + * @return Domain name for the Vms in the zone + */ + public String getDomain() { + return domain; + } + + /** + * + * @return the ID of the containing domain, null for public zones + */ + @Nullable + public long getDomainId() { + return domainId; + } + + /** + * + * @return the guest CIDR address for the Zone + */ + public String getGuestCIDRAddress() { + return guestCIDRAddress; + } + + /** + * + * @return the internal DNS for the Zone + */ + public List getInternalDNS() { + Builder builder = ImmutableList.builder(); + if (internalDNS1 != null && !"".equals(internalDNS1)) + builder.add(internalDNS1); + if (internalDNS2 != null && !"".equals(internalDNS2)) + builder.add(internalDNS2); + return builder.build(); + } + + /** + * + * @return Zone name + */ + public String getName() { + return name; + } + + /** + * + * @return the network type of the zone; can be Basic or Advanced + */ + public NetworkType getNetworkType() { + return networkType; + } + + /** + * + * @return + */ + public String getStatus() { + return status; + } + + /** + * + * @return the vlan range of the zone + */ + public String getVLAN() { + return VLAN; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((DNS1 == null) ? 0 : DNS1.hashCode()); + result = prime * result + ((DNS2 == null) ? 0 : DNS2.hashCode()); + result = prime * result + ((VLAN == null) ? 0 : VLAN.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((displayText == null) ? 0 : displayText.hashCode()); + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + (int) (domainId ^ (domainId >>> 32)); + result = prime * result + ((guestCIDRAddress == null) ? 0 : guestCIDRAddress.hashCode()); + result = prime * result + (int) (id ^ (id >>> 32)); + result = prime * result + ((internalDNS1 == null) ? 0 : internalDNS1.hashCode()); + result = prime * result + ((internalDNS2 == null) ? 0 : internalDNS2.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((networkType == null) ? 0 : networkType.hashCode()); + result = prime * result + ((status == null) ? 0 : status.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; + Zone other = (Zone) obj; + if (DNS1 == null) { + if (other.DNS1 != null) + return false; + } else if (!DNS1.equals(other.DNS1)) + return false; + if (DNS2 == null) { + if (other.DNS2 != null) + return false; + } else if (!DNS2.equals(other.DNS2)) + return false; + if (VLAN == null) { + if (other.VLAN != null) + return false; + } else if (!VLAN.equals(other.VLAN)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (displayText == null) { + if (other.displayText != null) + return false; + } else if (!displayText.equals(other.displayText)) + return false; + if (domain == null) { + if (other.domain != null) + return false; + } else if (!domain.equals(other.domain)) + return false; + if (domainId != other.domainId) + return false; + if (guestCIDRAddress == null) { + if (other.guestCIDRAddress != null) + return false; + } else if (!guestCIDRAddress.equals(other.guestCIDRAddress)) + return false; + if (id != other.id) + return false; + if (internalDNS1 == null) { + if (other.internalDNS1 != null) + return false; + } else if (!internalDNS1.equals(other.internalDNS1)) + return false; + if (internalDNS2 == null) { + if (other.internalDNS2 != null) + return false; + } else if (!internalDNS2.equals(other.internalDNS2)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (networkType != other.networkType) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + id + ", status=" + status + ", name=" + name + ", description=" + description + ", displayText=" + + displayText + ", domain=" + domain + ", domainId=" + domainId + ", networkType=" + networkType + + ", guestCIDRAddress=" + guestCIDRAddress + ", VLAN=" + VLAN + ", DNS=" + getDNS() + ", internalDNS=" + + getInternalDNS() + "]"; + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobAsyncClient.java new file mode 100644 index 0000000000..2640177d25 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobAsyncClient.java @@ -0,0 +1,73 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.cloudstack.domain.AsyncJob; +import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.cloudstack.options.ListAsyncJobsOptions; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.Unwrap; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to cloudstack via their REST API. + *

+ * + * @see AsyncJobClient + * @see + * @author Adrian Cole + */ +@RequestFilters(QuerySigner.class) +@QueryParams(keys = "response", values = "json") +public interface AsyncJobAsyncClient { + + /** + * @see AsyncJobClient#listAsyncJobs + */ + @GET + @QueryParams(keys = "command", values = "listAsyncJobs") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listAsyncJobs(ListAsyncJobsOptions... options); + + /** + * @see AsyncJobClient#getAsyncJob + */ + @GET + @QueryParams(keys = "command", values = "queryAsyncJobResult") + @Unwrap + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getAsyncJob(@QueryParam("jobid") long id); + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobClient.java new file mode 100644 index 0000000000..5c197bdf21 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AsyncJobClient.java @@ -0,0 +1,56 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.cloudstack.domain.AsyncJob; +import org.jclouds.cloudstack.options.ListAsyncJobsOptions; +import org.jclouds.concurrent.Timeout; + +/** + * Provides synchronous access to CloudStack asyncJob features. + *

+ * + * @see AsyncJobAsyncClient + * @see + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface AsyncJobClient { + /** + * Lists asyncJobs + * + * @param options + * if present, how to constrain the list. + * @return asyncJobs matching query, or empty set, if no asyncJobs are found + */ + Set listAsyncJobs(ListAsyncJobsOptions... options); + + /** + * get a specific asyncJob by id + * + * @param id + * asyncJob to get + * @return asyncJob or null if not found + */ + AsyncJob getAsyncJob(long id); +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkAsyncClient.java new file mode 100644 index 0000000000..060df493c6 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkAsyncClient.java @@ -0,0 +1,73 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.cloudstack.domain.Network; +import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.cloudstack.options.ListNetworksOptions; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.Unwrap; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to cloudstack via their REST API. + *

+ * + * @see NetworkClient + * @see + * @author Adrian Cole + */ +@RequestFilters(QuerySigner.class) +@QueryParams(keys = "response", values = "json") +public interface NetworkAsyncClient { + + /** + * @see NetworkClient#listNetworks + */ + @GET + @QueryParams(keys = "command", values = "listNetworks") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listNetworks(ListNetworksOptions... options); + + /** + * @see NetworkClient#getNetwork + */ + @GET + @QueryParams(keys = "command", values = "listNetworks") + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getNetwork(@QueryParam("id") long id); + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkClient.java new file mode 100644 index 0000000000..eb2d31e56f --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkClient.java @@ -0,0 +1,57 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.cloudstack.domain.Network; +import org.jclouds.cloudstack.options.ListNetworksOptions; +import org.jclouds.concurrent.Timeout; + +/** + * Provides synchronous access to CloudStack network features. + *

+ * + * @see NetworkAsyncClient + * @see + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface NetworkClient { + /** + * Lists networks + * + * @param options + * if present, how to constrain the list. + * @return networks matching query, or empty set, if no networks are found + */ + Set listNetworks(ListNetworksOptions... options); + + /** + * get a specific network by id + * + * @param id + * network to get + * @return network or null if not found + */ + Network getNetwork(long id); + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/OfferingAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/OfferingAsyncClient.java new file mode 100644 index 0000000000..492b57334a --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/OfferingAsyncClient.java @@ -0,0 +1,117 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.cloudstack.domain.DiskOffering; +import org.jclouds.cloudstack.domain.NetworkOffering; +import org.jclouds.cloudstack.domain.ServiceOffering; +import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.cloudstack.options.ListDiskOfferingsOptions; +import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions; +import org.jclouds.cloudstack.options.ListServiceOfferingsOptions; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.Unwrap; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to cloudstack via their REST API. + *

+ * + * @see OfferingClient + * @see + * @author Adrian Cole + */ +@RequestFilters(QuerySigner.class) +@QueryParams(keys = "response", values = "json") +public interface OfferingAsyncClient { + + /** + * @see OfferingClient#listServiceOfferings + */ + @GET + @QueryParams(keys = "command", values = "listServiceOfferings") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listServiceOfferings(ListServiceOfferingsOptions... options); + + /** + * @see OfferingClient#getServiceOffering + */ + @GET + @QueryParams(keys = "command", values = "listServiceOfferings") + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getServiceOffering(@QueryParam("id") long id); + + /** + * @see OfferingClient#listDiskOfferings + */ + @GET + @QueryParams(keys = "command", values = "listDiskOfferings") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listDiskOfferings(ListDiskOfferingsOptions... options); + + /** + * @see OfferingClient#getDiskOffering + */ + @GET + @QueryParams(keys = "command", values = "listDiskOfferings") + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getDiskOffering(@QueryParam("id") long id); + + /** + * @see NetworkOfferingClient#listNetworkOfferings + */ + @GET + @QueryParams(keys = "command", values = "listNetworkOfferings") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listNetworkOfferings(ListNetworkOfferingsOptions... options); + + /** + * @see NetworkOfferingClient#getNetworkOffering + */ + @GET + @QueryParams(keys = "command", values = "listNetworkOfferings") + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getNetworkOffering(@QueryParam("id") long id); + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/OfferingClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/OfferingClient.java new file mode 100644 index 0000000000..0f17e0313c --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/OfferingClient.java @@ -0,0 +1,96 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.cloudstack.domain.DiskOffering; +import org.jclouds.cloudstack.domain.NetworkOffering; +import org.jclouds.cloudstack.domain.ServiceOffering; +import org.jclouds.cloudstack.options.ListDiskOfferingsOptions; +import org.jclouds.cloudstack.options.ListNetworkOfferingsOptions; +import org.jclouds.cloudstack.options.ListServiceOfferingsOptions; +import org.jclouds.concurrent.Timeout; + +/** + * Provides synchronous access to CloudStack zone features. + *

+ * + * @see OfferingAsyncClient + * @see + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface OfferingClient { + /** + * Lists service offerings + * + * @param options + * if present, how to constrain the list. + * @return service offerings matching query, or empty set, if no service offerings are found + */ + Set listServiceOfferings(ListServiceOfferingsOptions... options); + + /** + * get a specific service offering by id + * + * @param id + * offering to get + * @return service offering or null if not found + */ + ServiceOffering getServiceOffering(long id); + + /** + * Lists disk offerings + * + * @param options + * if present, how to constrain the list. + * @return disk offerings matching query, or empty set, if no disk offerings are found + */ + Set listDiskOfferings(ListDiskOfferingsOptions... options); + + /** + * get a specific disk offering by id + * + * @param id + * offering to get + * @return disk offering or null if not found + */ + DiskOffering getDiskOffering(long id); + + /** + * Lists service offerings + * + * @param options + * if present, how to constrain the list. + * @return service offerings matching query, or empty set, if no service offerings are found + */ + Set listNetworkOfferings(ListNetworkOfferingsOptions... options); + + /** + * get a specific service offering by id + * + * @param id + * offering to get + * @return service offering or null if not found + */ + NetworkOffering getNetworkOffering(long id); +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClient.java new file mode 100644 index 0000000000..8765558ba5 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/SecurityGroupAsyncClient.java @@ -0,0 +1,91 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.cloudstack.domain.SecurityGroup; +import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.cloudstack.options.ListSecurityGroupsOptions; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.Unwrap; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to cloudstack via their REST API. + *

+ * + * @see OfferingClient + * @see + * @author Adrian Cole + */ +@RequestFilters(QuerySigner.class) +@QueryParams(keys = "response", values = "json") +public interface SecurityGroupAsyncClient { + + /** + * @see SecurityGroupClient#listSecurityGroups + */ + @GET + @QueryParams(keys = "command", values = "listSecurityGroups") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listSecurityGroups(ListSecurityGroupsOptions... options); + + /** + * @see SecurityGroupClient#getSecurityGroup + */ + @GET + @QueryParams(keys = "command", values = "listSecurityGroups") + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture getSecurityGroup(@QueryParam("id") long id); + + /** + * @see SecurityGroupClient#createSecurityGroup + */ + @GET + @QueryParams(keys = "command", values = "createSecurityGroup") + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture createSecurityGroup(@QueryParam("name") String name); + + /** + * @see SecurityGroupClient#deleteSecurityGroup + */ + @GET + @QueryParams(keys = "command", values = "deleteSecurityGroup") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture deleteSecurityGroup(@QueryParam("id") long id); + +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/SecurityGroupClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/SecurityGroupClient.java new file mode 100644 index 0000000000..3fe5a89490 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/SecurityGroupClient.java @@ -0,0 +1,73 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; +import java.util.concurrent.TimeUnit; + +import org.jclouds.cloudstack.domain.SecurityGroup; +import org.jclouds.cloudstack.options.ListSecurityGroupsOptions; +import org.jclouds.concurrent.Timeout; + +/** + * Provides synchronous access to CloudStack security group features. + *

+ * + * @see SecurityGroupAsyncClient + * @see + * @author Adrian Cole + */ +@Timeout(duration = 60, timeUnit = TimeUnit.SECONDS) +public interface SecurityGroupClient { + /** + * Lists security groups + * + * @param options + * if present, how to constrain the list. + * @return security groups matching query, or empty set, if no security groups are found + */ + Set listSecurityGroups(ListSecurityGroupsOptions... options); + + /** + * get a specific security group by id + * + * @param id + * group to get + * @return security group or null if not found + */ + SecurityGroup getSecurityGroup(long id); + + /** + * Creates a security group + * + * @param name + * name of the security group + * @return security group + */ + SecurityGroup createSecurityGroup(String name); + + /** + * delete a specific security group by id + * + * @param id + * group to delete + */ + void deleteSecurityGroup(long id); +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/TemplateAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/TemplateAsyncClient.java new file mode 100644 index 0000000000..4f90b90276 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/TemplateAsyncClient.java @@ -0,0 +1,83 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.features; + +import java.util.Set; + +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; + +import org.jclouds.cloudstack.domain.Template; +import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.cloudstack.options.ListTemplatesOptions; +import org.jclouds.rest.annotations.ExceptionParser; +import org.jclouds.rest.annotations.QueryParams; +import org.jclouds.rest.annotations.RequestFilters; +import org.jclouds.rest.annotations.Unwrap; +import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; + +import com.google.common.util.concurrent.ListenableFuture; + +/** + * Provides asynchronous access to cloudstack via their REST API. + *

+ * + * @see TemplateClient + * @see + * @author Adrian Cole + */ +@RequestFilters(QuerySigner.class) +@QueryParams(keys = "response", values = "json") +public interface TemplateAsyncClient { + + /** + * @see TemplateClient#listTemplates + */ + @GET + @QueryParams(keys = { "command", "templatefilter" }, values = { "listTemplates", "executable" }) + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listTemplates(); + + /** + * @see TemplateClient#listTemplates(ListTemplatesOptions) + */ + @GET + @QueryParams(keys = "command", values = "listTemplates") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) + ListenableFuture> listTemplates(ListTemplatesOptions options); + + /** + * @see TemplateClient#getTemplate + */ + @GET + @QueryParams(keys = { "command", "templatefilter" }, values = { "listTemplates", "executable" }) + @Unwrap(depth = 3, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture