Issue 1007: changed ec2 date parsing logic to use DateCodec and isolated hacks to eucalyptus and openstack-nova-ec2 respectively

This commit is contained in:
Adrian Cole 2012-07-06 22:29:21 -07:00
parent 7a776c0572
commit e9bfb9d1a2
24 changed files with 314 additions and 244 deletions

View File

@ -24,7 +24,8 @@ import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
@ -41,12 +42,12 @@ public class AttachmentHandler extends ParseSax.HandlerForGeneratedRequestWithRe
@Resource
protected Logger logger = Logger.NULL;
protected final DateService dateService;
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
@Inject
AttachmentHandler(DateService dateService, @Region Supplier<String> defaultRegion) {
this.dateService = dateService;
AttachmentHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion) {
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
}
@ -76,7 +77,7 @@ public class AttachmentHandler extends ParseSax.HandlerForGeneratedRequestWithRe
} else if (qName.equals("device")) {
device = currentText.toString().trim();
} else if (qName.equals("attachTime")) {
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
attachTime = dateCodec.toDate(currentText.toString().trim());
}
currentText = new StringBuilder();
}

View File

@ -24,11 +24,11 @@ import static org.jclouds.util.SaxUtils.equalsOrSuffix;
import java.util.Date;
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.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.InstanceState;
@ -38,7 +38,6 @@ import org.jclouds.ec2.domain.RunningInstance;
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.base.Supplier;
@ -51,17 +50,14 @@ import com.google.inject.Provider;
*/
public abstract class BaseReservationHandler<T> extends HandlerForGeneratedRequestWithResult<T> {
@Resource
protected Logger logger = Logger.NULL;
protected final DateService dateService;
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
protected final Provider<Builder> builderProvider;
@Inject
public BaseReservationHandler(DateService dateService, @Region Supplier<String> defaultRegion,
Provider<RunningInstance.Builder> builderProvider) {
this.dateService = dateService;
public BaseReservationHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
Provider<RunningInstance.Builder> builderProvider) {
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
this.builderProvider = builderProvider;
this.builder = builderProvider.get();
@ -148,7 +144,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
} else if (equalsOrSuffix(qName, "keyName")) {
builder.keyName(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "launchTime")) {
builder.launchTime(parseDate());
builder.launchTime(dateCodec.toDate(currentOrNull(currentText)));
} else if (equalsOrSuffix(qName, "availabilityZone")) {
builder.availabilityZone(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "virtualizationType")) {
@ -177,7 +173,7 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
} else if (equalsOrSuffix(qName, "status")) {
attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
} else if (equalsOrSuffix(qName, "attachTime")) {
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
attachTime = dateCodec.toDate(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "deleteOnTermination")) {
deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim());
} else if (equalsOrSuffix(qName, "ebs")) {
@ -191,15 +187,6 @@ public abstract class BaseReservationHandler<T> extends HandlerForGeneratedReque
currentText = new StringBuilder();
}
protected Date parseDate() {
try {
return dateService.iso8601DateParse(currentOrNull(currentText));
} catch (RuntimeException e) {
// Eucalyptus
return dateService.iso8601SecondsDateParse(currentOrNull(currentText));
}
}
protected void inItem() {
if (endOfInstanceItem()) {
refineBuilderBeforeAddingInstance();

View File

@ -21,7 +21,8 @@ package org.jclouds.ec2.xml;
import java.util.Date;
import java.util.Map;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.http.functions.ParseSax;
@ -44,11 +45,11 @@ public class BlockDeviceMappingHandler extends
private Attachment.Status attachmentStatus;
private Date attachTime;
protected final DateService dateService;
protected final DateCodec dateCodec;
@Inject
public BlockDeviceMappingHandler(DateService dateService) {
this.dateService = dateService;
public BlockDeviceMappingHandler(DateCodecFactory dateCodecFactory) {
this.dateCodec = dateCodecFactory.iso8601();
}
public Map<String, BlockDevice> getResult() {
@ -65,7 +66,7 @@ public class BlockDeviceMappingHandler extends
} else if (qName.equals("status")) {
attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
} else if (qName.equals("attachTime")) {
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
attachTime = dateCodec.toDate(currentText.toString().trim());
} else if (qName.equals("item")) {
ebsBlockDevices.put(deviceName, new BlockDevice(volumeId, attachmentStatus, attachTime, deleteOnTermination));
this.volumeId = null;

View File

@ -23,7 +23,8 @@ import java.util.Date;
import javax.inject.Inject;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.BundleTask;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
@ -35,13 +36,16 @@ import com.google.common.base.Supplier;
* @author Adrian Cole
*/
public class BundleTaskHandler extends ParseSax.HandlerForGeneratedRequestWithResult<BundleTask> {
private StringBuilder currentText = new StringBuilder();
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
@Inject
protected DateService dateService;
@Inject
@Region
Supplier<String> defaultRegion;
protected BundleTaskHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion) {
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
}
private StringBuilder currentText = new StringBuilder();
private String bundleId;
private String code;
@ -90,7 +94,7 @@ public class BundleTaskHandler extends ParseSax.HandlerForGeneratedRequestWithRe
temp = temp.substring(0, temp.length() - 1);
progress = Integer.parseInt(temp);
} else if (qName.equals("startTime")) {
startTime = dateService.iso8601DateParse(currentText.toString().trim());
startTime = dateCodec.toDate(currentText.toString().trim());
} else if (qName.equals("state")) {
state = currentText.toString().trim();
} else if (qName.equals("bucket")) {
@ -98,7 +102,7 @@ public class BundleTaskHandler extends ParseSax.HandlerForGeneratedRequestWithRe
} else if (qName.equals("prefix")) {
prefix = currentText.toString().trim();
} else if (qName.equals("updateTime")) {
updateTime = dateService.iso8601DateParse(currentText.toString().trim());
updateTime = dateCodec.toDate(currentText.toString().trim());
}
currentText = new StringBuilder();
}

View File

@ -25,18 +25,17 @@ import java.util.Map;
import java.util.Map.Entry;
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.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.Volume;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import org.jclouds.logging.Logger;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.xml.sax.Attributes;
@ -50,21 +49,22 @@ import com.google.common.collect.Sets;
* @author Adrian Cole
*/
public class CreateVolumeResponseHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Volume> {
protected StringBuilder currentText = new StringBuilder();
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
protected final Supplier<Map<String, Supplier<Set<String>>>> regionToZonesSupplier;
protected final Supplier<Set<String>> zonesSupplier;
@Resource
protected Logger logger = Logger.NULL;
@Inject
protected DateService dateService;
@Inject
@Region
protected Supplier<String> defaultRegion;
@Inject
@Zone
protected Supplier<Map<String, Supplier<Set<String>>>> regionToZonesSupplier;
@Inject
@Zone
protected Supplier<Set<String>> zonesSupplier;
protected CreateVolumeResponseHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
@Zone Supplier<Map<String, Supplier<Set<String>>>> regionToZonesSupplier,
@Zone Supplier<Set<String>> zonesSupplier) {
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
this.regionToZonesSupplier = regionToZonesSupplier;
this.zonesSupplier = zonesSupplier;
}
protected StringBuilder currentText = new StringBuilder();
protected String id;
protected int size;
@ -118,7 +118,7 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerForGeneratedReq
volumeStatus = Volume.Status.fromValue(currentText.toString().trim());
}
} else if (qName.equals("createTime")) {
createTime = dateService.iso8601DateParse(currentText.toString().trim());
createTime = dateCodec.toDate(currentText.toString().trim());
} else if (qName.equals("attachmentSet")) {
inAttachmentSet = false;
} else if (qName.equals("instanceId")) {
@ -130,7 +130,7 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerForGeneratedReq
} else if (qName.equals("device")) {
device = currentText.toString().trim();
} else if (qName.equals("attachTime")) {
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
attachTime = dateCodec.toDate(currentText.toString().trim());
} else if (qName.equals("item")) {
if (inAttachmentSet) {
attachments.add(new Attachment(region, volumeId, instanceId, device, attachmentStatus, attachTime));

View File

@ -22,7 +22,7 @@ import java.util.Set;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.location.Region;
@ -44,9 +44,9 @@ public class DescribeInstancesResponseHandler extends
private Set<Reservation<? extends RunningInstance>> reservations = Sets.newLinkedHashSet();
@Inject
DescribeInstancesResponseHandler(DateService dateService, @Region Supplier<String> defaultRegion,
Provider<RunningInstance.Builder> builderProvider) {
super(dateService, defaultRegion, builderProvider);
DescribeInstancesResponseHandler(DateCodecFactory dateCodecFactory,
@Region Supplier<String> defaultRegion, Provider<RunningInstance.Builder> builderProvider) {
super(dateCodecFactory, defaultRegion, builderProvider);
}
@Override

View File

@ -20,7 +20,8 @@ package org.jclouds.ec2.xml;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.PasswordData;
import org.jclouds.http.functions.ParseSax;
@ -28,10 +29,16 @@ import org.jclouds.http.functions.ParseSax;
* @author Richard Downer
*/
public class GetPasswordDataResponseHandler extends ParseSax.HandlerWithResult<PasswordData> {
protected final DateCodec dateCodec;
@Inject
protected GetPasswordDataResponseHandler(DateCodecFactory dateCodecFactory) {
this.dateCodec = dateCodecFactory.iso8601();
}
private StringBuilder currentText = new StringBuilder();
private PasswordData.Builder builder = PasswordData.builder();
@Inject protected DateService dateService;
@Override
public PasswordData getResult() {
@ -44,7 +51,7 @@ public class GetPasswordDataResponseHandler extends ParseSax.HandlerWithResult<P
} else if (qName.equals("instanceId")) {
builder.instanceId(currentText.toString().trim());
} else if (qName.equals("timestamp")) {
builder.timestamp(dateService.iso8601DateParse(currentText.toString().trim()));
builder.timestamp(dateCodec.toDate(currentText.toString().trim()));
} else if (qName.equals("passwordData")) {
builder.passwordData(currentText.toString().trim());
}

View File

@ -20,7 +20,7 @@ package org.jclouds.ec2.xml;
import javax.inject.Inject;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.location.Region;
@ -39,9 +39,9 @@ import com.google.inject.Provider;
public class RunInstancesResponseHandler extends BaseReservationHandler<Reservation<? extends RunningInstance>> {
@Inject
RunInstancesResponseHandler(DateService dateService, @Region Supplier<String> defaultRegion,
RunInstancesResponseHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
Provider<RunningInstance.Builder> builderProvider) {
super(dateService, defaultRegion, builderProvider);
super(dateCodecFactory, defaultRegion, builderProvider);
}
@Override

View File

@ -23,7 +23,8 @@ import java.util.Date;
import javax.inject.Inject;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Snapshot;
import org.jclouds.ec2.domain.Snapshot.Status;
import org.jclouds.http.functions.ParseSax;
@ -38,7 +39,7 @@ import com.google.common.base.Supplier;
public class SnapshotHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Snapshot> {
private StringBuilder currentText = new StringBuilder();
protected final DateService dateService;
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
private String id;
@ -52,8 +53,8 @@ public class SnapshotHandler extends ParseSax.HandlerForGeneratedRequestWithResu
private String ownerAlias;
@Inject
public SnapshotHandler(DateService dateService, @Region Supplier<String> defaultRegion) {
this.dateService = dateService;
public SnapshotHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion) {
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
}
@ -85,7 +86,7 @@ public class SnapshotHandler extends ParseSax.HandlerForGeneratedRequestWithResu
} else if (qName.equals("status")) {
status = Snapshot.Status.fromValue(currentText.toString().trim());
} else if (qName.equals("startTime")) {
startTime = dateService.iso8601DateParse(currentText.toString().trim());
startTime = dateCodec.toDate(currentText.toString().trim());
} else if (qName.equals("progress")) {
String progressString = currentText.toString().trim();
if (!progressString.equals("")) {

View File

@ -17,6 +17,7 @@
* under the License.
*/
package org.jclouds.eucalyptus;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
@ -26,6 +27,11 @@ import org.jclouds.apis.ApiMetadata;
import org.jclouds.ec2.EC2ApiMetadata;
import org.jclouds.ec2.EC2AsyncClient;
import org.jclouds.ec2.EC2Client;
import org.jclouds.eucalyptus.config.Iso8601SecondsModule;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
* Implementation of {@link ApiMetadata} for the Eucalyptus (EC2 clone) api.
@ -52,24 +58,27 @@ public class EucalyptusApiMetadata extends EC2ApiMetadata {
protected EucalyptusApiMetadata(Builder builder) {
super(builder);
}
public static Properties defaultProperties() {
Properties properties = EC2ApiMetadata.defaultProperties();
// in version 3, lowecase 'e' version 2, uppercase 'E'
// in version 3, lowercase 'e' version 2, uppercase 'E'
properties.setProperty(PROPERTY_REGIONS, "eucalyptus");
properties.setProperty(TIMEOUT_PORT_OPEN, 5 * 60 * 1000 + "");
return properties;
}
public static class Builder extends EC2ApiMetadata.Builder {
protected Builder(){
protected Builder() {
super(EC2Client.class, EC2AsyncClient.class);
id("eucalyptus")
.defaultEndpoint("http://partnercloud.eucalyptus.com:8773/services/Eucalyptus/")
.name("Eucalyptus (EC2 clone) API")
.defaultProperties(EucalyptusApiMetadata.defaultProperties());
.defaultProperties(EucalyptusApiMetadata.defaultProperties())
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.addAll(defaultModules)
.add(Iso8601SecondsModule.class).build());
}
@Override
public EucalyptusApiMetadata build() {
return new EucalyptusApiMetadata(this);

View File

@ -0,0 +1,34 @@
/**
* 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.eucalyptus.config;
import org.jclouds.date.internal.DateServiceDateCodecFactory.DateServiceIso8601Codec;
import org.jclouds.eucalyptus.internal.DateServiceIso8601SecondsCodec;
import com.google.inject.AbstractModule;
public class Iso8601SecondsModule extends AbstractModule {
@Override
protected void configure() {
bind(DateServiceIso8601Codec.class).to(DateServiceIso8601SecondsCodec.class);
}
}

View File

@ -0,0 +1,54 @@
/**
* 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.eucalyptus.internal;
import java.util.Date;
import javax.inject.Singleton;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.DateServiceDateCodecFactory.DateServiceIso8601Codec;
import com.google.inject.Inject;
@Singleton
public class DateServiceIso8601SecondsCodec extends DateServiceIso8601Codec {
@Inject
public DateServiceIso8601SecondsCodec(DateService dateService) {
super(dateService);
}
@Override
public Date toDate(String date) throws IllegalArgumentException {
try {
return super.toDate(date);
} catch (RuntimeException e) {
// Eucalyptus <3.0 didn't include milliseconds
// TODO: see if this is still a problem
return dateService.iso8601SecondsDateParse(date);
}
}
@Override
public String toString() {
return "iso8601Seconds()";
}
}

View File

@ -30,6 +30,7 @@ import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.ec2.EC2ApiMetadata;
import org.jclouds.ec2.compute.config.EC2ResolveImagesModule;
import org.jclouds.openstack.nova.ec2.config.HyphenToNullIso8601Module;
import org.jclouds.openstack.nova.ec2.config.NovaEC2ComputeServiceContextModule;
import org.jclouds.openstack.nova.ec2.config.NovaEC2RestClientModule;
import org.jclouds.rest.RestContext;
@ -95,7 +96,11 @@ public class NovaEC2ApiMetadata extends EC2ApiMetadata {
.defaultEndpoint("http://localhost:8773/services/Cloud")
.defaultProperties(NovaEC2ApiMetadata.defaultProperties())
.context(CONTEXT_TOKEN)
.defaultModules(ImmutableSet.<Class<? extends Module>>of(NovaEC2RestClientModule.class, EC2ResolveImagesModule.class, NovaEC2ComputeServiceContextModule.class));
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
.add(NovaEC2RestClientModule.class)
.add(EC2ResolveImagesModule.class)
.add(NovaEC2ComputeServiceContextModule.class)
.add(HyphenToNullIso8601Module.class).build());
}
@Override

View File

@ -0,0 +1,34 @@
/**
* 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 org.jclouds.date.internal.DateServiceDateCodecFactory.DateServiceIso8601Codec;
import org.jclouds.openstack.nova.ec2.internal.HyphenToNullIso8601Codec;
import com.google.inject.AbstractModule;
public class HyphenToNullIso8601Module extends AbstractModule {
@Override
protected void configure() {
bind(DateServiceIso8601Codec.class).to(HyphenToNullIso8601Codec.class);
}
}

View File

@ -1,134 +0,0 @@
/**
* 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);
}
@Override
public String rfc1123DateFormat(Date date) {
return delegate.rfc1123DateFormat(date);
}
@Override
public String rfc1123DateFormat() {
return delegate.rfc1123DateFormat();
}
@Override
public Date rfc1123DateParse(String toParse) {
return delegate.rfc1123DateParse(toParse);
}
}
}

View File

@ -83,7 +83,6 @@ public class NovaEC2RestClientModule extends EC2RestClientModule<NovaEC2Client,
@Override
protected void configure() {
install(new NovaEC2ParserModule());
super.configure();
bind(CreateVolumeResponseHandler.class).to(NovaCreateVolumeResponseHandler.class).in(Scopes.SINGLETON);
bind(DescribeImagesResponseHandler.class).to(NovaDescribeImagesResponseHandler.class);

View File

@ -0,0 +1,51 @@
/**
* 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.internal;
import java.util.Date;
import javax.inject.Singleton;
import org.jclouds.date.DateService;
import org.jclouds.date.internal.DateServiceDateCodecFactory.DateServiceIso8601Codec;
import com.google.common.base.Objects;
import com.google.inject.Inject;
@Singleton
public class HyphenToNullIso8601Codec extends DateServiceIso8601Codec {
@Inject
public HyphenToNullIso8601Codec(DateService dateService) {
super(dateService);
}
@Override
public Date toDate(String date) throws IllegalArgumentException {
if (Objects.equal("-", date))
return null;
return super.toDate(date);
}
@Override
public String toString() {
return "hyphenToNullIso8601()";
}
}

View File

@ -18,15 +18,32 @@
*/
package org.jclouds.openstack.nova.ec2.xml;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.Volume;
import org.jclouds.ec2.xml.CreateVolumeResponseHandler;
import org.jclouds.location.Region;
import org.jclouds.location.Zone;
import com.google.common.base.Supplier;
/**
*
* @author Adam lowe
*/
public class NovaCreateVolumeResponseHandler extends CreateVolumeResponseHandler {
@Inject
protected NovaCreateVolumeResponseHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
@Zone Supplier<Map<String, Supplier<Set<String>>>> regionToZonesSupplier,
@Zone Supplier<Set<String>> zonesSupplier) {
super(dateCodecFactory, defaultRegion, regionToZonesSupplier, zonesSupplier);
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("status")) {

View File

@ -26,7 +26,7 @@ import java.util.Set;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.location.Region;
@ -53,9 +53,9 @@ public class AWSDescribeInstancesResponseHandler extends
private String value;
@Inject
AWSDescribeInstancesResponseHandler(DateService dateService, @Region Supplier<String> defaultRegion,
AWSDescribeInstancesResponseHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
Provider<AWSRunningInstance.Builder> builderProvider, TagSetHandler tagSetHandler) {
super(dateService, defaultRegion, builderProvider);
super(dateCodecFactory, defaultRegion, builderProvider);
}
@Override

View File

@ -21,7 +21,7 @@ package org.jclouds.aws.ec2.xml;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Reservation;
import org.jclouds.ec2.domain.RunningInstance;
import org.jclouds.location.Region;
@ -40,9 +40,9 @@ import com.google.inject.Provider;
public class AWSRunInstancesResponseHandler extends BaseAWSReservationHandler<Reservation<? extends RunningInstance>> {
@Inject
AWSRunInstancesResponseHandler(DateService dateService, @Region Supplier<String> defaultRegion,
AWSRunInstancesResponseHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
Provider<AWSRunningInstance.Builder> builderProvider) {
super(dateService, defaultRegion, builderProvider);
super(dateCodecFactory, defaultRegion, builderProvider);
}
@Override

View File

@ -31,7 +31,8 @@ import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.AWSRunningInstance;
import org.jclouds.aws.ec2.domain.MonitoringState;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.Attachment;
import org.jclouds.ec2.domain.BlockDevice;
import org.jclouds.ec2.domain.Hypervisor;
@ -59,14 +60,14 @@ public abstract class BaseAWSReservationHandler<T> extends HandlerForGeneratedRe
@Resource
protected Logger logger = Logger.NULL;
protected final DateService dateService;
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
protected final Provider<AWSRunningInstance.Builder> builderProvider;
@Inject
public BaseAWSReservationHandler(DateService dateService, @Region Supplier<String> defaultRegion,
public BaseAWSReservationHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
Provider<AWSRunningInstance.Builder> builderProvider) {
this.dateService = dateService;
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
this.builderProvider = builderProvider;
this.builder = builderProvider.get();
@ -170,7 +171,7 @@ public abstract class BaseAWSReservationHandler<T> extends HandlerForGeneratedRe
} else if (equalsOrSuffix(qName, "keyName")) {
builder.keyName(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "launchTime")) {
builder.launchTime(parseDate());
builder.launchTime(dateCodec.toDate(currentOrNull(currentText)));
} else if (equalsOrSuffix(qName, "availabilityZone")) {
builder.availabilityZone(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "virtualizationType")) {
@ -196,7 +197,7 @@ public abstract class BaseAWSReservationHandler<T> extends HandlerForGeneratedRe
} else if (equalsOrSuffix(qName, "status")) {
attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
} else if (equalsOrSuffix(qName, "attachTime")) {
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
attachTime = dateCodec.toDate(currentOrNull(currentText));
} else if (equalsOrSuffix(qName, "deleteOnTermination")) {
deleteOnTermination = Boolean.parseBoolean(currentText.toString().trim());
} else if (equalsOrSuffix(qName, "ebs")) {
@ -209,11 +210,7 @@ public abstract class BaseAWSReservationHandler<T> extends HandlerForGeneratedRe
}
currentText = new StringBuilder();
}
protected Date parseDate() {
return dateService.iso8601DateParse(currentOrNull(currentText));
}
protected void inItem() {
if (endOfInstanceItem()) {
refineBuilderBeforeAddingInstance();

View File

@ -23,7 +23,8 @@ import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.LaunchSpecification;
import org.jclouds.aws.ec2.domain.LaunchSpecification.Builder;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.ec2.domain.BlockDeviceMapping;
import org.jclouds.http.functions.ParseSax.HandlerForGeneratedRequestWithResult;
import org.jclouds.logging.Logger;
@ -38,14 +39,14 @@ public class LaunchSpecificationHandler extends HandlerForGeneratedRequestWithRe
@Resource
protected Logger logger = Logger.NULL;
protected final DateService dateService;
protected final DateCodec dateCodec;
protected final Builder builder;
protected final BlockDeviceMapping.Builder blockDeviceMappingBuilder;
@Inject
public LaunchSpecificationHandler(DateService dateService, LaunchSpecification.Builder builder,
public LaunchSpecificationHandler(DateCodecFactory dateCodecFactory, LaunchSpecification.Builder builder,
BlockDeviceMapping.Builder blockDeviceMappingBuilder) {
this.dateService = dateService;
this.dateCodec = dateCodecFactory.iso8601();
this.builder = builder;
this.blockDeviceMappingBuilder = blockDeviceMappingBuilder;
}

View File

@ -22,7 +22,8 @@ import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.Spot;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
@ -35,12 +36,12 @@ import com.google.common.base.Supplier;
public class SpotHandler extends ParseSax.HandlerForGeneratedRequestWithResult<Spot> {
private StringBuilder currentText = new StringBuilder();
protected final DateService dateService;
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
@Inject
public SpotHandler(DateService dateService, @Region Supplier<String> defaultRegion) {
this.dateService = dateService;
public SpotHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion) {
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
}
@ -65,7 +66,7 @@ public class SpotHandler extends ParseSax.HandlerForGeneratedRequestWithResult<S
} else if (qName.equals("spotPrice")) {
builder.spotPrice(Float.parseFloat(currentText.toString().trim()));
} else if (qName.equals("timestamp")) {
builder.timestamp(dateService.iso8601DateParse(currentText.toString().trim()));
builder.timestamp(dateCodec.toDate(currentText.toString().trim()));
}
currentText = new StringBuilder();
}

View File

@ -26,7 +26,8 @@ import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest;
import org.jclouds.aws.ec2.domain.SpotInstanceRequest.Builder;
import org.jclouds.aws.util.AWSUtils;
import org.jclouds.date.DateService;
import org.jclouds.date.DateCodec;
import org.jclouds.date.DateCodecFactory;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.location.Region;
import org.xml.sax.Attributes;
@ -41,7 +42,7 @@ import com.google.common.base.Supplier;
public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWithResult<SpotInstanceRequest> {
private StringBuilder currentText = new StringBuilder();
protected final DateService dateService;
protected final DateCodec dateCodec;
protected final Supplier<String> defaultRegion;
protected final Builder builder;
protected boolean inLaunchSpecification;
@ -50,10 +51,10 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
protected final TagSetHandler tagSetHandler;
@Inject
public SpotInstanceHandler(DateService dateService, @Region Supplier<String> defaultRegion,
public SpotInstanceHandler(DateCodecFactory dateCodecFactory, @Region Supplier<String> defaultRegion,
LaunchSpecificationHandler launchSpecificationHandler, TagSetHandler tagSetHandler,
SpotInstanceRequest.Builder builder) {
this.dateService = dateService;
this.dateCodec = dateCodecFactory.iso8601();
this.defaultRegion = defaultRegion;
this.launchSpecificationHandler = launchSpecificationHandler;
this.tagSetHandler = tagSetHandler;
@ -132,7 +133,7 @@ public class SpotInstanceHandler extends ParseSax.HandlerForGeneratedRequestWith
} else if (qName.equals("createTime")) {
String createTime = currentOrNull(currentText);
if (createTime != null)
builder.createTime(dateService.iso8601DateParse(createTime));
builder.createTime(dateCodec.toDate(createTime));
} else if (qName.equals("productDescription")) {
builder.productDescription(currentOrNull(currentText));
}