added windows bundling functionality to ec2

This commit is contained in:
Adrian Cole 2010-07-17 10:57:46 -05:00
parent 1bc44bf36a
commit f7df4af65b
24 changed files with 1524 additions and 25 deletions

View File

@ -26,6 +26,7 @@ import org.jclouds.aws.ec2.services.InstanceAsyncClient;
import org.jclouds.aws.ec2.services.KeyPairAsyncClient;
import org.jclouds.aws.ec2.services.MonitoringAsyncClient;
import org.jclouds.aws.ec2.services.SecurityGroupAsyncClient;
import org.jclouds.aws.ec2.services.WindowsAsyncClient;
import org.jclouds.rest.annotations.Delegate;
/**
@ -72,6 +73,12 @@ public interface EC2AsyncClient {
@Delegate
MonitoringAsyncClient getMonitoringServices();
/**
* Provides asynchronous access to Windows services.
*/
@Delegate
WindowsAsyncClient getWindowsServices();
/**
* Provides asynchronous access to Availability Zones and Regions services.
*/

View File

@ -28,6 +28,7 @@ import org.jclouds.aws.ec2.services.InstanceClient;
import org.jclouds.aws.ec2.services.KeyPairClient;
import org.jclouds.aws.ec2.services.MonitoringClient;
import org.jclouds.aws.ec2.services.SecurityGroupClient;
import org.jclouds.aws.ec2.services.WindowsClient;
import org.jclouds.concurrent.Timeout;
import org.jclouds.rest.annotations.Delegate;
@ -74,6 +75,12 @@ public interface EC2Client {
@Delegate
MonitoringClient getMonitoringServices();
/**
* Provides asynchronous access to Windows services.
*/
@Delegate
WindowsClient getWindowsServices();
/**
* Provides synchronous access to Availability Zones and Regions services.
*/

View File

@ -0,0 +1,40 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.binders;
import static org.jclouds.aws.ec2.util.EC2Utils.indexStringArrayToFormValuesWithPrefix;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
* Binds the String [] to form parameters named with BundleId.index
*
* @author Adrian Cole
*/
@Singleton
public class BindBundleIdsToIndexedFormParams implements Binder {
public void bindToRequest(HttpRequest request, Object input) {
indexStringArrayToFormValuesWithPrefix(request, "BundleId", input);
}
}

View File

@ -0,0 +1,54 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.binders;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.http.HttpUtils.addFormParamTo;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.encryption.EncryptionService;
import org.jclouds.http.HttpRequest;
import org.jclouds.rest.Binder;
/**
*
* @author Adrian Cole
*/
@Singleton
public class BindS3UploadPolicyAndSignature implements Binder {
private final FormSigner signer;
private final EncryptionService encryptionService;
@Inject
BindS3UploadPolicyAndSignature(FormSigner signer, EncryptionService encryptionService) {
this.signer = signer;
this.encryptionService = encryptionService;
}
public void bindToRequest(HttpRequest request, Object input) {
String encodedJson = encryptionService.base64(checkNotNull(input, "json").toString().getBytes());
addFormParamTo(request, "Storage.S3.UploadPolicy", encodedJson);
String signature = signer.sign(encodedJson);
addFormParamTo(request, "Storage.S3.UploadPolicySignature", signature);
}
}

View File

@ -44,6 +44,8 @@ import org.jclouds.aws.ec2.services.MonitoringAsyncClient;
import org.jclouds.aws.ec2.services.MonitoringClient;
import org.jclouds.aws.ec2.services.SecurityGroupAsyncClient;
import org.jclouds.aws.ec2.services.SecurityGroupClient;
import org.jclouds.aws.ec2.services.WindowsAsyncClient;
import org.jclouds.aws.ec2.services.WindowsClient;
import org.jclouds.http.RequiresHttp;
import org.jclouds.rest.ConfiguresRestClient;
@ -61,17 +63,17 @@ import com.google.inject.Provides;
@ConfiguresRestClient
public class EC2RestClientModule extends AWSFormSigningRestClientModule<EC2Client, EC2AsyncClient> {
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap
.<Class<?>, Class<?>> builder()//
.put(AMIClient.class, AMIAsyncClient.class)//
.put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)//
.put(InstanceClient.class, InstanceAsyncClient.class)//
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
.put(MonitoringClient.class, MonitoringAsyncClient.class)//
.put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)//
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
.build();
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()//
.put(AMIClient.class, AMIAsyncClient.class)//
.put(ElasticIPAddressClient.class, ElasticIPAddressAsyncClient.class)//
.put(InstanceClient.class, InstanceAsyncClient.class)//
.put(KeyPairClient.class, KeyPairAsyncClient.class)//
.put(SecurityGroupClient.class, SecurityGroupAsyncClient.class)//
.put(MonitoringClient.class, MonitoringAsyncClient.class)//
.put(WindowsClient.class, WindowsAsyncClient.class)//
.put(AvailabilityZoneAndRegionClient.class, AvailabilityZoneAndRegionAsyncClient.class)//
.put(ElasticBlockStoreClient.class, ElasticBlockStoreAsyncClient.class)//
.build();
public EC2RestClientModule() {
super(EC2Client.class, EC2AsyncClient.class, DELEGATE_MAP);
@ -99,12 +101,11 @@ public class EC2RestClientModule extends AWSFormSigningRestClientModule<EC2Clien
@Provides
@Singleton
protected Map<String, String> provideAvailabilityZoneToRegions(EC2Client client,
@Region Map<String, URI> regions) {
protected Map<String, String> provideAvailabilityZoneToRegions(EC2Client client, @Region Map<String, URI> regions) {
Map<String, String> map = Maps.newHashMap();
for (String region : regions.keySet()) {
for (AvailabilityZoneInfo zoneInfo : client.getAvailabilityZoneAndRegionServices()
.describeAvailabilityZonesInRegion(region)) {
.describeAvailabilityZonesInRegion(region)) {
map.put(zoneInfo.getZone(), region);
}
}

View File

@ -0,0 +1,152 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import javax.annotation.Nullable;
/**
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-BundleInstanceS3StorageType.html"
* />
* @author Adrian Cole
*/
public class BundleInstanceS3Storage {
private final String awsAccessKeyId;
private final String bucket;
private final String prefix;
private final String secretAccessKey;
private final String uploadPolicy;
private final String uploadPolicySignature;
public BundleInstanceS3Storage(@Nullable String awsAccessKeyId, String bucket, String prefix,
@Nullable String secretAccessKey, @Nullable String uploadPolicy, @Nullable String uploadPolicySignature) {
this.awsAccessKeyId = awsAccessKeyId;
this.bucket = checkNotNull(bucket, "bucket");
this.prefix = checkNotNull(prefix, "prefix");
this.secretAccessKey = secretAccessKey;
this.uploadPolicy = uploadPolicy;
this.uploadPolicySignature = uploadPolicySignature;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((awsAccessKeyId == null) ? 0 : awsAccessKeyId.hashCode());
result = prime * result + ((bucket == null) ? 0 : bucket.hashCode());
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
result = prime * result + ((secretAccessKey == null) ? 0 : secretAccessKey.hashCode());
result = prime * result + ((uploadPolicy == null) ? 0 : uploadPolicy.hashCode());
result = prime * result + ((uploadPolicySignature == null) ? 0 : uploadPolicySignature.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;
BundleInstanceS3Storage other = (BundleInstanceS3Storage) obj;
if (awsAccessKeyId == null) {
if (other.awsAccessKeyId != null)
return false;
} else if (!awsAccessKeyId.equals(other.awsAccessKeyId))
return false;
if (bucket == null) {
if (other.bucket != null)
return false;
} else if (!bucket.equals(other.bucket))
return false;
if (prefix == null) {
if (other.prefix != null)
return false;
} else if (!prefix.equals(other.prefix))
return false;
if (secretAccessKey == null) {
if (other.secretAccessKey != null)
return false;
} else if (!secretAccessKey.equals(other.secretAccessKey))
return false;
if (uploadPolicy == null) {
if (other.uploadPolicy != null)
return false;
} else if (!uploadPolicy.equals(other.uploadPolicy))
return false;
if (uploadPolicySignature == null) {
if (other.uploadPolicySignature != null)
return false;
} else if (!uploadPolicySignature.equals(other.uploadPolicySignature))
return false;
return true;
}
@Override
public String toString() {
return "[awsAccessKeyId=" + awsAccessKeyId + ", bucket=" + bucket + ", prefix=" + prefix + ", secreAccessKey="
+ secretAccessKey + ", uploadPolicy=" + uploadPolicy + ", uploadPolicySignature=" + uploadPolicySignature
+ "]";
}
/**
*
* @returnThe bucket in which to store the AMI. You can specify a bucket that
* you already own or a new bucket that Amazon EC2 creates on your
* behalf. If you specify a bucket that belongs to someone else,
* Amazon EC2 returns an error.
*/
public String getBucket() {
return bucket;
}
/**
*
* @return Specifies the beginning of the file name of the AMI.
*/
public String getPrefix() {
return prefix;
}
/**
*
* @return An Amazon S3 upload policy that gives Amazon EC2 permission to
* upload items into Amazon S3 on the user's behalf. For more
* information on bundling in Windows, go to the Amazon Elastic
* Compute Cloud Developer Guide and Amazon Elastic Compute Cloud
* Getting Started
*/
public String getUploadPolicy() {
return uploadPolicy;
}
/**
*
* @return The signature of the Base64 encoded JSON document.
*/
public String getUploadPolicySignature() {
return uploadPolicySignature;
}
}

View File

@ -0,0 +1,294 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Date;
import javax.annotation.Nullable;
/**
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-BundleInstanceTaskType.html"
* />
* @author Adrian Cole
*/
public class BundleTask implements Comparable<BundleTask> {
/**
* {@inheritDoc}
*/
public int compareTo(BundleTask o) {
return (this == o) ? 0 : getBundleId().compareTo(o.getBundleId());
}
/**
* If the task fails, a description of the error.
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-BundleInstanceTaskErrorType.html"
* />
* @author Adrian Cole
*/
public static class Error {
private final String code;
private final String message;
public Error(String code, String message) {
this.code = checkNotNull(code, "code");
this.message = checkNotNull(message, "message");
}
public String getCode() {
return code;
}
public String getMessage() {
return message;
}
@Override
public String toString() {
return "[code=" + code + ", message=" + message + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((code == null) ? 0 : code.hashCode());
result = prime * result + ((message == null) ? 0 : message.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;
Error other = (Error) obj;
if (code == null) {
if (other.code != null)
return false;
} else if (!code.equals(other.code))
return false;
if (message == null) {
if (other.message != null)
return false;
} else if (!message.equals(other.message))
return false;
return true;
}
}
private final String region;
private final String bundleId;
private final Error error;
private final String instanceId;
private final int progress;
private final Date startTime;
private final String state;
private final String bucket;
private final String prefix;
private final Date updateTime;
public BundleTask(String region, String bundleId, @Nullable Error error, String instanceId, int progress,
Date startTime, String state, String bucket, String prefix, Date updateTime) {
this.region = checkNotNull(region, "region");
this.bundleId = checkNotNull(bundleId, "bundleId");
this.error = error;
this.instanceId = checkNotNull(instanceId, "instanceId");
this.progress = checkNotNull(progress, "progress");
this.startTime = checkNotNull(startTime, "startTime");
this.state = checkNotNull(state, "state");
this.bucket = checkNotNull(bucket, "bucket");
this.prefix = checkNotNull(prefix, "prefix");
this.updateTime = checkNotNull(updateTime, "updateTime");
}
@Override
public String toString() {
return "[bucket=" + bucket + ", bundleId=" + bundleId + ", error=" + error + ", instanceId=" + instanceId
+ ", prefix=" + prefix + ", progress=" + progress + ", region=" + region + ", startTime=" + startTime
+ ", state=" + state + ", updateTime=" + updateTime + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bucket == null) ? 0 : bucket.hashCode());
result = prime * result + ((bundleId == null) ? 0 : bundleId.hashCode());
result = prime * result + ((error == null) ? 0 : error.hashCode());
result = prime * result + ((instanceId == null) ? 0 : instanceId.hashCode());
result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
result = prime * result + progress;
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((startTime == null) ? 0 : startTime.hashCode());
result = prime * result + ((state == null) ? 0 : state.hashCode());
result = prime * result + ((updateTime == null) ? 0 : updateTime.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;
BundleTask other = (BundleTask) obj;
if (bucket == null) {
if (other.bucket != null)
return false;
} else if (!bucket.equals(other.bucket))
return false;
if (bundleId == null) {
if (other.bundleId != null)
return false;
} else if (!bundleId.equals(other.bundleId))
return false;
if (error == null) {
if (other.error != null)
return false;
} else if (!error.equals(other.error))
return false;
if (instanceId == null) {
if (other.instanceId != null)
return false;
} else if (!instanceId.equals(other.instanceId))
return false;
if (prefix == null) {
if (other.prefix != null)
return false;
} else if (!prefix.equals(other.prefix))
return false;
if (progress != other.progress)
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (startTime == null) {
if (other.startTime != null)
return false;
} else if (!startTime.equals(other.startTime))
return false;
if (state == null) {
if (other.state != null)
return false;
} else if (!state.equals(other.state))
return false;
if (updateTime == null) {
if (other.updateTime != null)
return false;
} else if (!updateTime.equals(other.updateTime))
return false;
return true;
}
/**
*
* @return region of the bundle task
*/
public String getRegion() {
return region;
}
/**
*
* @return The bucket in which to store the AMI. You can specify a bucket
* that you already own or a new bucket that Amazon EC2 creates on
* your behalf. If you specify a bucket that belongs to someone e
* lse, Amazon EC2 returns an error.
*/
public String getBucket() {
return bucket;
}
/**
*
* @return Specifies the beginning of the file name of the AMI.
*/
public String getPrefix() {
return prefix;
}
/**
*
* @return Identifier for this task.
*/
public String getBundleId() {
return bundleId;
}
/**
*
* @return If the task fails, a description of the error.
*/
public Error getError() {
return error;
}
/**
*
* @return Instance associated with this bundle task
*/
public String getInstanceId() {
return instanceId;
}
/**
*
* @return A percentage description of the progress of the task, such as 20.
*/
public int getProgress() {
return progress;
}
/**
*
* @return The time this task started.
*/
public Date getStartTime() {
return startTime;
}
/**
*
* @return The state of the task.
*/
public String getState() {
return state;
}
/**
*
* @return The time of the most recent update for the task.
*/
public Date getUpdateTime() {
return updateTime;
}
}

View File

@ -0,0 +1,95 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.Constants.PROPERTY_IDENTITY;
import javax.inject.Named;
import org.jclouds.aws.ec2.options.internal.BaseEC2RequestOptions;
import com.google.common.collect.Multimap;
import com.google.inject.Inject;
/**
* Contains options supported in the Form API for the RegisterImage operation.
* <h2>
* Usage</h2> The recommended way to instantiate a
* BundleInstanceS3StorageOptions object is to statically import
* BundleInstanceS3StorageOptions.Builder.* and invoke a static creation method
* followed by an instance mutator (if needed):
* <p/>
* <code>
* import static org.jclouds.aws.ec2.options.BundleInstanceS3StorageOptions.Builder.*
* <p/>
* EC2Client connection = // get connection
* String imageId = connection.getWindowsServices().bundleInstanceInRegion(...bucketOwnedBy(anotherAccessKey));
* <code>
*
* @author Adrian Cole
* @see <a
* href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-BundleInstance.html"
* />
*/
public class BundleInstanceS3StorageOptions extends BaseEC2RequestOptions {
@Inject(optional = true)
@Named(PROPERTY_IDENTITY)
String currentAwsAccessKeyId;
@Override
public Multimap<String, String> buildFormParameters() {
if (getAwsAccessKeyId() == null) {
checkState(currentAwsAccessKeyId != null, "currentAwsAccessKeyId should have been injected");
bucketOwnedBy(currentAwsAccessKeyId);
}
return super.buildFormParameters();
}
/**
*
* @param awsAccessKeyId
* The Access Key ID of the owner of the Amazon S3 bucket.
*/
public BundleInstanceS3StorageOptions bucketOwnedBy(String awsAccessKeyId) {
formParameters.put("Storage.S3.AWSAccessKeyId", checkNotNull(awsAccessKeyId, "awsAccessKeyId"));
return this;
}
/**
*
* @return The Access Key ID of the owner of the Amazon S3 bucket.
*/
public String getAwsAccessKeyId() {
return getFirstFormOrNull("Storage.S3.AWSAccessKeyId");
}
public static class Builder {
/**
* @see BundleInstanceS3StorageOptions#bucketOwnedBy(awsAccessKeyId)
*/
public static BundleInstanceS3StorageOptions bucketOwnedBy(String awsAccessKeyId) {
BundleInstanceS3StorageOptions options = new BundleInstanceS3StorageOptions();
return options.bucketOwnedBy(awsAccessKeyId);
}
}
}

View File

@ -0,0 +1,95 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.services;
import static org.jclouds.aws.ec2.reference.EC2Parameters.ACTION;
import static org.jclouds.aws.ec2.reference.EC2Parameters.VERSION;
import java.util.Set;
import javax.annotation.Nullable;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.binders.BindBundleIdsToIndexedFormParams;
import org.jclouds.aws.ec2.binders.BindS3UploadPolicyAndSignature;
import org.jclouds.aws.ec2.domain.BundleTask;
import org.jclouds.aws.ec2.options.BundleInstanceS3StorageOptions;
import org.jclouds.aws.ec2.xml.BundleTaskHandler;
import org.jclouds.aws.ec2.xml.DescribeBundleTasksResponseHandler;
import org.jclouds.aws.filters.FormSigner;
import org.jclouds.aws.functions.RegionToEndpoint;
import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.EndpointParam;
import org.jclouds.rest.annotations.FormParams;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.VirtualHost;
import org.jclouds.rest.annotations.XMLResponseParser;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Provides access to EC2 Windows via their REST API.
* <p/>
*
* @author Adrian Cole
*/
@RequestFilters(FormSigner.class)
@FormParams(keys = VERSION, values = EC2AsyncClient.VERSION)
@VirtualHost
public interface WindowsAsyncClient {
/**
* @see WindowsClient#bundleInstanceInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "BundleInstance")
@XMLResponseParser(BundleTaskHandler.class)
ListenableFuture<BundleTask> bundleInstanceInRegion(
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region,
@FormParam("InstanceId") String instanceId, @FormParam("Storage.S3.Prefix") String prefix,
@FormParam("Storage.S3.Bucket") String bucket,
@BinderParam(BindS3UploadPolicyAndSignature.class) String uploadPolicy,
BundleInstanceS3StorageOptions... options);
/**
* @see WindowsClient#cancelBundleTaskInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "CancelBundleTask")
@XMLResponseParser(BundleTaskHandler.class)
ListenableFuture<BundleTask> cancelBundleTaskInRegion(
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region, @FormParam("BundleId") String bundleId);
/**
* @see BundleTaskClient#describeBundleTasksInRegion
*/
@POST
@Path("/")
@FormParams(keys = ACTION, values = "DescribeBundleTasks")
@XMLResponseParser(DescribeBundleTasksResponseHandler.class)
ListenableFuture<? extends Set<BundleTask>> describeBundleTasksInRegion(
@EndpointParam(parser = RegionToEndpoint.class) @Nullable String region,
@BinderParam(BindBundleIdsToIndexedFormParams.class) String... bundleTaskIds);
}

View File

@ -0,0 +1,113 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.services;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.aws.ec2.domain.BundleTask;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.options.BundleInstanceS3StorageOptions;
import org.jclouds.concurrent.Timeout;
/**
* Provides windows services for EC2. For more information, refer to the Amazon
* EC2 Developer Guide.
* <p/>
*
* @author Adrian Cole
*/
@Timeout(duration = 45, timeUnit = TimeUnit.SECONDS)
public interface WindowsClient {
/**
* Bundles the Windows instance. This procedure is not applicable for Linux
* and UNIX instances. For more information, go to the Amazon Elastic Compute
* Cloud Developer Guide or Amazon Elastic Compute Cloud Getting Started
* Guide.
*
* @param region
* Bundles are tied to the Region where its files are located
* within Amazon S3.
*
* @param instanceId
* The ID of the instance to bundle.
* @param prefix
* Specifies the beginning of the file name of the AMI.
* @param bucket
* The bucket in which to store the AMI. You can specify a bucket
* that you already own or a new bucket that Amazon EC2 creates on
* your behalf. If you specify a bucket that belongs to som eone
* else, Amazon EC2 returns an error.
* @param uploadPolicy
* An Amazon S3 upload policy that gives Amazon EC2 permission to
* upload items into Amazon S3 on the user's behalf.
* <p/>
* ex.
*
* <pre>
* {"expiration": "2008-08-30T08:49:09Z","conditions": ["bucket": "my-bucket"},["starts-with", "$key", "my-new-image"]]}
* </pre>
*
* @param options
* if the bucket isn't owned by you, use this to set the bucket's
* accesskeyid
* @return status of the work
*
* @see #cancelBundleTaskInRegion
* @see #describeBundleTasksInRegion
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-BundleInstance.html"
* />
*/
BundleTask bundleInstanceInRegion(@Nullable String region, String instanceId, String prefix, String bucket,
String uploadPolicy, BundleInstanceS3StorageOptions... options);
/**
* Cancels an Amazon EC2 bundling operation.
*
* @param region
* The bundleTask ID is tied to the Region.
* @param bundleId
* The ID of the bundle task to cancel.
* @return task for the cancel.
*
* @see #bundleInstanceInRegion
* @see #describeBundleTasksInRegion
*
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-CancelBundleTask.html"
* />
*/
BundleTask cancelBundleTaskInRegion(@Nullable String region, String bundleId);
/**
*
* Describes current bundling tasks.
*
* @param region
* The bundleTask ID is tied to the Region.
*
* @see #cancelBundleTaskInRegion
* @see #bundleInstanceInRegion
* @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeBundleTasks.html"
* />
*/
Set<Reservation> describeBundleTasksInRegion(@Nullable String region, String... bundleTaskIds);
}

View File

@ -61,10 +61,8 @@ public class AttachmentHandler extends ParseSax.HandlerForGeneratedRequestWithRe
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")) {

View File

@ -0,0 +1,112 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import java.util.Date;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.aws.Region;
import org.jclouds.aws.ec2.domain.BundleTask;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.logging.Logger;
import org.jclouds.rest.internal.GeneratedHttpRequest;
/**
*
* @author Adrian Cole
*/
public class BundleTaskHandler extends ParseSax.HandlerForGeneratedRequestWithResult<BundleTask> {
private StringBuilder currentText = new StringBuilder();
@Resource
protected Logger logger = Logger.NULL;
@Inject
protected DateService dateService;
@Inject
@Region
String defaultRegion;
private String bundleId;
private String code;
private String message;
private String instanceId;
private int progress = 0;
private Date startTime;
private String state;
private String bucket;
private String prefix;
private Date updateTime;
public BundleTask getResult() {
String region = EC2Utils.findRegionInArgsOrNull((GeneratedHttpRequest<?>) request);
if (region == null)
region = defaultRegion;
BundleTask.Error error = null;
if (code != null)
error = new BundleTask.Error(code, message);
BundleTask returnVal = new BundleTask(region, bundleId, error, instanceId, progress, startTime,
state, bucket, prefix, updateTime);
this.bundleId = null;
this.code = null;
this.message = null;
this.instanceId = null;
this.progress = 0;
this.startTime = null;
this.state = null;
this.bucket = null;
this.prefix = null;
this.updateTime = null;
return returnVal;
}
public void endElement(String uri, String name, String qName) {
if (qName.equals("bundleId")) {
bundleId = currentText.toString().trim();
} else if (qName.equals("code")) {
code = currentText.toString().trim();
} else if (qName.equals("message")) {
message = currentText.toString().trim();
} else if (qName.equals("instanceId")) {
instanceId = currentText.toString().trim();
} else if (qName.equals("progress")) {
String temp = currentText.toString().trim();
temp = temp.substring(0, temp.length() - 1);
progress = Integer.parseInt(temp);
} else if (qName.equals("startTime")) {
startTime = dateService.iso8601DateParse(currentText.toString().trim());
} else if (qName.equals("state")) {
state = currentText.toString().trim();
} else if (qName.equals("bucket")) {
bucket = currentText.toString().trim();
} else if (qName.equals("prefix")) {
prefix = currentText.toString().trim();
} else if (qName.equals("updateTime")) {
updateTime = dateService.iso8601DateParse(currentText.toString().trim());
}
currentText = new StringBuilder();
}
public void characters(char ch[], int start, int length) {
currentText.append(ch, start, length);
}
}

View File

@ -0,0 +1,57 @@
package org.jclouds.aws.ec2.xml;
import java.util.Set;
import javax.inject.Inject;
import org.jclouds.aws.ec2.domain.BundleTask;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
*/
public class DescribeBundleTasksResponseHandler extends ParseSax.HandlerWithResult<Set<BundleTask>> {
private Set<BundleTask> bundleTasks = Sets.newLinkedHashSet();
private final BundleTaskHandler bundleTaskHandler;
@Inject
public DescribeBundleTasksResponseHandler(BundleTaskHandler bundleTaskHandler) {
this.bundleTaskHandler = bundleTaskHandler;
}
public Set<BundleTask> getResult() {
return bundleTasks;
}
@Override
public HandlerWithResult<Set<BundleTask>> setContext(HttpRequest request) {
bundleTaskHandler.setContext(request);
return super.setContext(request);
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (!qName.equals("item"))
bundleTaskHandler.startElement(uri, localName, qName, attributes);
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if (qName.equals("item")) {
bundleTasks.add(bundleTaskHandler.getResult());
}
bundleTaskHandler.endElement(uri, localName, qName);
}
public void characters(char ch[], int start, int length) {
bundleTaskHandler.characters(ch, start, length);
}
}

View File

@ -22,8 +22,7 @@ public class EC2AsyncClientTest extends BaseEC2AsyncClientTest<EC2AsyncClient> {
private EC2AsyncClient asyncClient;
private EC2Client syncClient;
public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException,
ExecutionException {
public void testSync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert syncClient.getAMIServices() != null;
assert syncClient.getAvailabilityZoneAndRegionServices() != null;
assert syncClient.getElasticBlockStoreServices() != null;
@ -32,10 +31,11 @@ public class EC2AsyncClientTest extends BaseEC2AsyncClientTest<EC2AsyncClient> {
assert syncClient.getKeyPairServices() != null;
assert syncClient.getMonitoringServices() != null;
assert syncClient.getSecurityGroupServices() != null;
assert syncClient.getWindowsServices() != null;
}
public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException,
ExecutionException {
public void testAsync() throws SecurityException, NoSuchMethodException, InterruptedException, ExecutionException {
assert asyncClient.getAMIServices() != null;
assert asyncClient.getAvailabilityZoneAndRegionServices() != null;
assert asyncClient.getElasticBlockStoreServices() != null;
@ -44,6 +44,7 @@ public class EC2AsyncClientTest extends BaseEC2AsyncClientTest<EC2AsyncClient> {
assert asyncClient.getKeyPairServices() != null;
assert asyncClient.getMonitoringServices() != null;
assert asyncClient.getSecurityGroupServices() != null;
assert asyncClient.getWindowsServices() != null;
}
@Override

View File

@ -0,0 +1,74 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.options;
import static java.util.Collections.EMPTY_LIST;
import static java.util.Collections.singleton;
import static org.jclouds.aws.ec2.options.BundleInstanceS3StorageOptions.Builder.bucketOwnedBy;
import static org.testng.Assert.assertEquals;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
/**
* Tests possible uses of BundleInstanceS3StorageOptions and
* BundleInstanceS3StorageOptions.Builder.*
*
* @author Adrian Cole
*/
public class BundleInstanceS3StorageOptionsTest {
@Test
public void testAssignability() {
assert HttpRequestOptions.class.isAssignableFrom(BundleInstanceS3StorageOptions.class);
assert !String.class.isAssignableFrom(BundleInstanceS3StorageOptions.class);
}
@Test
public void testBucketOwnedBy() {
BundleInstanceS3StorageOptions options = new BundleInstanceS3StorageOptions();
options.bucketOwnedBy("test");
assertEquals(options.buildFormParameters().get("Storage.S3.AWSAccessKeyId"), singleton("test"));
}
@Test(expectedExceptions = IllegalStateException.class)
public void testNullBucketOwnedByNotInjected() {
BundleInstanceS3StorageOptions options = new BundleInstanceS3StorageOptions();
assertEquals(options.buildFormParameters().get("Storage.S3.AWSAccessKeyId"), EMPTY_LIST);
}
@Test
public void testNullBucketOwnedBy() {
BundleInstanceS3StorageOptions options = new BundleInstanceS3StorageOptions();
options.currentAwsAccessKeyId = "foo";
assertEquals(options.buildFormParameters().get("Storage.S3.AWSAccessKeyId"), singleton("foo"));
}
@Test
public void testBucketOwnedByStatic() {
BundleInstanceS3StorageOptions options = bucketOwnedBy("test");
assertEquals(options.buildFormParameters().get("Storage.S3.AWSAccessKeyId"), singleton("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testBucketOwnedByNPE() {
bucketOwnedBy(null);
}
}

View File

@ -54,8 +54,7 @@ import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "ec2.InstanceAsyncClientTest")
public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest<InstanceAsyncClient> {
public void testDescribeInstances() throws SecurityException, NoSuchMethodException, IOException {
Method method = InstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, Array.newInstance(
String.class, 0).getClass());
Method method = InstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, String[].class);
HttpRequest request = processor.createRequest(method, (String) null);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
@ -71,8 +70,7 @@ public class InstanceAsyncClientTest extends BaseEC2AsyncClientTest<InstanceAsyn
}
public void testDescribeInstancesArgs() throws SecurityException, NoSuchMethodException, IOException {
Method method = InstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, Array.newInstance(
String.class, 0).getClass());
Method method = InstanceAsyncClient.class.getMethod("describeInstancesInRegion", String.class, String[].class);
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");

View File

@ -0,0 +1,127 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.services;
import java.io.IOException;
import java.lang.reflect.Method;
import org.jclouds.aws.ec2.options.BundleInstanceS3StorageOptions;
import org.jclouds.aws.ec2.xml.BundleTaskHandler;
import org.jclouds.aws.ec2.xml.DescribeBundleTasksResponseHandler;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.testng.annotations.Test;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code WindowsAsyncClient}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.WindowsAsyncClientTest")
public class WindowsAsyncClientTest extends BaseEC2AsyncClientTest<WindowsAsyncClient> {
public void testBundleInstanceInRegion() throws SecurityException, NoSuchMethodException, IOException {
Method method = WindowsAsyncClient.class.getMethod("bundleInstanceInRegion", String.class, String.class,
String.class, String.class, String.class, BundleInstanceS3StorageOptions[].class);
HttpRequest request = processor
.createRequest(
method,
null,
"i-e468cd8d",
"winami",
"my-bucket",
"{\"expiration\": \"2008-08-30T08:49:09Z\",\"conditions\": [{\"bucket\": \"my-bucket\"},[\"starts-with\", \"$key\", \"my-new-image\"]]}");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
String payload = "Version=2010-06-15&Action=BundleInstance&Storage.S3.Prefix=winami&InstanceId=i-e468cd8d&Storage.S3.Bucket=my-bucket&Storage.S3.UploadPolicy=eyJleHBpcmF0aW9uIjogIjIwMDgtMDgtMzBUMDg6NDk6MDlaIiwiY29uZGl0aW9ucyI6IFt7ImJ1Y2tldCI6ICJteS1idWNrZXQifSxbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAibXktbmV3LWltYWdlIl1dfQ%3D%3D&Storage.S3.UploadPolicySignature=ih%2FiohGe0A7y4QVRbKaq6BZShzUsmBEJEa9AdFbxM6Y%3D";
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, payload, "application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, BundleTaskHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testBundleInstanceInRegionOptions() throws SecurityException, NoSuchMethodException, IOException {
Method method = WindowsAsyncClient.class.getMethod("bundleInstanceInRegion", String.class, String.class,
String.class, String.class, String.class, BundleInstanceS3StorageOptions[].class);
HttpRequest request = processor
.createRequest(
method,
null,
"i-e468cd8d",
"winami",
"my-bucket",
"{\"expiration\": \"2008-08-30T08:49:09Z\",\"conditions\": [{\"bucket\": \"my-bucket\"},[\"starts-with\", \"$key\", \"my-new-image\"]]}",
BundleInstanceS3StorageOptions.Builder.bucketOwnedBy("10QMXFEV71ZS32XQFTR2"));
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
String payload = "Version=2010-06-15&Action=BundleInstance&Storage.S3.Prefix=winami&InstanceId=i-e468cd8d&Storage.S3.Bucket=my-bucket&Storage.S3.AWSAccessKeyId=10QMXFEV71ZS32XQFTR2&Storage.S3.UploadPolicy=eyJleHBpcmF0aW9uIjogIjIwMDgtMDgtMzBUMDg6NDk6MDlaIiwiY29uZGl0aW9ucyI6IFt7ImJ1Y2tldCI6ICJteS1idWNrZXQifSxbInN0YXJ0cy13aXRoIiwgIiRrZXkiLCAibXktbmV3LWltYWdlIl1dfQ%3D%3D&Storage.S3.UploadPolicySignature=ih%2FiohGe0A7y4QVRbKaq6BZShzUsmBEJEa9AdFbxM6Y%3D";
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, payload, "application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, BundleTaskHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testDescribeBundleTasks() throws SecurityException, NoSuchMethodException, IOException {
Method method = WindowsAsyncClient.class.getMethod("describeBundleTasksInRegion", String.class, String[].class);
HttpRequest request = processor.createRequest(method, (String) null);
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeBundleTasks", "application/x-www-form-urlencoded",
false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeBundleTasksResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
public void testDescribeBundleTasksArgs() throws SecurityException, NoSuchMethodException, IOException {
Method method = WindowsAsyncClient.class.getMethod("describeBundleTasksInRegion", String.class, String[].class);
HttpRequest request = processor.createRequest(method, null, "1", "2");
assertRequestLineEquals(request, "POST https://ec2.us-east-1.amazonaws.com/ HTTP/1.1");
assertNonPayloadHeadersEqual(request, "Host: ec2.us-east-1.amazonaws.com\n");
assertPayloadEquals(request, "Version=2010-06-15&Action=DescribeBundleTasks&BundleId.1=1&BundleId.2=2",
"application/x-www-form-urlencoded", false);
assertResponseParserClassEquals(method, request, ParseSax.class);
assertSaxResponseParserClassEquals(method, DescribeBundleTasksResponseHandler.class);
assertExceptionParserClassEquals(method, null);
checkFilters(request);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<WindowsAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<WindowsAsyncClient>>() {
};
}
}

View File

@ -0,0 +1,83 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.services;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
/**
* Tests behavior of {@code WindowsClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "ec2.WindowsClientLiveTest")
public class WindowsClientLiveTest {
private WindowsClient client;
private static final String DEFAULT_INSTANCE = "i-TODO";
private static final String DEFAULT_BUCKET = "TODO";
private RestContext<EC2Client, EC2AsyncClient> context;
@BeforeGroups(groups = { "live" })
public void setupClient() throws IOException {
String identity = checkNotNull(System.getProperty("jclouds.test.identity"), "jclouds.test.identity");
String credential = checkNotNull(System.getProperty("jclouds.test.credential"), "jclouds.test.credential");
context = new RestContextFactory().createContext("ec2", identity, credential, ImmutableSet
.<Module> of(new Log4JLoggingModule()));
client = context.getApi().getWindowsServices();
}
@Test(enabled = false)
// TODO get instance
public void testBundleInstanceInRegion() {
client
.bundleInstanceInRegion(
null,
DEFAULT_INSTANCE,
"prefix",
DEFAULT_BUCKET,
"{\"expiration\": \"2008-08-30T08:49:09Z\",\"conditions\": [{\"bucket\": \"my-bucket\"},[\"starts-with\", \"$key\", \"my-new-image\"]]}");
}
@Test(enabled = false)
// TODO get instance
public void testCancelBundleTaskInRegion() {
}
@Test(enabled = false)
// TODO get instance
public void testDescribeBundleTasksInRegion() {
}
}

View File

@ -0,0 +1,76 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.aws.ec2.domain.BundleTask;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
/**
* Tests behavior of {@code BundleTaskHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.BundleTaskHandlerTest")
public class BundleTaskHandlerTest extends BaseEC2HandlerTest {
public void testBundleInstance() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/bundle_instance.xml");
BundleTask expected = new BundleTask(defaultRegion, "bun-c1a540a8", null, "i-12345678", 70, dateService
.iso8601DateParse("2008-10-07T11:41:50.000Z"), "bundling", "my-bucket", "winami", dateService
.iso8601DateParse("2008-10-07T11:51:50.000Z"));
BundleTaskHandler handler = injector.getInstance(BundleTaskHandler.class);
addDefaultRegionToHandler(handler);
BundleTask result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
public void testCancleBundleTask() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/cancel_bundle_task.xml");
BundleTask expected = new BundleTask(defaultRegion, "bun-cla322b9", null, "i-12345678", 20, dateService
.iso8601DateParse("2008-10-07T11:41:50.000Z"), "canceling", "my-bucket", "my-new-image", dateService
.iso8601DateParse("2008-10-07T11:51:50.000Z"));
BundleTaskHandler handler = injector.getInstance(BundleTaskHandler.class);
addDefaultRegionToHandler(handler);
BundleTask result = factory.create(handler).parse(is);
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { null });
replay(request);
handler.setContext(request);
}
}

View File

@ -0,0 +1,64 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.xml;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.testng.Assert.assertEquals;
import java.io.InputStream;
import org.jclouds.aws.ec2.domain.BundleTask;
import org.jclouds.date.DateService;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.testng.annotations.Test;
import com.google.inject.internal.Iterables;
/**
* Tests behavior of {@code DescribeBundleTasksResponseHandler}
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ec2.DescribeBundleTasksResponseHandlerTest")
public class DescribeBundleTasksResponseHandlerTest extends BaseEC2HandlerTest {
public void testApplyInputStream() {
DateService dateService = injector.getInstance(DateService.class);
InputStream is = getClass().getResourceAsStream("/ec2/describe_bundle_tasks.xml");
BundleTask expected = new BundleTask(defaultRegion, "bun-c1a540a8", null, "i-12345678", 20, dateService
.iso8601DateParse("2008-10-07T11:41:50.000Z"), "canceling", "my-bucket", "winami", dateService
.iso8601DateParse("2008-10-07T11:51:50.000Z"));
DescribeBundleTasksResponseHandler handler = injector.getInstance(DescribeBundleTasksResponseHandler.class);
addDefaultRegionToHandler(handler);
BundleTask result = Iterables.getOnlyElement(factory.create(handler).parse(is));
assertEquals(result, expected);
}
private void addDefaultRegionToHandler(ParseSax.HandlerWithResult<?> handler) {
GeneratedHttpRequest<?> request = createMock(GeneratedHttpRequest.class);
expect(request.getArgs()).andReturn(new Object[] { null });
replay(request);
handler.setContext(request);
}
}

View File

@ -0,0 +1,18 @@
<BundleInstanceResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<requestId>bun-c1a540a8</requestId>
<bundleInstanceTask>
<instanceId>i-12345678</instanceId>
<bundleId>bun-c1a540a8</bundleId>
<state>bundling</state>
<startTime>2008-10-07T11:41:50.000Z</startTime>
<updateTime>2008-10-07T11:51:50.000Z</updateTime>
<progress>70%</progress>
<storage>
<S3>
<bucket>my-bucket</bucket>
<prefix>winami</prefix>
</S3>
</storage>
</bundleInstanceTask>
</BundleInstanceResponse>

View File

@ -0,0 +1,16 @@
<CancelBundleTaskResponse xmlns="http://ec2.amazonaws.com/doc/2009-04-04/">
<bundleInstanceTask>
<instanceId>i-12345678</instanceId>
<bundleId>bun-cla322b9</bundleId>
<state>canceling</state>
<startTime>2008-10-07T11:41:50.000Z</startTime>
<updateTime>2008-10-07T11:51:50.000Z</updateTime>
<progress>20%</progress>
<storage>
<S3>
<bucket>my-bucket</bucket>
<prefix>my-new-image</prefix>
</S3>
</storage>
</bundleInstanceTask>
</CancelBundleTaskResponse>

View File

@ -0,0 +1,18 @@
<DescribeBundleTasksResponse xmlns="http://ec2.amazonaws.com/doc/2009-11-30/">
<bundleInstanceTasksSet>
<item>
<instanceId>i-12345678</instanceId>
<bundleId>bun-c1a540a8</bundleId>
<state>canceling</state>
<startTime>2008-10-07T11:41:50.000Z</startTime>
<updateTime>2008-10-07T11:51:50.000Z</updateTime>
<progress>20%</progress>
<storage>
<S3>
<bucket>my-bucket</bucket>
<prefix>winami</prefix>
</S3>
</storage>
</item>
</bundleInstanceTasksSet>
</DescribeBundleTasksResponse>

View File

@ -417,7 +417,6 @@ public class HttpUtils {
public static void addFormParamTo(HttpRequest request, String key, String value) {
addFormParamTo(request, key, ImmutableSet.<Object> of(value));
}
public static void addFormParamTo(HttpRequest request, String key, Iterable<?> values) {