mirror of https://github.com/apache/jclouds.git
Issue 29: added attach/detach
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2532 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
c5d67c7cb3
commit
719aa3483b
|
@ -0,0 +1,144 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CreateVolume.html"
|
||||||
|
* />
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class Attachment {
|
||||||
|
public static enum Status {
|
||||||
|
ATTACHING, ATTACHED, DETACHING, DETACHED;
|
||||||
|
public String value() {
|
||||||
|
return name().toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Status fromValue(String status) {
|
||||||
|
return valueOf(checkNotNull(status, "status").toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String volumeId;
|
||||||
|
private final String instanceId;
|
||||||
|
private final String device;
|
||||||
|
private final Status status;
|
||||||
|
private final Date attachTime;
|
||||||
|
|
||||||
|
public Attachment(String volumeId, String instanceId, String device, Status status,
|
||||||
|
Date attachTime) {
|
||||||
|
this.volumeId = volumeId;
|
||||||
|
this.instanceId = instanceId;
|
||||||
|
this.device = device;
|
||||||
|
this.status = status;
|
||||||
|
this.attachTime = attachTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVolumeId() {
|
||||||
|
return volumeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstanceId() {
|
||||||
|
return instanceId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDevice() {
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getAttachTime() {
|
||||||
|
return attachTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + ((attachTime == null) ? 0 : attachTime.hashCode());
|
||||||
|
result = prime * result + ((device == null) ? 0 : device.hashCode());
|
||||||
|
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
|
||||||
|
result = prime * result + ((status == null) ? 0 : status.hashCode());
|
||||||
|
result = prime * result + ((volumeId == null) ? 0 : volumeId.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;
|
||||||
|
Attachment other = (Attachment) obj;
|
||||||
|
if (attachTime == null) {
|
||||||
|
if (other.attachTime != null)
|
||||||
|
return false;
|
||||||
|
} else if (!attachTime.equals(other.attachTime))
|
||||||
|
return false;
|
||||||
|
if (device == null) {
|
||||||
|
if (other.device != null)
|
||||||
|
return false;
|
||||||
|
} else if (!device.equals(other.device))
|
||||||
|
return false;
|
||||||
|
if (instanceId == null) {
|
||||||
|
if (other.instanceId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!instanceId.equals(other.instanceId))
|
||||||
|
return false;
|
||||||
|
if (status == null) {
|
||||||
|
if (other.status != null)
|
||||||
|
return false;
|
||||||
|
} else if (!status.equals(other.status))
|
||||||
|
return false;
|
||||||
|
if (volumeId == null) {
|
||||||
|
if (other.volumeId != null)
|
||||||
|
return false;
|
||||||
|
} else if (!volumeId.equals(other.volumeId))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Attachment [attachTime=" + attachTime + ", device=" + device + ", instanceId="
|
||||||
|
+ instanceId + ", status=" + status + ", volumeId=" + volumeId + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -60,115 +60,6 @@ public class Volume implements Comparable<Volume> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Attachment {
|
|
||||||
public static enum Status {
|
|
||||||
ATTACHING, ATTACHED, DETACHING, DETACHED;
|
|
||||||
public String value() {
|
|
||||||
return name().toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return value();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Status fromValue(String status) {
|
|
||||||
return valueOf(checkNotNull(status, "status").toUpperCase());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String volumeId;
|
|
||||||
private final String instanceId;
|
|
||||||
private final String device;
|
|
||||||
private final Status status;
|
|
||||||
private final Date attachTime;
|
|
||||||
|
|
||||||
public Attachment(String volumeId, String instanceId, String device, Status status,
|
|
||||||
Date attachTime) {
|
|
||||||
this.volumeId = volumeId;
|
|
||||||
this.instanceId = instanceId;
|
|
||||||
this.device = device;
|
|
||||||
this.status = status;
|
|
||||||
this.attachTime = attachTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getVolumeId() {
|
|
||||||
return volumeId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getInstanceId() {
|
|
||||||
return instanceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDevice() {
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Status getStatus() {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getAttachTime() {
|
|
||||||
return attachTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
final int prime = 31;
|
|
||||||
int result = 1;
|
|
||||||
result = prime * result + ((attachTime == null) ? 0 : attachTime.hashCode());
|
|
||||||
result = prime * result + ((device == null) ? 0 : device.hashCode());
|
|
||||||
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
|
|
||||||
result = prime * result + ((status == null) ? 0 : status.hashCode());
|
|
||||||
result = prime * result + ((volumeId == null) ? 0 : volumeId.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;
|
|
||||||
Attachment other = (Attachment) obj;
|
|
||||||
if (attachTime == null) {
|
|
||||||
if (other.attachTime != null)
|
|
||||||
return false;
|
|
||||||
} else if (!attachTime.equals(other.attachTime))
|
|
||||||
return false;
|
|
||||||
if (device == null) {
|
|
||||||
if (other.device != null)
|
|
||||||
return false;
|
|
||||||
} else if (!device.equals(other.device))
|
|
||||||
return false;
|
|
||||||
if (instanceId == null) {
|
|
||||||
if (other.instanceId != null)
|
|
||||||
return false;
|
|
||||||
} else if (!instanceId.equals(other.instanceId))
|
|
||||||
return false;
|
|
||||||
if (status == null) {
|
|
||||||
if (other.status != null)
|
|
||||||
return false;
|
|
||||||
} else if (!status.equals(other.status))
|
|
||||||
return false;
|
|
||||||
if (volumeId == null) {
|
|
||||||
if (other.volumeId != null)
|
|
||||||
return false;
|
|
||||||
} else if (!volumeId.equals(other.volumeId))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "Attachment [attachTime=" + attachTime + ", device=" + device + ", instanceId="
|
|
||||||
+ instanceId + ", status=" + status + ", volumeId=" + volumeId + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final int size;
|
private final int size;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed from this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* from 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 org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains options supported in the Form API for the DetachVolume operation. <h2>
|
||||||
|
* Usage</h2> The recommended way to instantiate a DetachVolumeOptions object is to statically
|
||||||
|
* import DetachVolumeOptions.Builder.* and invoke a static creation method followed by an instance
|
||||||
|
* mutator (if needed):
|
||||||
|
* <p/>
|
||||||
|
* <code>
|
||||||
|
* import static org.jclouds.aws.ec2.options.DetachVolumeOptions.Builder.*
|
||||||
|
* <p/>
|
||||||
|
* EC2Client client = // get connection
|
||||||
|
* client.getElasticBlockStoreServices().detachVolumeInRegion(Region.DEFAULT, id, fromDevice("123125").force());
|
||||||
|
* <code>
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
* @see <a
|
||||||
|
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/index.html?ApiReference-form-DetachVolume.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
public class DetachVolumeOptions extends BaseEC2RequestOptions {
|
||||||
|
/**
|
||||||
|
* The ID of the instance.
|
||||||
|
*/
|
||||||
|
public DetachVolumeOptions fromInstance(String instanceId) {
|
||||||
|
formParameters.put("InstanceId", checkNotNull(instanceId, "instanceId"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInstance() {
|
||||||
|
return getFirstFormOrNull("InstanceId");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The device name.
|
||||||
|
*/
|
||||||
|
public DetachVolumeOptions fromDevice(String device) {
|
||||||
|
formParameters.put("Device", checkNotNull(device, "device"));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDevice() {
|
||||||
|
return getFirstFormOrNull("Device");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forces detachment if the previous detachment attempt did not occur cleanly (logging into an
|
||||||
|
* instance, unmounting the volume, and detaching normally). This option can lead to data loss or
|
||||||
|
* a corrupted file system. Use this option only as a last resort to detach a volume from a
|
||||||
|
* failed instance. The instance will not have an opportunity to flush file system caches nor
|
||||||
|
* file system meta data. If you use this option, you must perform file system check and repair
|
||||||
|
* procedures.
|
||||||
|
*/
|
||||||
|
public DetachVolumeOptions force() {
|
||||||
|
formParameters.put("Force", "true");
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getForce() {
|
||||||
|
return getFirstFormOrNull("Force") != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
/**
|
||||||
|
* @see DetachVolumeOptions#fromInstance(String )
|
||||||
|
*/
|
||||||
|
public static DetachVolumeOptions fromInstance(String instance) {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
return options.fromInstance(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DetachVolumeOptions#fromDevice(String )
|
||||||
|
*/
|
||||||
|
public static DetachVolumeOptions fromDevice(String device) {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
return options.fromDevice(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see DetachVolumeOptions#force()
|
||||||
|
*/
|
||||||
|
public static DetachVolumeOptions force() {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
return options.force();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,11 +35,14 @@ import javax.ws.rs.Path;
|
||||||
|
|
||||||
import org.jclouds.aws.ec2.EC2;
|
import org.jclouds.aws.ec2.EC2;
|
||||||
import org.jclouds.aws.ec2.binders.BindVolumeIdsToIndexedFormParams;
|
import org.jclouds.aws.ec2.binders.BindVolumeIdsToIndexedFormParams;
|
||||||
|
import org.jclouds.aws.ec2.domain.Attachment;
|
||||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||||
import org.jclouds.aws.ec2.domain.Region;
|
import org.jclouds.aws.ec2.domain.Region;
|
||||||
import org.jclouds.aws.ec2.domain.Volume;
|
import org.jclouds.aws.ec2.domain.Volume;
|
||||||
import org.jclouds.aws.ec2.filters.FormSigner;
|
import org.jclouds.aws.ec2.filters.FormSigner;
|
||||||
import org.jclouds.aws.ec2.functions.RegionToEndpoint;
|
import org.jclouds.aws.ec2.functions.RegionToEndpoint;
|
||||||
|
import org.jclouds.aws.ec2.options.DetachVolumeOptions;
|
||||||
|
import org.jclouds.aws.ec2.xml.AttachmentHandler;
|
||||||
import org.jclouds.aws.ec2.xml.CreateVolumeResponseHandler;
|
import org.jclouds.aws.ec2.xml.CreateVolumeResponseHandler;
|
||||||
import org.jclouds.aws.ec2.xml.DescribeVolumesResponseHandler;
|
import org.jclouds.aws.ec2.xml.DescribeVolumesResponseHandler;
|
||||||
import org.jclouds.rest.annotations.BinderParam;
|
import org.jclouds.rest.annotations.BinderParam;
|
||||||
|
@ -107,4 +110,27 @@ public interface ElasticBlockStoreAsyncClient {
|
||||||
Future<Void> deleteVolumeInRegion(@EndpointParam(parser = RegionToEndpoint.class) Region region,
|
Future<Void> deleteVolumeInRegion(@EndpointParam(parser = RegionToEndpoint.class) Region region,
|
||||||
@FormParam("VolumeId") String volumeId);
|
@FormParam("VolumeId") String volumeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticBlockStoreClient#detachVolumeInRegion
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/")
|
||||||
|
@FormParams(keys = ACTION, values = "DetachVolume")
|
||||||
|
@XMLResponseParser(AttachmentHandler.class)
|
||||||
|
Future<Attachment> detachVolumeInRegion(
|
||||||
|
@EndpointParam(parser = RegionToEndpoint.class) Region region,
|
||||||
|
@FormParam("VolumeId") String volumeId, DetachVolumeOptions... options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see ElasticBlockStoreClient#attachVolumeInRegion
|
||||||
|
*/
|
||||||
|
@POST
|
||||||
|
@Path("/")
|
||||||
|
@FormParams(keys = ACTION, values = "AttachVolume")
|
||||||
|
@XMLResponseParser(AttachmentHandler.class)
|
||||||
|
Future<Attachment> attachVolumeInRegion(
|
||||||
|
@EndpointParam(parser = RegionToEndpoint.class) Region region,
|
||||||
|
@FormParam("VolumeId") String volumeId, @FormParam("InstanceId") String instanceId,
|
||||||
|
@FormParam("Device") String device);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,11 @@ package org.jclouds.aws.ec2.services;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.domain.Attachment;
|
||||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||||
import org.jclouds.aws.ec2.domain.Region;
|
import org.jclouds.aws.ec2.domain.Region;
|
||||||
import org.jclouds.aws.ec2.domain.Volume;
|
import org.jclouds.aws.ec2.domain.Volume;
|
||||||
|
import org.jclouds.aws.ec2.options.DetachVolumeOptions;
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,10 +119,10 @@ public interface ElasticBlockStoreClient {
|
||||||
* The ID of the volume to delete. The volume remains in the deleting state for several
|
* The ID of the volume to delete. The volume remains in the deleting state for several
|
||||||
* minutes after entering this command.
|
* minutes after entering this command.
|
||||||
*
|
*
|
||||||
* @see #describeVolumes
|
* @see #describeVolumesInRegion
|
||||||
* @see #createVolume
|
* @see #createVolumeInRegion
|
||||||
* @see #attachVolume
|
* @see #attachVolumeInRegion
|
||||||
* @see #detachVolume
|
* @see #detachVolumeInRegion
|
||||||
*
|
*
|
||||||
* @see <a href=
|
* @see <a href=
|
||||||
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteVolume.html"
|
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteVolume.html"
|
||||||
|
@ -128,4 +130,67 @@ public interface ElasticBlockStoreClient {
|
||||||
*/
|
*/
|
||||||
void deleteVolumeInRegion(Region region, String volumeId);
|
void deleteVolumeInRegion(Region region, String volumeId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches an Amazon EBS volume to a running instance and exposes it as the specified device.
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* <h3>Note</h3>
|
||||||
|
*
|
||||||
|
* Windows instances currently support devices xvda through xvdp. Devices xvda and xvdb are
|
||||||
|
* reserved by the operating system, xvdc is assigned to drive C:\, and, depending on the
|
||||||
|
* instance type, devices xvdd through xvde might be reserved by the instance stores. Any device
|
||||||
|
* that is not reserved can be attached to an Amazon EBS volume. For a list of devices that are
|
||||||
|
* reserved by the instance stores, go to the Amazon Elastic Compute Cloud Developer Guide or
|
||||||
|
* Amazon Elastic Compute Cloud User Guide.
|
||||||
|
*
|
||||||
|
* @param region
|
||||||
|
* region where the volume is defined
|
||||||
|
* @param volumeId
|
||||||
|
* The ID of the volume to delete. The volume remains in the deleting state for several
|
||||||
|
* minutes after entering this command.
|
||||||
|
* @param options
|
||||||
|
* options like force()
|
||||||
|
*
|
||||||
|
* @see #describeVolumesInRegion
|
||||||
|
* @see #createVolumeInRegion
|
||||||
|
* @see #attachVolumeInRegion
|
||||||
|
* @see #deleteVolumeInRegion
|
||||||
|
*
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DetachVolume.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
Attachment detachVolumeInRegion(Region region, String volumeId, DetachVolumeOptions... options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches an Amazon EBS volume to a running instance and exposes it as the specified device.
|
||||||
|
*
|
||||||
|
* <h3>Note</h3> Windows instances currently support devices xvda through xvdp. Devices xvda and
|
||||||
|
* xvdb are reserved by the operating system, xvdc is assigned to drive C:\, and, depending on
|
||||||
|
* the instance type, devices xvdd through xvde might be reserved by the instance stores. Any
|
||||||
|
* device that is not reserved can be attached to an Amazon EBS volume. For a list of devices
|
||||||
|
* that are reserved by the instance stores, go to the Amazon Elastic Compute Cloud Developer
|
||||||
|
* Guide or Amazon Elastic Compute Cloud User Guide.
|
||||||
|
*
|
||||||
|
* @param region
|
||||||
|
* region where the volume is defined
|
||||||
|
* @param volumeId
|
||||||
|
* The ID of the Amazon EBS volume. The volume and instance must be within the same
|
||||||
|
* Availability Zone and the instance must be running.
|
||||||
|
* @param instanceId
|
||||||
|
* The ID of the instance to which the volume attaches. The volume and instance must be
|
||||||
|
* within the same Availability Zone and the instance must be running.
|
||||||
|
* @param device
|
||||||
|
* Specifies how the device is exposed to the instance (e.g., /dev/sdh).
|
||||||
|
*
|
||||||
|
* @see #describeVolumesInRegion
|
||||||
|
* @see #createVolumeInRegion
|
||||||
|
* @see #detachVolumeInRegion
|
||||||
|
* @see #deleteVolumeInRegion
|
||||||
|
*
|
||||||
|
* @see <a href=
|
||||||
|
* "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-AttachVolume.html"
|
||||||
|
* />
|
||||||
|
*/
|
||||||
|
Attachment attachVolumeInRegion(Region region, String volumeId, String instanceId, String device);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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.Date;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.domain.Attachment;
|
||||||
|
import org.jclouds.date.DateService;
|
||||||
|
import org.jclouds.http.functions.ParseSax;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class AttachmentHandler extends ParseSax.HandlerWithResult<Attachment> {
|
||||||
|
private StringBuilder currentText = new StringBuilder();
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
@Inject
|
||||||
|
protected DateService dateService;
|
||||||
|
|
||||||
|
private String volumeId;
|
||||||
|
private String instanceId;
|
||||||
|
private String device;
|
||||||
|
private Attachment.Status attachmentStatus;
|
||||||
|
private Date attachTime;
|
||||||
|
|
||||||
|
public Attachment getResult() {
|
||||||
|
return new Attachment(volumeId, instanceId, device, attachmentStatus, attachTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void endElement(String uri, String name, String qName) {
|
||||||
|
if (qName.equals("volumeId")) {
|
||||||
|
volumeId = currentText.toString().trim();
|
||||||
|
|
||||||
|
} else if (qName.equals("volumeId")) {
|
||||||
|
volumeId = currentText.toString().trim();
|
||||||
|
|
||||||
|
} else if (qName.equals("status")) {
|
||||||
|
attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
|
||||||
|
} else if (qName.equals("instanceId")) {
|
||||||
|
instanceId = currentText.toString().trim();
|
||||||
|
} else if (qName.equals("device")) {
|
||||||
|
device = currentText.toString().trim();
|
||||||
|
} else if (qName.equals("attachTime")) {
|
||||||
|
attachTime = dateService.iso8601DateParse(currentText.toString().trim());
|
||||||
|
}
|
||||||
|
currentText = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void characters(char ch[], int start, int length) {
|
||||||
|
currentText.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,9 +29,9 @@ import java.util.Set;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.domain.Attachment;
|
||||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||||
import org.jclouds.aws.ec2.domain.Volume;
|
import org.jclouds.aws.ec2.domain.Volume;
|
||||||
import org.jclouds.aws.ec2.domain.Volume.Attachment;
|
|
||||||
import org.jclouds.date.DateService;
|
import org.jclouds.date.DateService;
|
||||||
import org.jclouds.http.functions.ParseSax;
|
import org.jclouds.http.functions.ParseSax;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
@ -62,7 +62,7 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerWithResult<Volu
|
||||||
private String volumeId;
|
private String volumeId;
|
||||||
private String instanceId;
|
private String instanceId;
|
||||||
private String device;
|
private String device;
|
||||||
private Volume.Attachment.Status attachmentStatus;
|
private Attachment.Status attachmentStatus;
|
||||||
private Date attachTime;
|
private Date attachTime;
|
||||||
|
|
||||||
private boolean inAttachmentSet;
|
private boolean inAttachmentSet;
|
||||||
|
@ -102,7 +102,7 @@ public class CreateVolumeResponseHandler extends ParseSax.HandlerWithResult<Volu
|
||||||
}
|
}
|
||||||
} else if (qName.equals("status")) {
|
} else if (qName.equals("status")) {
|
||||||
if (inAttachmentSet) {
|
if (inAttachmentSet) {
|
||||||
attachmentStatus = Volume.Attachment.Status.fromValue(currentText.toString().trim());
|
attachmentStatus = Attachment.Status.fromValue(currentText.toString().trim());
|
||||||
} else {
|
} else {
|
||||||
volumeStatus = Volume.Status.fromValue(currentText.toString().trim());
|
volumeStatus = Volume.Status.fromValue(currentText.toString().trim());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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.DetachVolumeOptions.Builder.force;
|
||||||
|
import static org.jclouds.aws.ec2.options.DetachVolumeOptions.Builder.fromDevice;
|
||||||
|
import static org.jclouds.aws.ec2.options.DetachVolumeOptions.Builder.fromInstance;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.jclouds.http.options.HttpRequestOptions;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests possible uses of DetachVolumeOptions and DetachVolumeOptions.Builder.*
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
public class DetachVolumeOptionsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAssignability() {
|
||||||
|
assert HttpRequestOptions.class.isAssignableFrom(DetachVolumeOptions.class);
|
||||||
|
assert !String.class.isAssignableFrom(DetachVolumeOptions.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromDevice() {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
options.fromDevice("test");
|
||||||
|
assertEquals(options.buildFormParameters().get("Device"), Collections.singletonList("test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFromDevice() {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
assertEquals(options.buildFormParameters().get("Device"), Collections.EMPTY_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromDeviceStatic() {
|
||||||
|
DetachVolumeOptions options = fromDevice("test");
|
||||||
|
assertEquals(options.buildFormParameters().get("Device"), Collections.singletonList("test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
|
public void testFromDeviceNPE() {
|
||||||
|
fromDevice(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromInstance() {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
options.fromInstance("test");
|
||||||
|
assertEquals(options.buildFormParameters().get("InstanceId"), Collections
|
||||||
|
.singletonList("test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNullFromInstance() {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
assertEquals(options.buildFormParameters().get("InstanceId"), Collections.EMPTY_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromInstanceStatic() {
|
||||||
|
DetachVolumeOptions options = fromInstance("test");
|
||||||
|
assertEquals(options.buildFormParameters().get("InstanceId"), Collections
|
||||||
|
.singletonList("test"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = NullPointerException.class)
|
||||||
|
public void testFromInstanceNPE() {
|
||||||
|
fromInstance(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForce() {
|
||||||
|
DetachVolumeOptions options = new DetachVolumeOptions();
|
||||||
|
options.force();
|
||||||
|
assertEquals(options.buildFormParameters().get("Force"), Collections.singletonList("true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testForceStatic() {
|
||||||
|
DetachVolumeOptions options = force();
|
||||||
|
assertEquals(options.buildFormParameters().get("Force"), Collections.singletonList("true"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,6 +23,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.aws.ec2.services;
|
package org.jclouds.aws.ec2.services;
|
||||||
|
|
||||||
|
import static org.jclouds.aws.ec2.options.DetachVolumeOptions.Builder.fromInstance;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -37,6 +38,8 @@ import org.jclouds.aws.ec2.EC2;
|
||||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||||
import org.jclouds.aws.ec2.domain.Region;
|
import org.jclouds.aws.ec2.domain.Region;
|
||||||
import org.jclouds.aws.ec2.filters.FormSigner;
|
import org.jclouds.aws.ec2.filters.FormSigner;
|
||||||
|
import org.jclouds.aws.ec2.options.DetachVolumeOptions;
|
||||||
|
import org.jclouds.aws.ec2.xml.AttachmentHandler;
|
||||||
import org.jclouds.aws.ec2.xml.CreateVolumeResponseHandler;
|
import org.jclouds.aws.ec2.xml.CreateVolumeResponseHandler;
|
||||||
import org.jclouds.aws.ec2.xml.DescribeVolumesResponseHandler;
|
import org.jclouds.aws.ec2.xml.DescribeVolumesResponseHandler;
|
||||||
import org.jclouds.aws.reference.AWSConstants;
|
import org.jclouds.aws.reference.AWSConstants;
|
||||||
|
@ -160,6 +163,66 @@ public class ElasticBlockStoreAsyncClientTest extends RestClientTest<ElasticBloc
|
||||||
checkFilters(httpMethod);
|
checkFilters(httpMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAttachVolume() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
|
Method method = ElasticBlockStoreAsyncClient.class.getMethod("attachVolumeInRegion",
|
||||||
|
Region.class, String.class, String.class, String.class);
|
||||||
|
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
|
||||||
|
method, Region.DEFAULT, "id", "instanceId", "/device");
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
|
||||||
|
assertHeadersEqual(httpMethod,
|
||||||
|
"Content-Length: 89\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
|
||||||
|
assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=AttachVolume&InstanceId=instanceId&VolumeId=id&Device=%2Fdevice");
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, AttachmentHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDetachVolume() throws SecurityException, NoSuchMethodException, IOException {
|
||||||
|
Method method = ElasticBlockStoreAsyncClient.class.getMethod("detachVolumeInRegion",
|
||||||
|
Region.class, String.class, Array.newInstance(DetachVolumeOptions.class, 0)
|
||||||
|
.getClass());
|
||||||
|
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
|
||||||
|
method, Region.DEFAULT, "id");
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
|
||||||
|
assertHeadersEqual(httpMethod,
|
||||||
|
"Content-Length: 50\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
|
||||||
|
assertPayloadEquals(httpMethod, "Version=2009-11-30&Action=DetachVolume&VolumeId=id");
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, AttachmentHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDetachVolumeOptions() throws SecurityException, NoSuchMethodException,
|
||||||
|
IOException {
|
||||||
|
Method method = ElasticBlockStoreAsyncClient.class.getMethod("detachVolumeInRegion",
|
||||||
|
Region.class, String.class, Array.newInstance(DetachVolumeOptions.class, 0)
|
||||||
|
.getClass());
|
||||||
|
GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod = processor.createRequest(
|
||||||
|
method, Region.DEFAULT, "id", fromInstance("instanceId").fromDevice("/device")
|
||||||
|
.force());
|
||||||
|
|
||||||
|
assertRequestLineEquals(httpMethod, "POST https://ec2.amazonaws.com/ HTTP/1.1");
|
||||||
|
assertHeadersEqual(httpMethod,
|
||||||
|
"Content-Length: 100\nContent-Type: application/x-www-form-urlencoded\nHost: ec2.amazonaws.com\n");
|
||||||
|
assertPayloadEquals(
|
||||||
|
httpMethod,
|
||||||
|
"Version=2009-11-30&Action=DetachVolume&VolumeId=id&InstanceId=instanceId&Device=%2Fdevice&Force=true");
|
||||||
|
|
||||||
|
assertResponseParserClassEquals(method, httpMethod, ParseSax.class);
|
||||||
|
assertSaxResponseParserClassEquals(method, AttachmentHandler.class);
|
||||||
|
assertExceptionParserClassEquals(method, null);
|
||||||
|
|
||||||
|
checkFilters(httpMethod);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void checkFilters(GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod) {
|
protected void checkFilters(GeneratedHttpRequest<ElasticBlockStoreAsyncClient> httpMethod) {
|
||||||
assertEquals(httpMethod.getFilters().size(), 1);
|
assertEquals(httpMethod.getFilters().size(), 1);
|
||||||
|
|
|
@ -123,6 +123,16 @@ public class ElasticBlockStoreClientLiveTest {
|
||||||
// assertEquals(volume, result);
|
// assertEquals(volume, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAttachVolumeInRegion() {
|
||||||
|
// TODO: need an instance
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDetachVolumeInRegion() {
|
||||||
|
// TODO: need an instance
|
||||||
|
}
|
||||||
|
|
||||||
@AfterTest
|
@AfterTest
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
context.close();
|
context.close();
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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 org.jclouds.aws.ec2.domain.Attachment;
|
||||||
|
import org.jclouds.date.DateService;
|
||||||
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code AttachmentHandler}
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Test(groups = "unit", testName = "ec2.AttachmentHandlerTest")
|
||||||
|
public class AttachmentHandlerTest extends BaseHandlerTest {
|
||||||
|
public void testApplyInputStream() {
|
||||||
|
DateService dateService = injector.getInstance(DateService.class);
|
||||||
|
InputStream is = getClass().getResourceAsStream("/ec2/attach.xml");
|
||||||
|
|
||||||
|
Attachment expected = new Attachment("vol-4d826724", "i-6058a509", "/dev/sdh",
|
||||||
|
Attachment.Status.ATTACHING, dateService
|
||||||
|
.iso8601DateParse("2008-05-07T11:51:50.000Z"));
|
||||||
|
Attachment result = factory.create(injector.getInstance(AttachmentHandler.class)).parse(is);
|
||||||
|
|
||||||
|
assertEquals(result, expected);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,9 +27,9 @@ import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.domain.Attachment;
|
||||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||||
import org.jclouds.aws.ec2.domain.Volume;
|
import org.jclouds.aws.ec2.domain.Volume;
|
||||||
import org.jclouds.aws.ec2.domain.Volume.Attachment;
|
|
||||||
import org.jclouds.date.DateService;
|
import org.jclouds.date.DateService;
|
||||||
import org.jclouds.http.functions.BaseHandlerTest;
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
|
@ -28,9 +28,9 @@ import static org.testng.Assert.assertEquals;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.domain.Attachment;
|
||||||
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
import org.jclouds.aws.ec2.domain.AvailabilityZone;
|
||||||
import org.jclouds.aws.ec2.domain.Volume;
|
import org.jclouds.aws.ec2.domain.Volume;
|
||||||
import org.jclouds.aws.ec2.domain.Volume.Attachment;
|
|
||||||
import org.jclouds.date.DateService;
|
import org.jclouds.date.DateService;
|
||||||
import org.jclouds.http.functions.BaseHandlerTest;
|
import org.jclouds.http.functions.BaseHandlerTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -55,7 +55,7 @@ public class DescribeVolumesResponseHandlerTest extends BaseHandlerTest {
|
||||||
expected.add(new Volume("vol-4282672b", 800, null, AvailabilityZone.US_EAST_1A,
|
expected.add(new Volume("vol-4282672b", 800, null, AvailabilityZone.US_EAST_1A,
|
||||||
Volume.Status.IN_USE, dateService.iso8601DateParse("2008-05-07T11:51:50.000Z"), Sets
|
Volume.Status.IN_USE, dateService.iso8601DateParse("2008-05-07T11:51:50.000Z"), Sets
|
||||||
.<Attachment> newHashSet(new Attachment("vol-4282672b", "i-6058a509",
|
.<Attachment> newHashSet(new Attachment("vol-4282672b", "i-6058a509",
|
||||||
"/dev/sdh", Volume.Attachment.Status.ATTACHED, dateService
|
"/dev/sdh", Attachment.Status.ATTACHED, dateService
|
||||||
.iso8601DateParse("2008-05-07T12:51:50.000Z")))));
|
.iso8601DateParse("2008-05-07T12:51:50.000Z")))));
|
||||||
Set<Volume> result = factory.create(
|
Set<Volume> result = factory.create(
|
||||||
injector.getInstance(DescribeVolumesResponseHandler.class)).parse(is);
|
injector.getInstance(DescribeVolumesResponseHandler.class)).parse(is);
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<AttachVolumeResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
|
||||||
|
<volumeId>vol-4d826724</volumeId>
|
||||||
|
<instanceId>i-6058a509</instanceId>
|
||||||
|
<device>/dev/sdh</device>
|
||||||
|
<status>attaching</status>
|
||||||
|
<attachTime>2008-05-07T11:51:50.000Z</attachTime>
|
||||||
|
</AttachVolumeResponse>
|
Loading…
Reference in New Issue