Updated Branches: refs/heads/master 8db0218cf -> bbfec4a99
JCLOUDS-160: Support tags in EC2 images Based on the work made by Brock Noland Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/bbfec4a9 Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/bbfec4a9 Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/bbfec4a9 Branch: refs/heads/master Commit: bbfec4a9906a9df898fb3a464f1470917999cc1c Parents: 8db0218 Author: Ignasi Barrera <[email protected]> Authored: Fri Jul 5 00:43:47 2013 +0200 Committer: Ignasi Barrera <[email protected]> Committed: Sat Jul 6 10:08:10 2013 +0200 ---------------------------------------------------------------------- .../main/java/org/jclouds/ec2/domain/Image.java | 16 ++++++++-- .../ec2/xml/DescribeImagesResponseHandler.java | 28 ++++++++++++++--- .../xml/DescribeImagesResponseHandlerTest.java | 25 ++++++++++++--- .../src/test/resources/describe_images_tags.xml | 33 ++++++++++++++++++++ .../xml/NovaDescribeImagesResponseHandler.java | 5 +-- .../strategy/AWSEC2ReviseParsedImageTest.java | 5 ++- 6 files changed, 99 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/bbfec4a9/apis/ec2/src/main/java/org/jclouds/ec2/domain/Image.java ---------------------------------------------------------------------- diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Image.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Image.java index c4e7946..6304c43 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Image.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Image.java @@ -59,6 +59,7 @@ public class Image implements Comparable<Image> { @Nullable private final String rootDeviceName; private final Map<String, EbsBlockDevice> ebsBlockDevices = Maps.newHashMap(); + private final Map<String, String> tags = Maps.newLinkedHashMap(); private final VirtualizationType virtualizationType; public VirtualizationType getVirtualizationType() { @@ -76,7 +77,7 @@ public class Image implements Comparable<Image> { ImageType imageType, boolean isPublic, Iterable<String> productCodes, @Nullable String kernelId, @Nullable String platform, @Nullable String ramdiskId, RootDeviceType rootDeviceType, @Nullable String rootDeviceName, Map<String, EbsBlockDevice> ebsBlockDevices, - VirtualizationType virtualizationType, Hypervisor hypervisor) { + Map<String, String> tags, VirtualizationType virtualizationType, Hypervisor hypervisor) { this.region = checkNotNull(region, "region"); this.architecture = architecture; this.imageId = checkNotNull(imageId, "imageId"); @@ -95,6 +96,7 @@ public class Image implements Comparable<Image> { this.ramdiskId = ramdiskId; this.rootDeviceType = checkNotNull(rootDeviceType, "rootDeviceType"); this.ebsBlockDevices.putAll(checkNotNull(ebsBlockDevices, "ebsBlockDevices")); + this.tags.putAll(checkNotNull(tags, "tags")); this.virtualizationType = checkNotNull(virtualizationType, "virtualizationType"); this.hypervisor = checkNotNull(hypervisor, "hypervisor"); } @@ -346,6 +348,10 @@ public class Image implements Comparable<Image> { return ebsBlockDevices; } + public Map<String, String> getTags() { + return tags; + } + @Override public int hashCode() { final int prime = 31; @@ -353,6 +359,7 @@ public class Image implements Comparable<Image> { result = prime * result + ((architecture == null) ? 0 : architecture.hashCode()); result = prime * result + ((description == null) ? 0 : description.hashCode()); result = prime * result + ((ebsBlockDevices == null) ? 0 : ebsBlockDevices.hashCode()); + result = prime * result + ((tags == null) ? 0 : tags.hashCode()); result = prime * result + ((imageId == null) ? 0 : imageId.hashCode()); result = prime * result + ((imageLocation == null) ? 0 : imageLocation.hashCode()); result = prime * result + ((imageOwnerId == null) ? 0 : imageOwnerId.hashCode()); @@ -395,6 +402,11 @@ public class Image implements Comparable<Image> { return false; } else if (!ebsBlockDevices.equals(other.ebsBlockDevices)) return false; + if (tags == null) { + if (other.tags != null) + return false; + } else if (!tags.equals(other.tags)) + return false; if (imageId == null) { if (other.imageId != null) return false; @@ -478,7 +490,7 @@ public class Image implements Comparable<Image> { + ", kernelId=" + kernelId + ", name=" + name + ", platform=" + platform + ", productCodes=" + productCodes + ", ramdiskId=" + ramdiskId + ", region=" + region + ", rootDeviceName=" + rootDeviceName + ", rootDeviceType=" + rootDeviceType + ", virtualizationType=" + virtualizationType - + ", hypervisor=" + hypervisor + "]"; + + ", hypervisor=" + hypervisor + ", tags=" + tags + "]"; } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/bbfec4a9/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeImagesResponseHandler.java ---------------------------------------------------------------------- diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeImagesResponseHandler.java b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeImagesResponseHandler.java index edcf499..8e9a656 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeImagesResponseHandler.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/xml/DescribeImagesResponseHandler.java @@ -17,6 +17,7 @@ package org.jclouds.ec2.xml; import static org.jclouds.util.SaxUtils.currentOrNull; +import static org.jclouds.util.SaxUtils.equalsOrSuffix; import java.util.Map; import java.util.Set; @@ -54,8 +55,9 @@ import com.google.common.collect.Sets; public class DescribeImagesResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Set<Image>> { @Inject - public DescribeImagesResponseHandler(@Region Supplier<String> defaultRegion) { + public DescribeImagesResponseHandler(@Region Supplier<String> defaultRegion, TagSetHandler tagSetHandler) { this.defaultRegion = defaultRegion; + this.tagSetHandler = tagSetHandler; } @Resource @@ -64,6 +66,7 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerForGeneratedR protected Set<Image> contents = Sets.newLinkedHashSet(); private StringBuilder currentText = new StringBuilder(); private final Supplier<String> defaultRegion; + private final TagSetHandler tagSetHandler; private Architecture architecture; private String name; @@ -81,8 +84,10 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerForGeneratedR private String ramdiskId; private boolean inProductCodes; private boolean inBlockDeviceMapping; + private boolean inTagSet; private RootDeviceType rootDeviceType = RootDeviceType.INSTANCE_STORE; private Map<String, EbsBlockDevice> ebsBlockDevices = Maps.newHashMap(); + private Map<String, String> tags = Maps.newLinkedHashMap(); private String deviceName; private String snapshotId; private VirtualizationType virtualizationType = VirtualizationType.PARAVIRTUAL; @@ -102,10 +107,21 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerForGeneratedR inProductCodes = true; } else if (qName.equals("blockDeviceMapping")) { inBlockDeviceMapping = true; + } else if (equalsOrSuffix(qName, "tagSet")) { + inTagSet = true; + } + if (inTagSet) { + tagSetHandler.startElement(uri, name, qName, attrs); } } public void endElement(String uri, String name, String qName) { + if (equalsOrSuffix(qName, "tagSet")) { + inTagSet = false; + tags = tagSetHandler.getResult(); + } else if (inTagSet) { + tagSetHandler.endElement(uri, name, qName); + } if (qName.equals("architecture")) { architecture = Architecture.fromValue(currentText.toString().trim()); // Nova Diablo uses the wrong name for this field @@ -161,14 +177,14 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerForGeneratedR this.snapshotId = null; this.volumeSize = 0; this.deleteOnTermination = true; - } else if (!inProductCodes) { + } else if (!inTagSet && !inProductCodes) { try { String region = getRequest() != null ? AWSUtils.findRegionInArgsOrNull(getRequest()) : null; if (region == null) region = defaultRegion.get(); contents.add(new Image(region, architecture, this.name, description, imageId, imageLocation, imageOwnerId, imageState, rawState, imageType, isPublic, productCodes, kernelId, platform, - ramdiskId, rootDeviceType, rootDeviceName, ebsBlockDevices, virtualizationType, hypervisor)); + ramdiskId, rootDeviceType, rootDeviceName, ebsBlockDevices, tags, virtualizationType, hypervisor)); } catch (NullPointerException e) { logger.warn(e, "malformed image: %s", imageId); } @@ -198,6 +214,10 @@ public class DescribeImagesResponseHandler extends ParseSax.HandlerForGeneratedR } public void characters(char ch[], int start, int length) { - currentText.append(ch, start, length); + if (inTagSet) { + tagSetHandler.characters(ch, start, length); + } else { + currentText.append(ch, start, length); + } } } http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/bbfec4a9/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeImagesResponseHandlerTest.java ---------------------------------------------------------------------- diff --git a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeImagesResponseHandlerTest.java b/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeImagesResponseHandlerTest.java index 2ddf4ab..f2b0894 100644 --- a/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeImagesResponseHandlerTest.java +++ b/apis/ec2/src/test/java/org/jclouds/ec2/xml/DescribeImagesResponseHandlerTest.java @@ -59,7 +59,7 @@ public class DescribeImagesResponseHandlerTest { "ec2-public-images/fedora-8-i386-base-v1.04.manifest.xml", "206029621532", ImageState.AVAILABLE, "available", ImageType.MACHINE, false, Sets.<String> newHashSet("9961934F"), "aki-4438dd2d", null, "ari-4538dd2c", RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of(), - VirtualizationType.PARAVIRTUAL, Hypervisor.XEN)); + ImmutableMap.<String, String> of(), VirtualizationType.PARAVIRTUAL, Hypervisor.XEN)); Set<Image> result = parseImages("/describe_images.xml"); @@ -73,7 +73,7 @@ public class DescribeImagesResponseHandlerTest { "aws-solutions-amis/SqlSvrStd2003r2-x86_64-Win_SFWBasic5.1-v1.0.manifest.xml", "771350841976", ImageState.AVAILABLE, "available", ImageType.MACHINE, true, Sets.<String> newHashSet("5771E9A6"), null, "windows", null, RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of(), - VirtualizationType.PARAVIRTUAL, Hypervisor.XEN)); + ImmutableMap.<String, String> of(), VirtualizationType.PARAVIRTUAL, Hypervisor.XEN)); Set<Image> result = parseImages("/describe_images_windows.xml"); @@ -89,7 +89,7 @@ public class DescribeImagesResponseHandlerTest { ImageState.AVAILABLE, "available", ImageType.MACHINE, true, Sets.<String> newHashSet(), null, "windows", null, RootDeviceType.EBS, "/dev/sda1", ImmutableMap.<String, EbsBlockDevice> of("/dev/sda1", new EbsBlockDevice("snap-d01272b9", 30, true), "xvdf", new EbsBlockDevice("snap-d31272ba", 250, - false)), VirtualizationType.HVM, Hypervisor.XEN)); + false)), ImmutableMap.<String, String> of(), VirtualizationType.HVM, Hypervisor.XEN)); Set<Image> result = parseImages("/describe_images_ebs.xml"); @@ -98,12 +98,29 @@ public class DescribeImagesResponseHandlerTest { assertEquals(get(result, 0).getRawState(), "available"); } + public void testTags() { + Set<Image> contents = ImmutableSet.of(new Image("us-east-1", Architecture.I386, null, null, "ami-be3adfd7", + "ec2-public-images/fedora-8-i386-base-v1.04.manifest.xml", "206029621532", ImageState.AVAILABLE, "available", + ImageType.MACHINE, false, Sets.<String> newHashSet("9961934F"), "aki-4438dd2d", null, "ari-4538dd2c", + RootDeviceType.INSTANCE_STORE, null, ImmutableMap.<String, EbsBlockDevice> of(), + ImmutableMap.<String, String> of("Name", "Some machine name", "Second", "Second value"), + VirtualizationType.PARAVIRTUAL, Hypervisor.XEN)); + + Set<Image> result = parseImages("/describe_images_tags.xml"); + + assertEquals(result.toString(), contents.toString()); + assertEquals(get(result, 0).getImageState(), ImageState.AVAILABLE); + assertEquals(get(result, 0).getRawState(), "available"); + assertEquals(get(result, 0).getTags().get("Name"), "Some machine name"); + assertEquals(get(result, 0).getTags().get("Second"), "Second value"); + } + public void testDiabloWithIncorrectDisplayNameField() { Set<Image> contents = ImmutableSet.of(new Image("us-east-1", Architecture.X86_64, "CentOS 6.2 Server 64-bit 20120125", "", "ami-0000054e", "local (CentOS 6.2 Server 64-bit 20120125)", "", ImageState.AVAILABLE, "available", ImageType.MACHINE, true, Sets.<String> newHashSet(), "aki-0000054c", null, "ari-0000054d", RootDeviceType.INSTANCE_STORE, "/dev/sda1", ImmutableMap.<String, EbsBlockDevice> of(), - VirtualizationType.PARAVIRTUAL, Hypervisor.XEN)); + ImmutableMap.<String, String> of(), VirtualizationType.PARAVIRTUAL, Hypervisor.XEN)); Set<Image> result = parseImages("/describe_images_nova.xml"); http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/bbfec4a9/apis/ec2/src/test/resources/describe_images_tags.xml ---------------------------------------------------------------------- diff --git a/apis/ec2/src/test/resources/describe_images_tags.xml b/apis/ec2/src/test/resources/describe_images_tags.xml new file mode 100644 index 0000000..ab22d1d --- /dev/null +++ b/apis/ec2/src/test/resources/describe_images_tags.xml @@ -0,0 +1,33 @@ +<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/"> + <imagesSet> + <item> + <imageId>ami-be3adfd7</imageId> + <imageLocation>ec2-public-images/fedora-8-i386-base-v1.04.manifest.xml</imageLocation> + <imageState>available</imageState> + <imageOwnerId>206029621532</imageOwnerId> + <isPublic>false</isPublic> + <productCodes> + <item> + <productCode>9961934F</productCode> + </item> + </productCodes> + <architecture>i386</architecture> + <imageType>machine</imageType> + <kernelId>aki-4438dd2d</kernelId> + <ramdiskId>ari-4538dd2c</ramdiskId> + <rootDeviceType>instance-store</rootDeviceType> + <blockDeviceMapping /> + <virtualizationType>paravirtual</virtualizationType> + <tagSet> + <item> + <key>Name</key> + <value>Some machine name</value> + </item> + <item> + <key>Second</key> + <value>Second value</value> + </item> + </tagSet> + </item> + </imagesSet> +</DescribeImagesResponse> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/bbfec4a9/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/xml/NovaDescribeImagesResponseHandler.java ---------------------------------------------------------------------- diff --git a/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/xml/NovaDescribeImagesResponseHandler.java b/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/xml/NovaDescribeImagesResponseHandler.java index 12fdfe7..bf654d1 100644 --- a/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/xml/NovaDescribeImagesResponseHandler.java +++ b/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/xml/NovaDescribeImagesResponseHandler.java @@ -23,6 +23,7 @@ import javax.inject.Inject; import org.jclouds.ec2.domain.Image; import org.jclouds.ec2.domain.Image.ImageType; import org.jclouds.ec2.xml.DescribeImagesResponseHandler; +import org.jclouds.ec2.xml.TagSetHandler; import org.jclouds.location.Region; import com.google.common.base.Predicate; @@ -37,8 +38,8 @@ import com.google.common.collect.Iterables; */ public class NovaDescribeImagesResponseHandler extends DescribeImagesResponseHandler { @Inject - public NovaDescribeImagesResponseHandler(@Region Supplier<String> defaultRegion) { - super(defaultRegion); + public NovaDescribeImagesResponseHandler(@Region Supplier<String> defaultRegion, TagSetHandler tagSetHandler) { + super(defaultRegion, tagSetHandler); } public Set<Image> getResult() { http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/bbfec4a9/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImageTest.java ---------------------------------------------------------------------- diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImageTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImageTest.java index 7789af2..e63a9b4 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImageTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ReviseParsedImageTest.java @@ -100,9 +100,12 @@ public class AWSEC2ReviseParsedImageTest { RootDeviceType rootDeviceType = RootDeviceType.EBS; String rootDeviceName = ""; Map<String, Image.EbsBlockDevice> ebsBlockDevices = ImmutableMap.of(); + Map<String, String> tags = ImmutableMap.of(); VirtualizationType virtualizationType = VirtualizationType.HVM; Hypervisor hypervisor = Hypervisor.XEN; - Image from = new Image(region, architecture, imageName, description, imageId, imageOwnerId + "/" + imageName, imageOwnerId, imageState, "available", imageType, isPublic, productCodes, kernelId, platform, ramdiskId, rootDeviceType, rootDeviceName, ebsBlockDevices, virtualizationType, hypervisor); + Image from = new Image(region, architecture, imageName, description, imageId, imageOwnerId + "/" + imageName, + imageOwnerId, imageState, "available", imageType, isPublic, productCodes, kernelId, platform, ramdiskId, + rootDeviceType, rootDeviceName, ebsBlockDevices, tags, virtualizationType, hypervisor); return from; } }
