You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ra...@apache.org on 2014/09/01 12:39:32 UTC
[17/51] [partial] Fixing STRATOS-765 - upgrade to JClouds 1.8.0
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java
new file mode 100644
index 0000000..9640e4b
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/DescribeImagesParallel.java
@@ -0,0 +1,82 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.util.concurrent.Futures.allAsList;
+import static com.google.common.util.concurrent.Futures.getUnchecked;
+
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.options.DescribeImagesOptions;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+@Singleton
+public class DescribeImagesParallel implements
+ Function<Iterable<Entry<String, DescribeImagesOptions>>, Iterable<? extends org.jclouds.ec2.domain.Image>> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected final EC2Api api;
+ final ListeningExecutorService userExecutor;
+
+ @Inject
+ public DescribeImagesParallel(EC2Api api, @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
+ this.api = api;
+ this.userExecutor = userExecutor;
+ }
+
+ @Override
+ public Iterable<? extends org.jclouds.ec2.domain.Image> apply(
+ final Iterable<Entry<String, DescribeImagesOptions>> queries) {
+ ListenableFuture<List<Set<? extends org.jclouds.ec2.domain.Image>>> futures
+ = allAsList(transform(
+ queries,
+ new Function<Entry<String, DescribeImagesOptions>,
+ ListenableFuture<? extends Set<? extends org.jclouds.ec2.domain.Image>>>() {
+ public ListenableFuture<Set<? extends org.jclouds.ec2.domain.Image>> apply(
+ final Entry<String, DescribeImagesOptions> from) {
+ return userExecutor.submit(new Callable<Set<? extends org.jclouds.ec2.domain.Image>>() {
+ @Override
+ public Set<? extends org.jclouds.ec2.domain.Image> call() throws Exception {
+ return api.getAMIApi().get().describeImagesInRegion(from.getKey(), from.getValue());
+ }
+ });
+ }
+ }));
+ logger.trace("amis");
+
+ return concat(getUnchecked(futures));
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java
new file mode 100644
index 0000000..e41c0f8
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java
@@ -0,0 +1,252 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.size;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Sets.difference;
+import static com.google.common.util.concurrent.Atomics.newReference;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+import static org.jclouds.compute.functions.DefaultCredentialsFromImageOrOverridingCredentials.overrideDefaultCredentialsWithOptionsIfPresent;
+import static org.jclouds.ec2.compute.util.EC2ComputeUtils.getZoneFromLocationOrNull;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListenableFuture;
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.config.CustomizationResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
+import org.jclouds.compute.util.ComputeUtils;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.compute.functions.PresentInstances;
+import org.jclouds.ec2.compute.options.EC2TemplateOptions;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.ec2.options.RunInstancesOptions;
+import org.jclouds.ec2.reference.EC2Constants;
+import org.jclouds.logging.Logger;
+
+/**
+ * creates futures that correlate to
+ */
+@Singleton
+public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThenAddToSet {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ @Inject
+ @Named(EC2Constants.PROPERTY_EC2_AUTO_ALLOCATE_ELASTIC_IPS)
+ @VisibleForTesting
+ boolean autoAllocateElasticIps = false;
+
+ @VisibleForTesting
+ final EC2Api client;
+ @VisibleForTesting
+ final Predicate<AtomicReference<NodeMetadata>> nodeRunning;
+ @VisibleForTesting
+ final LoadingCache<RegionAndName, String> elasticIpCache;
+ @VisibleForTesting
+ final CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize;
+ @VisibleForTesting
+ final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
+ @VisibleForTesting
+ final ComputeUtils utils;
+ final PresentInstances presentInstances;
+ final LoadingCache<RunningInstance, Optional<LoginCredentials>> instanceToCredentials;
+ final Map<String, Credentials> credentialStore;
+
+ @Inject
+ protected EC2CreateNodesInGroupThenAddToSet(
+ EC2Api client,
+ @Named("ELASTICIP") LoadingCache<RegionAndName, String> elasticIpCache,
+ @Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>> nodeRunning,
+ CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
+ PresentInstances presentInstances, Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
+ LoadingCache<RunningInstance, Optional<LoginCredentials>> instanceToCredentials,
+ Map<String, Credentials> credentialStore, ComputeUtils utils) {
+ this.client = checkNotNull(client, "client");
+ this.elasticIpCache = checkNotNull(elasticIpCache, "elasticIpCache");
+ this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning");
+ this.presentInstances = checkNotNull(presentInstances, "presentInstances");
+ this.createKeyPairAndSecurityGroupsAsNeededAndReturncustomize = checkNotNull(
+ createKeyPairAndSecurityGroupsAsNeededAndReturncustomize,
+ "createKeyPairAndSecurityGroupsAsNeededAndReturncustomize");
+ this.runningInstanceToNodeMetadata = checkNotNull(runningInstanceToNodeMetadata, "runningInstanceToNodeMetadata");
+ this.instanceToCredentials = checkNotNull(instanceToCredentials, "instanceToCredentials");
+ this.credentialStore = checkNotNull(credentialStore, "credentialStore");
+ this.utils = checkNotNull(utils, "utils");
+ }
+
+ public static final Function<RunningInstance, RegionAndName> instanceToRegionAndName = new Function<RunningInstance, RegionAndName>() {
+ @Override
+ public RegionAndName apply(RunningInstance from) {
+ return new RegionAndName(from.getRegion(), from.getId());
+ }
+ };
+
+ @Override
+ public Map<?, ListenableFuture<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes,
+ Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
+
+ Template mutableTemplate = template.clone();
+
+ Set<RunningInstance> started = runInstancesAndWarnOnInvisible(group, count, mutableTemplate);
+ if (started.size() == 0) {
+ logger.warn("<< unable to start instances(%s)", mutableTemplate);
+ return ImmutableMap.of();
+ }
+ populateCredentials(started, template.getOptions());
+
+ if (autoAllocateElasticIps) // before customization as the elastic ips may be needed
+ blockUntilRunningAndAssignElasticIpsToInstancesOrPutIntoBadMap(started, badNodes);
+
+ return utils.customizeNodesAndAddToGoodMapOrPutExceptionIntoBadMap(mutableTemplate.getOptions(),
+ transform(started, runningInstanceToNodeMetadata), goodNodes, badNodes, customizationResponses);
+ }
+
+ /**
+ * attempts to start the specified count of instances. eventual consistency might cause a problem where instances
+ * aren't immediately visible to the api. This method will warn when that occurs.
+ */
+ private Set<RunningInstance> runInstancesAndWarnOnInvisible(String group, int count, Template mutableTemplate) {
+ Set<RunningInstance> started = createKeyPairAndSecurityGroupsAsNeededThenRunInstances(group, count,
+ mutableTemplate);
+ Set<RegionAndName> startedIds = ImmutableSet.copyOf(transform(started, instanceToRegionAndName));
+ if (startedIds.size() == 0) {
+ return ImmutableSet.copyOf(started);
+ }
+ logger.debug("<< started instances(%s)", startedIds);
+ Set<RunningInstance> visible = presentInstances.apply(startedIds);
+ Set<RegionAndName> visibleIds = ImmutableSet.copyOf(transform(visible, instanceToRegionAndName));
+ logger.trace("<< visible instances(%s)", visibleIds);
+
+ // add an exception for each of the nodes we cannot customize
+ Set<RegionAndName> invisibleIds = difference(startedIds, visibleIds);
+ if (invisibleIds.size() > 0) {
+ logger.warn("<< not api visible instances(%s)", invisibleIds);
+ }
+ return started;
+ }
+
+ private void populateCredentials(Set<RunningInstance> input, TemplateOptions options) {
+ LoginCredentials credentials = null;
+ for (RunningInstance instance : input) {
+ credentials = instanceToCredentials.getUnchecked(instance).orNull();
+ if (credentials != null)
+ break;
+ }
+ credentials = overrideDefaultCredentialsWithOptionsIfPresent(credentials, options);
+ if (credentials != null)
+ for (RegionAndName instance : transform(input, instanceToRegionAndName))
+ credentialStore.put("node#" + instance.slashEncode(), credentials);
+ }
+
+ private void blockUntilRunningAndAssignElasticIpsToInstancesOrPutIntoBadMap(Set<RunningInstance> input,
+ Map<NodeMetadata, Exception> badNodes) {
+ Map<RegionAndName, RunningInstance> instancesById = Maps.uniqueIndex(input, instanceToRegionAndName);
+ for (Map.Entry<RegionAndName, RunningInstance> entry : instancesById.entrySet()) {
+ RegionAndName id = entry.getKey();
+ RunningInstance instance = entry.getValue();
+ try {
+ logger.debug("<< allocating elastic IP instance(%s)", id);
+ String ip = client.getElasticIPAddressApi().get().allocateAddressInRegion(id.getRegion());
+ // block until instance is running
+ logger.debug(">> awaiting status running instance(%s)", id);
+ AtomicReference<NodeMetadata> node = newReference(runningInstanceToNodeMetadata
+ .apply(instance));
+ nodeRunning.apply(node);
+ logger.trace("<< running instance(%s)", id);
+ logger.debug(">> associating elastic IP %s to instance %s", ip, id);
+ client.getElasticIPAddressApi().get().associateAddressInRegion(id.getRegion(), ip, id.getName());
+ logger.trace("<< associated elastic IP %s to instance %s", ip, id);
+ // add mapping of instance to ip into the cache
+ elasticIpCache.put(id, ip);
+ } catch (RuntimeException e) {
+ badNodes.put(runningInstanceToNodeMetadata.apply(instancesById.get(id)), e);
+ }
+ }
+ }
+
+ private Set<RunningInstance> createKeyPairAndSecurityGroupsAsNeededThenRunInstances(String group, int count,
+ Template template) {
+ String region = AWSUtils.getRegionFromLocationOrNull(template.getLocation());
+ String zone = getZoneFromLocationOrNull(template.getLocation());
+ RunInstancesOptions instanceOptions = createKeyPairAndSecurityGroupsAsNeededAndReturncustomize.execute(region,
+ group, template);
+ return createNodesInRegionAndZone(region, zone, group, count, template, instanceOptions);
+ }
+
+ protected Set<RunningInstance> createNodesInRegionAndZone(String region, String zone, String group,
+ int count, Template template,
+ RunInstancesOptions instanceOptions) {
+ int countStarted = 0;
+ int tries = 0;
+ Set<RunningInstance> started = ImmutableSet.<RunningInstance> of();
+
+ int maxCount = EC2TemplateOptions.class.cast(template.getOptions()).getMaxCount();
+ int countToProvision;
+
+ if (maxCount == 0) {
+ maxCount = count;
+ countToProvision = 1;
+ } else {
+ countToProvision = count;
+ }
+
+ while (countStarted < count && tries++ < count) {
+ if (logger.isDebugEnabled())
+ logger.debug(">> running %d instance region(%s) zone(%s) ami(%s) params(%s)", count - countStarted, region,
+ zone, template.getImage().getProviderId(), instanceOptions.buildFormParameters());
+
+ started = ImmutableSet.copyOf(concat(
+ started,
+ client.getInstanceApi().get().runInstancesInRegion(region, zone, template.getImage().getProviderId(),
+ countToProvision, maxCount - countStarted, instanceOptions)));
+
+ countStarted = size(started);
+ if (countStarted < count)
+ logger.debug(">> not enough instances (%d/%d) started, attempting again", countStarted, count);
+ }
+ return started;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategy.java
new file mode 100644
index 0000000..b8a1b5c
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2DestroyNodeStrategy.java
@@ -0,0 +1,101 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.concurrent.ExecutionException;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.DestroyNodeStrategy;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.reference.EC2Constants;
+import org.jclouds.logging.Logger;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+@Singleton
+public class EC2DestroyNodeStrategy implements DestroyNodeStrategy {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+ protected final EC2Api client;
+ protected final GetNodeMetadataStrategy getNode;
+ protected final LoadingCache<RegionAndName, String> elasticIpCache;
+
+ @Inject
+ @Named(EC2Constants.PROPERTY_EC2_AUTO_ALLOCATE_ELASTIC_IPS)
+ @VisibleForTesting
+ boolean autoAllocateElasticIps = false;
+
+ @Inject
+ protected EC2DestroyNodeStrategy(EC2Api client, GetNodeMetadataStrategy getNode,
+ @Named("ELASTICIP") LoadingCache<RegionAndName, String> elasticIpCache) {
+ this.client = checkNotNull(client, "client");
+ this.getNode = checkNotNull(getNode, "getNode");
+ this.elasticIpCache = checkNotNull(elasticIpCache, "elasticIpCache");
+ }
+
+ @Override
+ public NodeMetadata destroyNode(String id) {
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String instanceId = parts[1];
+
+ // TODO: can there be multiple?
+ releaseAnyPublicIpForInstanceInRegion(instanceId, region);
+ destroyInstanceInRegion(instanceId, region);
+ return getNode.getNode(id);
+ }
+
+ protected void releaseAnyPublicIpForInstanceInRegion(String instanceId, String region) {
+ if (!autoAllocateElasticIps)
+ return;
+ try {
+ String ip = elasticIpCache.get(new RegionAndName(region, instanceId));
+ logger.debug(">> disassociating elastic IP %s", ip);
+ client.getElasticIPAddressApi().get().disassociateAddressInRegion(region, ip);
+ logger.trace("<< disassociated elastic IP %s", ip);
+ elasticIpCache.invalidate(new RegionAndName(region, instanceId));
+ logger.debug(">> releasing elastic IP %s", ip);
+ client.getElasticIPAddressApi().get().releaseAddressInRegion(region, ip);
+ logger.trace("<< released elastic IP %s", ip);
+ } catch (CacheLoader.InvalidCacheLoadException e) {
+ // no ip was found
+ return;
+ } catch (ExecutionException e) {
+ // don't propagate as we need to clean up the node regardless
+ logger.warn(e, "error cleaning up elastic ip for instance %s/%s", region, instanceId);
+ }
+
+ }
+
+ protected void destroyInstanceInRegion(String instanceId, String region) {
+ client.getInstanceApi().get().terminateInstancesInRegion(region, instanceId);
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetImageStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetImageStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetImageStrategy.java
new file mode 100644
index 0000000..55a7889
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetImageStrategy.java
@@ -0,0 +1,66 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.strategy.GetImageStrategy;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.domain.Image;
+import org.jclouds.ec2.options.DescribeImagesOptions;
+
+import com.google.common.base.Function;
+
+@Singleton
+public class EC2GetImageStrategy implements GetImageStrategy {
+
+ private final EC2Api client;
+ private final Function<Image, org.jclouds.compute.domain.Image> imageToImage;
+
+ @Inject
+ protected EC2GetImageStrategy(EC2Api client, Function<Image, org.jclouds.compute.domain.Image> imageToImage) {
+ this.client = checkNotNull(client, "client");
+ this.imageToImage = checkNotNull(imageToImage, "imageToImage");
+ }
+
+ @Override
+ public org.jclouds.compute.domain.Image getImage(String id) {
+ checkNotNull(id, "id");
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String instanceId = parts[1];
+ try {
+ Image image = getImageInRegion(region, instanceId);
+ return imageToImage.apply(image);
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ }
+
+ public Image getImageInRegion(String region, String id) {
+ return getOnlyElement(client.getAMIApi().get().describeImagesInRegion(region,
+ DescribeImagesOptions.Builder.imageIds(id)));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetNodeMetadataStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetNodeMetadataStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetNodeMetadataStrategy.java
new file mode 100644
index 0000000..0d7fa77
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetNodeMetadataStrategy.java
@@ -0,0 +1,67 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+import java.util.NoSuchElementException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.domain.RunningInstance;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Iterables;
+
+@Singleton
+public class EC2GetNodeMetadataStrategy implements GetNodeMetadataStrategy {
+
+ private final EC2Api client;
+ private final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
+
+ @Inject
+ protected EC2GetNodeMetadataStrategy(EC2Api client,
+ Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata) {
+ this.client = checkNotNull(client, "client");
+ this.runningInstanceToNodeMetadata = checkNotNull(runningInstanceToNodeMetadata, "runningInstanceToNodeMetadata");
+ }
+
+ @Override
+ public NodeMetadata getNode(String id) {
+ checkNotNull(id, "id");
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String instanceId = parts[1];
+ try {
+ RunningInstance runningInstance = getRunningInstanceInRegion(region, instanceId);
+ return runningInstanceToNodeMetadata.apply(runningInstance);
+ } catch (NoSuchElementException e) {
+ return null;
+ }
+ }
+
+ public RunningInstance getRunningInstanceInRegion(String region, String id) {
+ return getOnlyElement(Iterables.concat(client.getInstanceApi().get().describeInstancesInRegion(region, id)));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java
new file mode 100644
index 0000000..2f0204a
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ListNodesStrategy.java
@@ -0,0 +1,160 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Predicates.and;
+import static com.google.common.base.Predicates.in;
+import static com.google.common.base.Predicates.notNull;
+import static com.google.common.collect.Iterables.concat;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.toArray;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Multimaps.filterKeys;
+import static com.google.common.collect.Multimaps.index;
+import static com.google.common.collect.Multimaps.transformValues;
+
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.Constants;
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.ComputeMetadata;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.predicates.NodePredicates;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.domain.Reservation;
+import org.jclouds.ec2.domain.RunningInstance;
+import org.jclouds.location.Region;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.inject.Inject;
+
+@Singleton
+public class EC2ListNodesStrategy implements ListNodesStrategy {
+
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ @Inject(optional = true)
+ @Named(Constants.PROPERTY_REQUEST_TIMEOUT)
+ protected static Long maxTime;
+
+ protected final EC2Api client;
+ protected final Supplier<Set<String>> regions;
+ protected final Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata;
+ protected final ListeningExecutorService userExecutor;
+
+ @Inject
+ protected EC2ListNodesStrategy(EC2Api client, @Region Supplier<Set<String>> regions,
+ Function<RunningInstance, NodeMetadata> runningInstanceToNodeMetadata,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
+ this.client = checkNotNull(client, "client");
+ this.regions = checkNotNull(regions, "regions");
+ this.runningInstanceToNodeMetadata = checkNotNull(runningInstanceToNodeMetadata, "runningInstanceToNodeMetadata");
+ this.userExecutor = checkNotNull(userExecutor, "userExecutor");
+ }
+
+ @Override
+ public Set<? extends ComputeMetadata> listNodes() {
+ return listDetailsOnNodesMatching(NodePredicates.all());
+ }
+
+ @Override
+ public Set<? extends NodeMetadata> listNodesByIds(Iterable<String> ids) {
+ Multimap<String, String> idsByHandles = index(ids, splitHandle(1));
+ Multimap<String, String> idsByRegions = transformValues(idsByHandles, splitHandle(0));
+ Multimap<String, String> idsByConfiguredRegions = filterKeys(idsByRegions, in(regions.get()));
+
+ if (idsByConfiguredRegions.isEmpty()) {
+ return ImmutableSet.of();
+ }
+
+ Iterable<? extends RunningInstance> instances = pollRunningInstancesByRegionsAndIds(idsByConfiguredRegions);
+ Iterable<? extends NodeMetadata> nodes = transform(filter(instances, notNull()),
+ runningInstanceToNodeMetadata);
+ return ImmutableSet.copyOf(nodes);
+ }
+
+ @Override
+ public Set<? extends NodeMetadata> listDetailsOnNodesMatching(Predicate<ComputeMetadata> filter) {
+ Iterable<? extends RunningInstance> instances = pollRunningInstances();
+ Iterable<? extends NodeMetadata> nodes = filter(transform(filter(instances, notNull()),
+ runningInstanceToNodeMetadata), and(notNull(), filter));
+ return ImmutableSet.copyOf(nodes);
+ }
+
+ protected Iterable<? extends RunningInstance> pollRunningInstances() {
+ Iterable<? extends Set<? extends Reservation<? extends RunningInstance>>> reservations
+ = transform(regions.get(), allInstancesInRegion());
+
+ return concat(concat(reservations));
+ }
+
+ protected Iterable<? extends RunningInstance> pollRunningInstancesByRegionsAndIds(final Multimap<String, String> idsByRegions) {
+ Iterable<? extends Set<? extends Reservation<? extends RunningInstance>>> reservations
+ = transform(idsByRegions.keySet(), instancesByIdInRegion(idsByRegions));
+
+ return concat(concat(reservations));
+ }
+
+ protected Function<String, String> splitHandle(final int pos) {
+ return new Function<String, String>() {
+
+ @Override
+ public String apply(String handle) {
+ return AWSUtils.parseHandle(handle)[pos];
+ }
+ };
+ }
+
+ protected Function<String, Set<? extends Reservation<? extends RunningInstance>>> allInstancesInRegion() {
+ return new Function<String, Set<? extends Reservation<? extends RunningInstance>>>() {
+
+ @Override
+ public Set<? extends Reservation<? extends RunningInstance>> apply(String from) {
+ return client.getInstanceApi().get().describeInstancesInRegion(from);
+ }
+
+ };
+ }
+
+ protected Function<String, Set<? extends Reservation<? extends RunningInstance>>>
+ instancesByIdInRegion(final Multimap<String, String> idsByRegions) {
+ return new Function<String, Set<? extends Reservation<? extends RunningInstance>>>() {
+
+ @Override
+ public Set<? extends Reservation<? extends RunningInstance>> apply(String from) {
+ return client.getInstanceApi().get()
+ .describeInstancesInRegion(from, toArray(idsByRegions.get(from), String.class));
+ }
+
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2PopulateDefaultLoginCredentialsForImageStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2PopulateDefaultLoginCredentialsForImageStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2PopulateDefaultLoginCredentialsForImageStrategy.java
new file mode 100644
index 0000000..91eaaa9
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2PopulateDefaultLoginCredentialsForImageStrategy.java
@@ -0,0 +1,72 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.compute.strategy.impl.ReturnCredentialsBoundToImage;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.domain.LoginCredentials.Builder;
+import org.jclouds.ec2.domain.Image;
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.collect.ImmutableMap;
+
+@Singleton
+public class EC2PopulateDefaultLoginCredentialsForImageStrategy extends ReturnCredentialsBoundToImage {
+ public EC2PopulateDefaultLoginCredentialsForImageStrategy() {
+ this(null, ImmutableMap.<String, Credentials> of(), ImmutableMap.<OsFamily, LoginCredentials>of());
+ }
+
+ @Inject
+ public EC2PopulateDefaultLoginCredentialsForImageStrategy(@Nullable @Named("image") LoginCredentials creds,
+ Map<String, Credentials> credentialStore, Map<OsFamily, LoginCredentials> osFamilyToCredentials) {
+ super(creds, credentialStore, osFamilyToCredentials);
+ }
+
+ @Override
+ public LoginCredentials apply(Object resourceToAuthenticate) {
+ if (creds != null)
+ return creds;
+ Builder credentials = LoginCredentials.builder().user("root");
+ if (resourceToAuthenticate != null) {
+ String owner = null;
+ if (resourceToAuthenticate instanceof Image) {
+ owner = Image.class.cast(resourceToAuthenticate).getImageOwnerId();
+ } else if (resourceToAuthenticate instanceof org.jclouds.compute.domain.Image) {
+ owner = org.jclouds.compute.domain.Image.class.cast(resourceToAuthenticate).getUserMetadata().get("owner");
+ }
+ checkArgument(owner != null, "Resource must be an image (for EC2)");
+ // canonical/alestic images use the ubuntu user to login
+ if (owner.matches("063491364108|099720109477")) {
+ credentials.user("ubuntu");
+ // http://typepad.com/2010/09/introducing-amazon-linux-ami.html
+ } else if (owner.equals("137112412989")) {
+ credentials.user("ec2-user");
+ }
+ }
+ return credentials.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2RebootNodeStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2RebootNodeStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2RebootNodeStrategy.java
new file mode 100644
index 0000000..fbc8096
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2RebootNodeStrategy.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.compute.strategy.RebootNodeStrategy;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.features.InstanceApi;
+
+@Singleton
+public class EC2RebootNodeStrategy implements RebootNodeStrategy {
+ private final InstanceApi client;
+ private final GetNodeMetadataStrategy getNode;
+
+ @Inject
+ protected EC2RebootNodeStrategy(EC2Api client, GetNodeMetadataStrategy getNode) {
+ this.client = client.getInstanceApi().get();
+ this.getNode = getNode;
+ }
+
+ @Override
+ public NodeMetadata rebootNode(String id) {
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String instanceId = parts[1];
+ client.rebootInstancesInRegion(region, instanceId);
+ return getNode.getNode(id);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ResumeNodeStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ResumeNodeStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ResumeNodeStrategy.java
new file mode 100644
index 0000000..6c5a093
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2ResumeNodeStrategy.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.compute.strategy.ResumeNodeStrategy;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.features.InstanceApi;
+
+@Singleton
+public class EC2ResumeNodeStrategy implements ResumeNodeStrategy {
+ private final InstanceApi client;
+ private final GetNodeMetadataStrategy getNode;
+
+ @Inject
+ protected EC2ResumeNodeStrategy(EC2Api client, GetNodeMetadataStrategy getNode) {
+ this.client = client.getInstanceApi().get();
+ this.getNode = getNode;
+ }
+
+ @Override
+ public NodeMetadata resumeNode(String id) {
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String instanceId = parts[1];
+ client.startInstancesInRegion(region, instanceId);
+ return getNode.getNode(id);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2SuspendNodeStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2SuspendNodeStrategy.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2SuspendNodeStrategy.java
new file mode 100644
index 0000000..ec737a2
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/EC2SuspendNodeStrategy.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.aws.util.AWSUtils;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
+import org.jclouds.compute.strategy.SuspendNodeStrategy;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.features.InstanceApi;
+
+@Singleton
+public class EC2SuspendNodeStrategy implements SuspendNodeStrategy {
+ private final InstanceApi client;
+ private final GetNodeMetadataStrategy getNode;
+
+ @Inject
+ protected EC2SuspendNodeStrategy(EC2Api client, GetNodeMetadataStrategy getNode) {
+ this.client = client.getInstanceApi().get();
+ this.getNode = getNode;
+ }
+
+ @Override
+ public NodeMetadata suspendNode(String id) {
+ String[] parts = AWSUtils.parseHandle(id);
+ String region = parts[0];
+ String instanceId = parts[1];
+ client.stopInstancesInRegion(region, true, instanceId);
+ return getNode.getNode(id);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/ReviseParsedImage.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/ReviseParsedImage.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/ReviseParsedImage.java
new file mode 100644
index 0000000..18dabd7
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/strategy/ReviseParsedImage.java
@@ -0,0 +1,40 @@
+/*
+ * 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.ec2.compute.strategy;
+
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+
+import com.google.inject.ImplementedBy;
+
+@ImplementedBy(ReviseParsedImage.NoopReviseParsedImage.class)
+public interface ReviseParsedImage {
+ void reviseParsedImage(org.jclouds.ec2.domain.Image from, ImageBuilder builder, OsFamily family,
+ OperatingSystem.Builder osBuilder);
+
+ @Singleton
+ public static class NoopReviseParsedImage implements ReviseParsedImage {
+
+ @Override
+ public void reviseParsedImage(org.jclouds.ec2.domain.Image from, ImageBuilder builder, OsFamily family,
+ OperatingSystem.Builder osBuilder) {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java
new file mode 100644
index 0000000..7ba4d1c
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2HardwareSupplier.java
@@ -0,0 +1,42 @@
+/*
+ * 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.ec2.compute.suppliers;
+
+import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_medium;
+import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.c1_xlarge;
+import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_large;
+import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_small;
+import static org.jclouds.ec2.compute.domain.EC2HardwareBuilder.m1_xlarge;
+
+import java.util.Set;
+
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.Hardware;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+
+@Singleton
+public class EC2HardwareSupplier implements Supplier<Set<? extends Hardware>> {
+
+ @Override
+ public Set<? extends Hardware> get() {
+ return ImmutableSet.<Hardware> of(m1_small().build(), c1_medium().build(), c1_xlarge()
+ .build(), m1_large().build(), m1_xlarge().build());
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2ImageSupplier.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2ImageSupplier.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2ImageSupplier.java
new file mode 100644
index 0000000..4fd4d6c
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/EC2ImageSupplier.java
@@ -0,0 +1,116 @@
+/*
+ * 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.ec2.compute.suppliers;
+
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.transform;
+import static org.jclouds.ec2.options.DescribeImagesOptions.Builder.ownedBy;
+import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+import org.jclouds.ec2.compute.functions.EC2ImageParser;
+import org.jclouds.ec2.compute.functions.ImagesToRegionAndIdMap;
+import org.jclouds.ec2.compute.strategy.DescribeImagesParallel;
+import org.jclouds.ec2.options.DescribeImagesOptions;
+import org.jclouds.location.Region;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+@Singleton
+public class EC2ImageSupplier implements Supplier<Set<? extends Image>> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Supplier<Set<String>> regions;
+ private final DescribeImagesParallel describer;
+ private final String[] amiOwners;
+ private final EC2ImageParser parser;
+ private final Supplier<LoadingCache<RegionAndName, ? extends Image>> cache;
+
+ @Inject
+ protected EC2ImageSupplier(@Region Supplier<Set<String>> regions, DescribeImagesParallel describer,
+ @Named(PROPERTY_EC2_AMI_OWNERS) String[] amiOwners, Supplier<LoadingCache<RegionAndName, ? extends Image>> cache,
+ EC2ImageParser parser) {
+ this.regions = regions;
+ this.describer = describer;
+ this.amiOwners = amiOwners;
+ this.cache = cache;
+ this.parser = parser;
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public Set<? extends Image> get() {
+ if (amiOwners.length == 0) {
+ logger.debug(">> no owners specified, skipping image parsing");
+ return ImmutableSet.of();
+
+ } else {
+ logger.debug(">> providing images");
+
+ Iterable<Entry<String, DescribeImagesOptions>> queries = getDescribeQueriesForOwnersInRegions(regions.get(),
+ amiOwners);
+
+ Iterable<? extends Image> parsedImages = ImmutableSet.copyOf(filter(transform(describer.apply(queries), parser), Predicates
+ .notNull()));
+
+ Map<RegionAndName, ? extends Image> imageMap = ImagesToRegionAndIdMap.imagesToMap(parsedImages);
+ cache.get().invalidateAll();
+ cache.get().asMap().putAll((Map)imageMap);
+ logger.debug("<< images(%d)", imageMap.size());
+
+ return Sets.newLinkedHashSet(imageMap.values());
+ }
+ }
+
+ public Iterable<Entry<String, DescribeImagesOptions>> getDescribeQueriesForOwnersInRegions(Set<String> regions,
+ String[] amiOwners) {
+ DescribeImagesOptions options = getOptionsForOwners(amiOwners);
+ Builder<String, DescribeImagesOptions> builder = ImmutableMap.builder();
+ for (String region : regions)
+ builder.put(region, options);
+ return builder.build().entrySet();
+ }
+
+ public DescribeImagesOptions getOptionsForOwners(String... amiOwners) {
+ DescribeImagesOptions options;
+ if (amiOwners.length == 1 && amiOwners[0].equals("*"))
+ options = new DescribeImagesOptions();
+ else
+ options = ownedBy(amiOwners);
+ return options;
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java
new file mode 100644
index 0000000..ae9daea
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/suppliers/RegionAndNameToImageSupplier.java
@@ -0,0 +1,49 @@
+/*
+ * 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.ec2.compute.suppliers;
+
+import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.Image;
+import org.jclouds.ec2.compute.domain.RegionAndName;
+
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
+@Singleton
+public class RegionAndNameToImageSupplier implements Supplier<LoadingCache<RegionAndName, ? extends Image>> {
+ private final LoadingCache<RegionAndName, Image> cache;
+
+ @Inject
+ protected RegionAndNameToImageSupplier(CacheLoader<RegionAndName, Image> regionAndIdToImage,
+ @Named(PROPERTY_SESSION_INTERVAL) long expirationSecs) {
+ cache = CacheBuilder.newBuilder().expireAfterWrite(expirationSecs, TimeUnit.SECONDS).build(regionAndIdToImage);
+ }
+
+ @Override
+ public LoadingCache<RegionAndName, ? extends Image> get() {
+ return cache;
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/util/EC2ComputeUtils.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/util/EC2ComputeUtils.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/util/EC2ComputeUtils.java
new file mode 100644
index 0000000..766da1c
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/compute/util/EC2ComputeUtils.java
@@ -0,0 +1,31 @@
+/*
+ * 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.ec2.compute.util;
+
+import javax.inject.Singleton;
+
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationScope;
+
+@Singleton
+public class EC2ComputeUtils {
+
+ public static String getZoneFromLocationOrNull(Location location) {
+ return location.getScope() == LocationScope.ZONE ? location.getId() : null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/BaseEC2HttpApiModule.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/BaseEC2HttpApiModule.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/BaseEC2HttpApiModule.java
new file mode 100644
index 0000000..5db1728
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/BaseEC2HttpApiModule.java
@@ -0,0 +1,59 @@
+/*
+ * 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.ec2.config;
+
+
+
+
+import org.jclouds.aws.config.FormSigningHttpApiModule;
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.ec2.suppliers.DescribeAvailabilityZonesInRegion;
+import org.jclouds.ec2.suppliers.DescribeRegionsForRegionURIs;
+import org.jclouds.location.config.LocationModule;
+import org.jclouds.location.suppliers.RegionIdToURISupplier;
+import org.jclouds.location.suppliers.RegionIdToZoneIdsSupplier;
+import org.jclouds.location.suppliers.RegionIdsSupplier;
+import org.jclouds.location.suppliers.ZoneIdToURISupplier;
+import org.jclouds.location.suppliers.ZoneIdsSupplier;
+import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet;
+import org.jclouds.location.suppliers.derived.ZoneIdToURIFromJoinOnRegionIdToURI;
+import org.jclouds.location.suppliers.derived.ZoneIdsFromRegionIdToZoneIdsValues;
+import org.jclouds.rest.ConfiguresHttpApi;
+
+import com.google.inject.Scopes;
+
+/**
+ * Configures the EC2 connection.
+ */
+@ConfiguresHttpApi
+public abstract class BaseEC2HttpApiModule<A extends EC2Api> extends
+ FormSigningHttpApiModule<A> {
+
+ protected BaseEC2HttpApiModule(Class<A> api) {
+ super(api);
+ }
+
+ @Override
+ protected void installLocations() {
+ install(new LocationModule());
+ bind(RegionIdToZoneIdsSupplier.class).to(DescribeAvailabilityZonesInRegion.class).in(Scopes.SINGLETON);
+ bind(RegionIdToURISupplier.class).to(DescribeRegionsForRegionURIs.class).in(Scopes.SINGLETON);
+ bind(ZoneIdsSupplier.class).to(ZoneIdsFromRegionIdToZoneIdsValues.class).in(Scopes.SINGLETON);
+ bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class).in(Scopes.SINGLETON);
+ bind(ZoneIdToURISupplier.class).to(ZoneIdToURIFromJoinOnRegionIdToURI.class).in(Scopes.SINGLETON);
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/EC2HttpApiModule.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/EC2HttpApiModule.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/EC2HttpApiModule.java
new file mode 100644
index 0000000..9980513
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/config/EC2HttpApiModule.java
@@ -0,0 +1,35 @@
+/*
+ * 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.ec2.config;
+
+
+
+
+import org.jclouds.ec2.EC2Api;
+import org.jclouds.rest.ConfiguresHttpApi;
+
+
+/**
+ * Configures the EC2 connection.
+ */
+@ConfiguresHttpApi
+public class EC2HttpApiModule extends BaseEC2HttpApiModule<EC2Api> {
+
+ public EC2HttpApiModule() {
+ super(EC2Api.class);
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/Attachment.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/Attachment.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/Attachment.java
new file mode 100644
index 0000000..23f2722
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/Attachment.java
@@ -0,0 +1,225 @@
+/*
+ * 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.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"
+ * />
+ */
+public class Attachment implements Comparable<Attachment> {
+ public static enum Status {
+ ATTACHING, ATTACHED, DETACHING, DETACHED, BUSY, UNRECOGNIZED;
+
+ public String value() {
+ return name().toLowerCase();
+ }
+
+ @Override
+ public String toString() {
+ return value();
+ }
+
+ public static Status fromValue(String status) {
+ try {
+ return valueOf(checkNotNull(status, "status").toUpperCase());
+ } catch (IllegalArgumentException e) {
+ return UNRECOGNIZED;
+ }
+ }
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String region;
+ private String volumeId;
+ private String instanceId;
+ private String device;
+ private Status status;
+ private Date attachTime;
+
+ public Builder region(String region) {
+ this.region = region;
+ return this;
+ }
+
+ public Builder volumeId(String volumeId) {
+ this.volumeId = volumeId;
+ return this;
+ }
+
+ public Builder instanceId(String instanceId) {
+ this.instanceId = instanceId;
+ return this;
+ }
+
+ public Builder device(String device) {
+ this.device = device;
+ return this;
+ }
+
+ public Builder status(Status status) {
+ this.status = status;
+ return this;
+ }
+
+ public Builder attachTime(Date attachTime) {
+ this.attachTime = attachTime;
+ return this;
+ }
+
+ public Attachment build() {
+ return new Attachment(region, volumeId, instanceId, device, status, attachTime);
+ }
+ }
+
+ private final String region;
+ private final String volumeId;
+ private final String instanceId;
+ private final String device;
+ private final Status status;
+ private final Date attachTime;
+
+ public Attachment(String region, String volumeId, String instanceId, String device, Status status, Date attachTime) {
+ this.region = checkNotNull(region, "region");
+ this.volumeId = volumeId;
+ this.instanceId = instanceId;
+ this.device = device;
+ this.status = status;
+ this.attachTime = attachTime;
+ }
+
+ /**
+ * To be removed in jclouds 1.6 <h4>Warning</h4>
+ *
+ * Especially on EC2 clones that may not support regions, this value is fragile. Consider
+ * alternate means to determine context.
+ */
+ @Deprecated
+ public String getRegion() {
+ return region;
+ }
+
+ /**
+ * The ID of the volume.
+ */
+ public String getVolumeId() {
+ return volumeId;
+ }
+
+ /**
+ * The ID of the instance.
+ */
+ public String getId() {
+ return instanceId;
+ }
+
+ /**
+ * The device as it is exposed to the instance.
+ */
+ public String getDevice() {
+ return device;
+ }
+
+ /**
+ * Volume state.
+ */
+ public Status getStatus() {
+ return status;
+ }
+
+ /**
+ * Time stamp when the attachment initiated.
+ */
+ 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 + ((region == null) ? 0 : region.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 (region == null) {
+ if (other.region != null)
+ return false;
+ } else if (!region.equals(other.region))
+ 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 [region=" + region + ", volumeId=" + volumeId + ", instanceId=" + instanceId + ", device="
+ + device + ", attachTime=" + attachTime + ", status=" + status + "]";
+ }
+
+ @Override
+ public int compareTo(Attachment o) {
+ return attachTime.compareTo(o.attachTime);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/AvailabilityZoneInfo.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/AvailabilityZoneInfo.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/AvailabilityZoneInfo.java
new file mode 100644
index 0000000..dcc9432
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/AvailabilityZoneInfo.java
@@ -0,0 +1,128 @@
+/*
+ * 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.ec2.domain;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Set;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
+/**
+ *
+ * @see <a href="http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-AvailabilityZoneItemType.html"
+ * />
+ */
+public class AvailabilityZoneInfo implements Comparable<AvailabilityZoneInfo> {
+
+ private final String zone;
+ private final String state;
+ private final String region;
+ private final Set<String> messages = Sets.newHashSet();
+
+ public AvailabilityZoneInfo(String zone, String zoneState,
+ String region, Iterable<String> messages) {
+ this.zone = checkNotNull(zone, "zone");
+ this.state = checkNotNull(zoneState, "zoneState");
+ this.region = checkNotNull(region, "region");
+ Iterables.addAll(this.messages, checkNotNull(messages, "messages"));
+ }
+
+ /**
+ * the Availability Zone.
+ */
+ public String getZone() {
+ return zone;
+ }
+
+ /**
+ * State of the Availability Zone.
+ */
+ public String getState() {
+ return state;
+ }
+
+ /**
+ * Name of the Region.
+ */
+ public String getRegion() {
+ return region;
+ }
+
+ /**
+ * Messages
+ */
+ public Set<String> getMessages() {
+ return messages;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((messages == null) ? 0 : messages.hashCode());
+ result = prime * result + ((region == null) ? 0 : region.hashCode());
+ result = prime * result + ((state == null) ? 0 : state.hashCode());
+ result = prime * result + ((zone == null) ? 0 : zone.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;
+ AvailabilityZoneInfo other = (AvailabilityZoneInfo) obj;
+ if (messages == null) {
+ if (other.messages != null)
+ return false;
+ } else if (!messages.equals(other.messages))
+ return false;
+ if (region == null) {
+ if (other.region != null)
+ return false;
+ } else if (!region.equals(other.region))
+ return false;
+ if (state == null) {
+ if (other.state != null)
+ return false;
+ } else if (!state.equals(other.state))
+ return false;
+ if (zone == null) {
+ if (other.zone != null)
+ return false;
+ } else if (!zone.equals(other.zone))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "AvailabilityZoneInfo [messages=" + messages + ", region=" + region + ", state="
+ + state + ", zone=" + zone + "]";
+ }
+
+ @Override
+ public int compareTo(AvailabilityZoneInfo that) {
+ return zone.compareTo(that.zone);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/89fab312/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/BlockDevice.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/BlockDevice.java b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/BlockDevice.java
new file mode 100644
index 0000000..b4a2710
--- /dev/null
+++ b/dependencies/jclouds/apis/ec2/1.8.0-stratos/src/main/java/org/jclouds/ec2/domain/BlockDevice.java
@@ -0,0 +1,108 @@
+/*
+ * 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.ec2.domain;
+
+import java.util.Date;
+
+import org.jclouds.ec2.domain.Attachment.Status;
+
+/**
+ *
+ * @see <a href=
+ * "http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-ItemType-RunningInstancesItemType.html"
+ * />
+ */
+public class BlockDevice {
+ private final String volumeId;
+ private final Attachment.Status attachmentStatus;
+ private final Date attachTime;
+ private final boolean deleteOnTermination;
+
+ public BlockDevice(String volumeId, Status attachmentStatus, Date attachTime, boolean deleteOnTermination) {
+ this.volumeId = volumeId;
+ this.attachmentStatus = attachmentStatus;
+ this.attachTime = attachTime;
+ this.deleteOnTermination = deleteOnTermination;
+ }
+
+ public BlockDevice(String volumeId, boolean deleteOnTermination) {
+ this(volumeId, null, null, deleteOnTermination);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((attachTime == null) ? 0 : attachTime.hashCode());
+ result = prime * result + ((attachmentStatus == null) ? 0 : attachmentStatus.hashCode());
+ result = prime * result + (deleteOnTermination ? 1231 : 1237);
+ 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;
+ BlockDevice other = (BlockDevice) obj;
+ if (attachTime == null) {
+ if (other.attachTime != null)
+ return false;
+ } else if (!attachTime.equals(other.attachTime))
+ return false;
+ if (attachmentStatus == null) {
+ if (other.attachmentStatus != null)
+ return false;
+ } else if (!attachmentStatus.equals(other.attachmentStatus))
+ return false;
+ if (deleteOnTermination != other.deleteOnTermination)
+ return false;
+ if (volumeId == null) {
+ if (other.volumeId != null)
+ return false;
+ } else if (!volumeId.equals(other.volumeId))
+ return false;
+ return true;
+ }
+
+ public String getVolumeId() {
+ return volumeId;
+ }
+
+ public Attachment.Status getAttachmentStatus() {
+ return attachmentStatus;
+ }
+
+ public Date getAttachTime() {
+ return attachTime;
+ }
+
+ public boolean isDeleteOnTermination() {
+ return deleteOnTermination;
+ }
+
+ @Override
+ public String toString() {
+ return "[volumeId=" + volumeId + ", attachmentStatus=" + attachmentStatus + ", attachTime="
+ + attachTime + ", deleteOnTermination=" + deleteOnTermination + "]";
+ }
+
+}