From 7c317b80e85dc0c370d5e432d3600580c4e97e4d Mon Sep 17 00:00:00 2001 From: Adam Lowe Date: Wed, 2 May 2012 17:34:00 +0100 Subject: [PATCH] openstack-nova-ec2: work-around for dates encoded as '-' when they should be null (the should not be present in the response!) --- .../nova/ec2/config/NovaEC2ParserModule.java | 119 ++++++++++++++++ .../ec2/config/NovaEC2RestClientModule.java | 2 + .../NovaEC2InstanceClientExpectTest.java | 54 ++++++++ .../resources/nova_ec2_describe_instances.xml | 128 ++++++++++++++++++ 4 files changed, 303 insertions(+) create mode 100644 apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2ParserModule.java create mode 100644 apis/openstack-nova-ec2/src/test/java/org/jclouds/openstack/nova/ec2/services/NovaEC2InstanceClientExpectTest.java create mode 100644 apis/openstack-nova-ec2/src/test/resources/nova_ec2_describe_instances.xml diff --git a/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2ParserModule.java b/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2ParserModule.java new file mode 100644 index 0000000000..d8f7931c3f --- /dev/null +++ b/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2ParserModule.java @@ -0,0 +1,119 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.openstack.nova.ec2.config; + +import java.util.Date; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.date.DateService; +import org.jclouds.date.internal.SimpleDateFormatDateService; + +import com.google.common.base.Objects; +import com.google.inject.AbstractModule; + +/** + * @author Adam Lowe + */ +public class NovaEC2ParserModule extends AbstractModule { + + @Override + protected void configure() { + bind(DateService.class).to(Iso8601WithDashesTreatedAsNullDateService.class); + } + + @Singleton + public static class Iso8601WithDashesTreatedAsNullDateService implements DateService { + DateService delegate; + + @Inject + public Iso8601WithDashesTreatedAsNullDateService(SimpleDateFormatDateService service) { + this.delegate = service; + } + + @Override + public Date fromSeconds(long seconds) { + return delegate.fromSeconds(seconds); + } + + @Override + public String cDateFormat(Date date) { + return delegate.cDateFormat(date); + } + + @Override + public String cDateFormat() { + return delegate.cDateFormat(); + } + + @Override + public Date cDateParse(String toParse) { + return delegate.cDateParse(toParse); + } + + @Override + public String rfc822DateFormat(Date date) { + return delegate.rfc822DateFormat(date); + } + + @Override + public String rfc822DateFormat() { + return delegate.rfc822DateFormat(); + } + + @Override + public Date rfc822DateParse(String toParse) { + return delegate.rfc822DateParse(toParse); + } + + @Override + public String iso8601SecondsDateFormat(Date dateTime) { + return delegate.iso8601SecondsDateFormat(dateTime); + } + + @Override + public String iso8601SecondsDateFormat() { + return delegate.iso8601SecondsDateFormat(); + } + + @Override + public String iso8601DateFormat(Date date) { + return delegate.iso8601DateFormat(date); + } + + @Override + public String iso8601DateFormat() { + return delegate.iso8601DateFormat(); + } + + @Override + public Date iso8601DateParse(String toParse) { + if (Objects.equal("-", toParse)) return null; + return delegate.iso8601DateParse(toParse); + } + + @Override + public Date iso8601SecondsDateParse(String toParse) { + if (Objects.equal("-", toParse)) return null; + return delegate.iso8601SecondsDateParse(toParse); + } + } + +} diff --git a/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2RestClientModule.java b/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2RestClientModule.java index 5d6358bf3b..da18c3733f 100644 --- a/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2RestClientModule.java +++ b/apis/openstack-nova-ec2/src/main/java/org/jclouds/openstack/nova/ec2/config/NovaEC2RestClientModule.java @@ -37,12 +37,14 @@ import com.google.inject.Scopes; /** * * @author Adrian Cole + * @author Adam Lowe */ @ConfiguresRestClient public class NovaEC2RestClientModule extends EC2RestClientModule { @Override protected void configure() { + install(new NovaEC2ParserModule()); super.configure(); bind(CreateVolumeResponseHandler.class).to(NovaCreateVolumeResponseHandler.class).in(Scopes.SINGLETON); bind(DescribeImagesResponseHandler.class).to(NovaDescribeImagesResponseHandler.class); diff --git a/apis/openstack-nova-ec2/src/test/java/org/jclouds/openstack/nova/ec2/services/NovaEC2InstanceClientExpectTest.java b/apis/openstack-nova-ec2/src/test/java/org/jclouds/openstack/nova/ec2/services/NovaEC2InstanceClientExpectTest.java new file mode 100644 index 0000000000..5e55bb092b --- /dev/null +++ b/apis/openstack-nova-ec2/src/test/java/org/jclouds/openstack/nova/ec2/services/NovaEC2InstanceClientExpectTest.java @@ -0,0 +1,54 @@ +package org.jclouds.openstack.nova.ec2.services; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertFalse; + +import java.net.URI; +import java.util.Set; + +import org.jclouds.ec2.domain.Attachment; +import org.jclouds.ec2.domain.BlockDevice; +import org.jclouds.ec2.domain.Reservation; +import org.jclouds.ec2.domain.RunningInstance; +import org.jclouds.ec2.services.InstanceClient; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.openstack.nova.ec2.internal.BaseNovaEC2RestClientExpectTest; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Iterables; + +/** + * @author Adam Lowe + */ +public class NovaEC2InstanceClientExpectTest extends BaseNovaEC2RestClientExpectTest { + + public void testDescribeInstancesWithDashesInPlaceOfNullDates() { + InstanceClient client = requestsSendResponses( + describeAvailabilityZonesRequest, + describeAvailabilityZonesResponse, + HttpRequest.builder().method("POST") + .endpoint(URI.create("http://localhost:8773/services/Cloud/")) + .headers(ImmutableMultimap.of("Host", "localhost:8773")) + .payload(payloadFromStringWithContentType("Action=DescribeInstances&Signature=kkCE1HzyntmkICEidOizw50B9yjLdNZvAWUXVse1c8o%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=2012-04-16T15%3A54%3A08.897Z&Version=2009-04-04&AWSAccessKeyId=identity", "application/x-www-form-urlencoded")).build(), + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/nova_ec2_describe_instances.xml")).build() + ).getInstanceServices(); + + Set> response = client.describeInstancesInRegion("nova"); + + assertEquals(response.size(), 3); + + Reservation target = Iterables.get(response, 2); + RunningInstance runningInstance = Iterables.getOnlyElement(target); + BlockDevice bd = Iterables.getOnlyElement(runningInstance.getEbsBlockDevices().values()); + + // this is a '-' in the nova_ec2_describe_instances.xml + assertNull(bd.getAttachTime()); + + // double-check the other fields + assertFalse(bd.isDeleteOnTermination()); + assertEquals(bd.getVolumeId(), "1"); + } + +} diff --git a/apis/openstack-nova-ec2/src/test/resources/nova_ec2_describe_instances.xml b/apis/openstack-nova-ec2/src/test/resources/nova_ec2_describe_instances.xml new file mode 100644 index 0000000000..707fc4af22 --- /dev/null +++ b/apis/openstack-nova-ec2/src/test/resources/nova_ec2_describe_instances.xml @@ -0,0 +1,128 @@ + + + req-a68563bb-034e-4a32-aac7-5126e041cf91 + + + 2b25129754c145de8426896b09a42106 + + + default + + + r-1jywe5ye + + + + nova + + instance-store + None (2b25129754c145de8426896b09a42106, ubuntu) + i-00000003 + + 16 + running + + + ami-00000001 + + mishdemo + mishdemo + 2012-05-02T06:59:59.000Z + 0 + /dev/vda + aki-00000002 + ari-00000003 + 10.77.22.4 + m1.small + 10.77.22.4 + + + + + d8f0cd49971a44d187b454e14921056d + + + default + + + r-pctvv0ey + + + + nova + + instance-store + None (d8f0cd49971a44d187b454e14921056d, ubuntu) + i-00000001 + + 16 + running + + + ami-00000001 + + avi-server1 + avi-server1 + 2012-05-01T09:18:37.000Z + 0 + /dev/vda + aki-00000002 + ari-00000003 + 10.77.22.2 + m1.tiny + 10.77.22.2 + + + + + d8f0cd49971a44d187b454e14921056d + + + default + + + avi-sg1 + + + r-0iwpw2u8 + + + + + /dev/vdc + + in-use + false + 1 + - + + + + + nova + + instance-store + avi-kp1 (d8f0cd49971a44d187b454e14921056d, ubuntu) + i-00000002 + + 16 + running + + + ami-00000001 + + avi-server2 + avi-server2 + 2012-05-01T09:22:26.000Z + 0 + /dev/vda + aki-00000002 + ari-00000003 + 10.77.22.3 + m1.tiny + 10.77.22.3 + + + + + \ No newline at end of file