diff --git a/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java index 19837550e7..5496539fff 100644 --- a/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java +++ b/apis/byon/src/main/java/org/jclouds/byon/internal/BYONComputeServiceAdapter.java @@ -45,7 +45,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.ImmutableSet.Builder; import com.google.common.util.concurrent.UncheckedExecutionException; - /** * * @author Adrian Cole @@ -118,6 +117,11 @@ public class BYONComputeServiceAdapter implements JCloudsNativeComputeServiceAda return node != null ? converter.apply(node) : null; } + @Override + public Image getImage(final String id) { + throw new UnsupportedOperationException(); + } + @Override public void destroyNode(final String id) { throw new UnsupportedOperationException(); diff --git a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersComputeServiceAdapter.java b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersComputeServiceAdapter.java index df7a956be2..72d1a087b9 100644 --- a/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersComputeServiceAdapter.java +++ b/apis/cloudservers/src/main/java/org/jclouds/cloudservers/compute/strategy/CloudServersComputeServiceAdapter.java @@ -94,6 +94,12 @@ public class CloudServersComputeServiceAdapter implements ComputeServiceAdapter< public Server getNode(String id) { int serverId = Integer.parseInt(id); return client.getServer(serverId); + } + + @Override + public Image getImage(String id) { + int imageId = Integer.parseInt(id); + return client.getImage(imageId); } @Override diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java index 74327d03b1..1299acc9d5 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java @@ -210,7 +210,12 @@ public class CloudSigmaComputeServiceAdapter implements public ServerInfo getNode(String id) { return client.getServerInfo(id); } - + + @Override + public DriveInfo getImage(String id) { + return client.getDriveInfo(id); + } + @Override public void destroyNode(String id) { ServerInfo server = getNode(id); diff --git a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java index 8aeb94ff19..012d630034 100644 --- a/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java +++ b/apis/cloudstack/src/main/java/org/jclouds/cloudstack/compute/strategy/CloudStackComputeServiceAdapter.java @@ -22,6 +22,9 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.get; +import static org.jclouds.cloudstack.options.DeployVirtualMachineOptions.Builder.displayName; +import static org.jclouds.cloudstack.options.ListTemplatesOptions.Builder.id; import static org.jclouds.cloudstack.predicates.TemplatePredicates.isReady; import java.util.List; @@ -133,7 +136,7 @@ public class CloudStackComputeServiceAdapter implements CloudStackTemplateOptions templateOptions = template.getOptions().as(CloudStackTemplateOptions.class); checkState(optionsConverters.containsKey(zone.getNetworkType()), "no options converter configured for network type %s",zone.getNetworkType()); - DeployVirtualMachineOptions options = DeployVirtualMachineOptions.Builder.displayName(name).name(name); + DeployVirtualMachineOptions options = displayName(name).name(name); OptionsConverter optionsConverter = optionsConverters.get(zone.getNetworkType()); options = optionsConverter.apply(templateOptions, networks, zoneId, options); @@ -198,6 +201,11 @@ public class CloudStackComputeServiceAdapter implements return filter(client.getTemplateClient().listTemplates(), isReady()); } + @Override + public Template getImage(String id) { + return get(client.getTemplateClient().listTemplates(id(id)), 0, null); + } + @Override public Iterable listNodes() { return client.getVirtualMachineClient().listVirtualMachines(); diff --git a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java index 0a6349a02d..31857eddfc 100644 --- a/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java +++ b/apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java @@ -118,6 +118,11 @@ public class DeltacloudComputeServiceAdapter implements return client.getInstance(URI.create(checkNotNull(id, "id"))); } + @Override + public org.jclouds.deltacloud.domain.Image getImage(String id) { + return client.getImage(URI.create(checkNotNull(id, "id"))); + } + @Override public void destroyNode(String id) { Instance instance = getNode(id); diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java index 518feab89c..4a7d24bdd9 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java @@ -17,16 +17,18 @@ * under the License. */ package org.jclouds.ec2.compute; - import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.transform; import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; import static org.jclouds.util.Preconditions2.checkNotEmpty; import java.util.Map; -import java.util.Map.Entry; import java.util.Set; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicReference; @@ -53,6 +55,7 @@ import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; @@ -77,8 +80,8 @@ import com.google.common.base.Predicate; import com.google.common.base.Supplier; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.ImmutableMultimap.Builder; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableMultimap.Builder; import com.google.inject.Inject; /** @@ -93,26 +96,28 @@ public class EC2ComputeService extends BaseComputeService { @Inject protected EC2ComputeService(ComputeServiceContext context, Map credentialStore, - @Memoized Supplier> images, @Memoized Supplier> sizes, - @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, - RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, - ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy, - Provider templateBuilderProvider, Provider templateOptionsProvider, - @Named("NODE_RUNNING") Predicate> nodeRunning, - @Named("NODE_TERMINATED") Predicate> nodeTerminated, - @Named("NODE_SUSPENDED") Predicate> nodeSuspended, - InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, - RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, - PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client, - ConcurrentMap credentialsMap, @Named("SECURITY") LoadingCache securityGroupMap, - Optional imageExtension, GroupNamingConvention.Factory namingConvention) { - super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, - runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, - templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, - initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, timeouts, - executor, imageExtension); + @Memoized Supplier> images, @Memoized Supplier> sizes, + @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, + GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, + CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, + DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy, + SuspendNodeStrategy stopNodeStrategy, Provider templateBuilderProvider, + Provider templateOptionsProvider, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, + @Named(TIMEOUT_NODE_TERMINATED) Predicate> nodeTerminated, + @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, + RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, + PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, + @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client, + ConcurrentMap credentialsMap, + @Named("SECURITY") LoadingCache securityGroupMap, + Optional imageExtension, GroupNamingConvention.Factory namingConvention) { + super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy, + getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, + startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, + nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, + persistNodeCredentials, timeouts, executor, imageExtension); this.ec2Client = ec2Client; this.credentialsMap = credentialsMap; this.securityGroupMap = securityGroupMap; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java index 0a32887794..57cde3933f 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2BindComputeStrategiesByClass.java @@ -22,6 +22,7 @@ import org.jclouds.compute.config.BindComputeStrategiesByClass; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; @@ -29,6 +30,7 @@ import org.jclouds.compute.strategy.ResumeNodeStrategy; import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.ec2.compute.strategy.EC2CreateNodesInGroupThenAddToSet; import org.jclouds.ec2.compute.strategy.EC2DestroyNodeStrategy; +import org.jclouds.ec2.compute.strategy.EC2GetImageStrategy; import org.jclouds.ec2.compute.strategy.EC2GetNodeMetadataStrategy; import org.jclouds.ec2.compute.strategy.EC2ListNodesStrategy; import org.jclouds.ec2.compute.strategy.EC2RebootNodeStrategy; @@ -69,6 +71,11 @@ public class EC2BindComputeStrategiesByClass extends BindComputeStrategiesByClas return EC2GetNodeMetadataStrategy.class; } + @Override + protected Class defineGetImageStrategy() { + return EC2GetImageStrategy.class; + } + @Override protected Class defineListNodesStrategy() { return EC2ListNodesStrategy.class; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java index 54a750d2b2..9f40be09ba 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/config/EC2ComputeServiceDependenciesModule.java @@ -42,6 +42,7 @@ import org.jclouds.ec2.compute.extensions.EC2ImageExtension; import org.jclouds.ec2.compute.functions.AddElasticIpsToNodemetadata; import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; import org.jclouds.ec2.compute.functions.CredentialsForInstance; +import org.jclouds.ec2.compute.functions.EC2ImageParser; import org.jclouds.ec2.compute.functions.RunningInstanceToNodeMetadata; import org.jclouds.ec2.compute.functions.WindowsLoginCredentialsFromEncryptedData; import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; @@ -127,6 +128,8 @@ public class EC2ComputeServiceDependenciesModule extends AbstractModule { bind(new TypeLiteral>() { }).annotatedWith(Names.named("ELASTICIP")).to(LoadPublicIpForInstanceOrNull.class); bind(WindowsLoginCredentialsFromEncryptedData.class); + bind(new TypeLiteral>() { + }).to(EC2ImageParser.class); bind(new TypeLiteral() { }).to(EC2ImageExtension.class); bind(new TypeLiteral>() { diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java index a1f2dd27e4..465b63dbc5 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2CreateNodesInGroupThenAddToSet.java @@ -17,10 +17,10 @@ * under the License. */ package org.jclouds.ec2.compute.strategy; - import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.all; import static com.google.common.collect.Iterables.transform; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import static org.jclouds.ec2.compute.util.EC2ComputeUtils.getZoneFromLocationOrNull; import java.util.Map; @@ -57,9 +57,9 @@ import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; +import com.google.common.collect.ImmutableSet.Builder; /** * creates futures that correlate to @@ -102,7 +102,7 @@ public class EC2CreateNodesInGroupThenAddToSet implements CreateNodesInGroupThen EC2Client client, @Named("ELASTICIP") LoadingCache elasticIpCache, - @Named("NODE_RUNNING") Predicate> nodeRunning, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, Provider templateBuilderProvider, CreateKeyPairAndSecurityGroupsAsNeededAndReturnRunOptions createKeyPairAndSecurityGroupsAsNeededAndReturncustomize, InstancePresent instancePresent, Function runningInstanceToNodeMetadata, diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetImageStrategy.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetImageStrategy.java new file mode 100644 index 0000000000..a29ac4524c --- /dev/null +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/strategy/EC2GetImageStrategy.java @@ -0,0 +1,72 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.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.EC2Client; +import org.jclouds.ec2.domain.Image; +import org.jclouds.ec2.options.DescribeImagesOptions; + +import com.google.common.base.Function; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class EC2GetImageStrategy implements GetImageStrategy { + + private final EC2Client client; + private final Function imageToImage; + + @Inject + protected EC2GetImageStrategy(EC2Client client, Function 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.getAMIServices().describeImagesInRegion(region, + DescribeImagesOptions.Builder.imageIds(id))); + } + +} diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java index 0403679cd4..adce2eba15 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java @@ -202,6 +202,11 @@ public class ElasticStackComputeServiceAdapter implements @Override public ServerInfo getNode(String id) { return client.getServerInfo(id); + } + + @Override + public DriveInfo getImage(String id) { + return client.getDriveInfo(id); } @Override diff --git a/apis/nova/src/main/java/org/jclouds/openstack/nova/compute/strategy/NovaComputeServiceAdapter.java b/apis/nova/src/main/java/org/jclouds/openstack/nova/compute/strategy/NovaComputeServiceAdapter.java index 1fe73bc1d8..eff7bec3fd 100644 --- a/apis/nova/src/main/java/org/jclouds/openstack/nova/compute/strategy/NovaComputeServiceAdapter.java +++ b/apis/nova/src/main/java/org/jclouds/openstack/nova/compute/strategy/NovaComputeServiceAdapter.java @@ -91,6 +91,12 @@ public class NovaComputeServiceAdapter implements ComputeServiceAdapter credentialStore, - @Memoized Supplier> images, @Memoized Supplier> sizes, - @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, - RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, - ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy, - Provider templateBuilderProvider, Provider templateOptionsProvider, - @Named("NODE_RUNNING") Predicate> nodeRunning, - @Named("NODE_TERMINATED") Predicate> nodeTerminated, - @Named("NODE_SUSPENDED") Predicate> nodeSuspended, - InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, - RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, - PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, NovaClient novaClient, - LoadingCache securityGroupMap, - LoadingCache keyPairCache, - Function, Multimap> orphanedGroupsByZoneId, - GroupNamingConvention.Factory namingConvention, Optional imageExtension) { - super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, - runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, - stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, - nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, - timeouts, executor, imageExtension); + @Memoized Supplier> images, @Memoized Supplier> sizes, + @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, + GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, + CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, + DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy, + SuspendNodeStrategy stopNodeStrategy, Provider templateBuilderProvider, + Provider templateOptionsProvider, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, + @Named(TIMEOUT_NODE_TERMINATED) Predicate> nodeTerminated, + @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, + RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, + PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, + @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, NovaClient novaClient, + LoadingCache securityGroupMap, + LoadingCache keyPairCache, + Function, Multimap> orphanedGroupsByZoneId, + GroupNamingConvention.Factory namingConvention, Optional imageExtension) { + super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy, + getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, + startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, + nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, + persistNodeCredentials, timeouts, executor, imageExtension); this.novaClient = checkNotNull(novaClient, "novaClient"); this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap"); this.keyPairCache = checkNotNull(keyPairCache, "keyPairCache"); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceAdapter.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceAdapter.java index 2603a5f69c..e550435607 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceAdapter.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceAdapter.java @@ -198,6 +198,13 @@ public class NovaComputeServiceAdapter implements return server == null ? null : new ServerInZone(server, zoneAndId.getZone()); } + @Override + public ImageInZone getImage(String id) { + ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id); + Image image = novaClient.getImageClientForZone(zoneAndId.getZone()).getImage(zoneAndId.getId()); + return image == null ? null : new ImageInZone(image, zoneAndId.getZone()); + } + @Override public void destroyNode(String id) { ZoneAndId zoneAndId = ZoneAndId.fromSlashEncoded(id); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java index 3576c11fb2..63244c36a7 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java @@ -182,7 +182,7 @@ public class NovaComputeServiceContextModule extends @Provides @Singleton - @Named("SECURITY") + @Named(TIMEOUT_SECURITYGROUP_PRESENT) protected Predicate> securityGroupEventualConsistencyDelay( FindSecurityGroupWithNameAndReturnTrue in, @Named(TIMEOUT_SECURITYGROUP_PRESENT) long msDelay) { diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/AllocateAndAddFloatingIpToNode.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/AllocateAndAddFloatingIpToNode.java index 6f14e4db0e..6bfda9115f 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/AllocateAndAddFloatingIpToNode.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/AllocateAndAddFloatingIpToNode.java @@ -17,9 +17,9 @@ * under the License. */ package org.jclouds.openstack.nova.v1_1.compute.functions; - import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import java.util.ArrayList; import java.util.Collections; @@ -64,7 +64,7 @@ public class AllocateAndAddFloatingIpToNode implements private final LoadingCache> floatingIpCache; @Inject - public AllocateAndAddFloatingIpToNode(@Named("NODE_RUNNING") Predicate> nodeRunning, + public AllocateAndAddFloatingIpToNode(@Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, NovaClient novaClient, @Named("FLOATINGIP") LoadingCache> floatingIpCache) { this.nodeRunning = checkNotNull(nodeRunning, "nodeRunning"); this.novaClient = checkNotNull(novaClient, "novaClient"); diff --git a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/loaders/FindSecurityGroupOrCreate.java b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/loaders/FindSecurityGroupOrCreate.java index 6e0933c0a5..26ba957c9c 100644 --- a/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/loaders/FindSecurityGroupOrCreate.java +++ b/apis/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/loaders/FindSecurityGroupOrCreate.java @@ -17,9 +17,9 @@ * under the License. */ package org.jclouds.openstack.nova.v1_1.compute.loaders; - import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import static org.jclouds.openstack.nova.v1_1.config.NovaProperties.TIMEOUT_SECURITYGROUP_PRESENT; import java.util.concurrent.atomic.AtomicReference; @@ -45,7 +45,7 @@ public class FindSecurityGroupOrCreate extends CacheLoader> returnSecurityGroupExistsInZone, + @Named(TIMEOUT_SECURITYGROUP_PRESENT) Predicate> returnSecurityGroupExistsInZone, Function groupCreator) { this.returnSecurityGroupExistsInZone = checkNotNull(returnSecurityGroupExistsInZone, "returnSecurityGroupExistsInZone"); diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudComputeServiceAdapter.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudComputeServiceAdapter.java index d2c919868f..cb508a3acd 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudComputeServiceAdapter.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/compute/strategy/VCloudComputeServiceAdapter.java @@ -162,7 +162,13 @@ public class VCloudComputeServiceAdapter implements ComputeServiceAdapter credentialStore, - @Memoized Supplier> images, @Memoized Supplier> sizes, - @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, - RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, - ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy, - Provider templateBuilderProvider, Provider templateOptionsProvider, - @Named("NODE_RUNNING") Predicate> nodeRunning, - @Named("NODE_TERMINATED") Predicate> nodeTerminated, - @Named("NODE_SUSPENDED") Predicate> nodeSuspended, - InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, - RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, - PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, CleanupOrphanKeys cleanupOrphanKeys, - Optional imageExtension) { - super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, - runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, resumeNodeStrategy, - suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, - nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, - timeouts, executor, imageExtension); + @Memoized Supplier> images, @Memoized Supplier> sizes, + @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, + GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, + CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, + DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy resumeNodeStrategy, + SuspendNodeStrategy suspendNodeStrategy, Provider templateBuilderProvider, + Provider templateOptionsProvider, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, + @Named(TIMEOUT_NODE_TERMINATED) Predicate> nodeTerminated, + @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, + RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, + PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, + @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, CleanupOrphanKeys cleanupOrphanKeys, + Optional imageExtension) { + super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy, + getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, + resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, + nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, + persistNodeCredentials, timeouts, executor, imageExtension); this.cleanupOrphanKeys = cleanupOrphanKeys; } diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkBindComputeStrategiesByClass.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkBindComputeStrategiesByClass.java index 66e6f9013e..30fe05bf7d 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkBindComputeStrategiesByClass.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkBindComputeStrategiesByClass.java @@ -22,6 +22,7 @@ import org.jclouds.compute.config.BindComputeStrategiesByClass; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; @@ -30,6 +31,7 @@ import org.jclouds.compute.strategy.SuspendNodeStrategy; import org.jclouds.trmk.vcloud_0_8.compute.strategy.StartVAppWithGroupEncodedIntoName; import org.jclouds.trmk.vcloud_0_8.compute.strategy.TerremarkEncodeTagIntoNameRunNodesAndAddToSetStrategy; import org.jclouds.trmk.vcloud_0_8.compute.strategy.TerremarkVCloudDestroyNodeStrategy; +import org.jclouds.trmk.vcloud_0_8.compute.strategy.TerremarkVCloudGetImageStrategy; import org.jclouds.trmk.vcloud_0_8.compute.strategy.TerremarkVCloudGetNodeMetadataStrategy; import org.jclouds.trmk.vcloud_0_8.compute.strategy.TerremarkVCloudLifeCycleStrategy; import org.jclouds.trmk.vcloud_0_8.compute.strategy.TerremarkVCloudListNodesStrategy; @@ -49,6 +51,11 @@ public class TerremarkBindComputeStrategiesByClass extends BindComputeStrategies return TerremarkVCloudGetNodeMetadataStrategy.class; } + @Override + protected Class defineGetImageStrategy() { + return TerremarkVCloudGetImageStrategy.class; + } + @Override protected Class defineListNodesStrategy() { return TerremarkVCloudListNodesStrategy.class; diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java index fcafc8e2a0..c192f23ad7 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/config/TerremarkVCloudComputeServiceContextModule.java @@ -33,6 +33,7 @@ import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; import org.jclouds.trmk.vcloud_0_8.compute.TerremarkVCloudComputeService; import org.jclouds.trmk.vcloud_0_8.compute.domain.OrgAndName; +import org.jclouds.trmk.vcloud_0_8.compute.functions.ImageForVCloudExpressVAppTemplate; import org.jclouds.trmk.vcloud_0_8.compute.functions.ImagesInVCloudExpressOrg; import org.jclouds.trmk.vcloud_0_8.compute.functions.NodeMetadataToOrgAndName; import org.jclouds.trmk.vcloud_0_8.compute.functions.ParseOsFromVAppTemplateName; @@ -42,6 +43,7 @@ import org.jclouds.trmk.vcloud_0_8.compute.strategy.ParseVAppTemplateDescription import org.jclouds.trmk.vcloud_0_8.domain.Org; import org.jclouds.trmk.vcloud_0_8.domain.Status; import org.jclouds.trmk.vcloud_0_8.domain.VApp; +import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; @@ -103,7 +105,10 @@ public class TerremarkVCloudComputeServiceContextModule extends BaseComputeServi bind(SecureRandom.class).toInstance(new SecureRandom()); install(new TerremarkBindComputeStrategiesByClass()); install(new TerremarkBindComputeSuppliersByClass()); - bindVAppConverter(); + bind(new TypeLiteral>() { + }).to(VAppToNodeMetadata.class); + bind(new TypeLiteral>() { + }).to(ImageForVCloudExpressVAppTemplate.class); bind(new TypeLiteral>>() { }).to(new TypeLiteral() { }); @@ -111,11 +116,6 @@ public class TerremarkVCloudComputeServiceContextModule extends BaseComputeServi }).to(ParseOsFromVAppTemplateName.class); } - protected void bindVAppConverter() { - bind(new TypeLiteral>() { - }).to(VAppToNodeMetadata.class); - } - @Provides @Singleton Supplier provideSuffix(final SecureRandom random) { diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingGetNodeMetadataStrategy.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/TerremarkVCloudGetImageStrategy.java similarity index 50% rename from providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingGetNodeMetadataStrategy.java rename to common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/TerremarkVCloudGetImageStrategy.java index 4f052633b4..ec0a9e86fb 100644 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingGetNodeMetadataStrategy.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/compute/strategy/TerremarkVCloudGetImageStrategy.java @@ -16,39 +16,44 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.rimuhosting.miro.compute.strategy; +package org.jclouds.trmk.vcloud_0_8.compute.strategy; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; import javax.inject.Inject; import javax.inject.Singleton; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.strategy.GetNodeMetadataStrategy; -import org.jclouds.rimuhosting.miro.RimuHostingClient; -import org.jclouds.rimuhosting.miro.domain.Server; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.strategy.GetImageStrategy; +import org.jclouds.trmk.vcloud_0_8.TerremarkVCloudClient; +import org.jclouds.trmk.vcloud_0_8.domain.VAppTemplate; import com.google.common.base.Function; /** - * * @author Adrian Cole */ @Singleton -public class RimuHostingGetNodeMetadataStrategy implements GetNodeMetadataStrategy { +public class TerremarkVCloudGetImageStrategy implements GetImageStrategy { - private final RimuHostingClient client; - private final Function serverToNodeMetadata; + protected final TerremarkVCloudClient client; + protected final Function vAppToImage; @Inject - protected RimuHostingGetNodeMetadataStrategy(RimuHostingClient client, - Function serverToNodeMetadata) { - this.client = client; - this.serverToNodeMetadata = serverToNodeMetadata; + protected TerremarkVCloudGetImageStrategy(TerremarkVCloudClient client, Function vAppToImage) { + this.client = checkNotNull(client, "client"); + this.vAppToImage = vAppToImage; } @Override - public NodeMetadata getNode(String id) { - long serverId = Long.parseLong(id); - Server server = client.getServer(serverId); - return server == null ? null : serverToNodeMetadata.apply(server); + public Image getImage(String in) { + URI id = URI.create(in); + VAppTemplate from = client.getVAppTemplate(id); + if (from == null) + return null; + return vAppToImage.apply(from); } + } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/ComputeService.java b/compute/src/main/java/org/jclouds/compute/ComputeService.java index 40083c8abb..65cc0a38ac 100644 --- a/compute/src/main/java/org/jclouds/compute/ComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeService.java @@ -74,7 +74,9 @@ public interface ComputeService { * differently. However, it is a good indicator of relative speed within a cloud. memory is * measured in megabytes and disks in gigabytes. * - * @return a map of hardware profiles by ID, conceding that in some clouds the "id" is not used. + *

note

+ * + * This is a cached collection */ Set listHardwareProfiles(); @@ -82,10 +84,22 @@ public interface ComputeService { * Images define the operating system and metadata related to a node. In some clouds, Images are * bound to a specific region, and their identifiers are different across these regions. For this * reason, you should consider matching image requirements like operating system family with - * TemplateBuilder as opposed to choosing an image explicitly. The getImages() command returns a - * map of images by id. + * TemplateBuilder as opposed to choosing an image explicitly. + * + *

note

+ * + * This is a cached collection */ Set listImages(); + + /** + * Find an image by its id. + * + *

note

+ * + * This is an uncached call to the backend service + */ + Image getImage(String id); /** * all nodes available to the current user by id. If possible, the returned set will include @@ -98,6 +112,10 @@ public interface ComputeService { * which is typically region or zone. A region is a general area, like eu-west, where a zone is * similar to a datacenter. If a location has a parent, that implies it is within that location. * For example a location can be a rack, whose parent is likely to be a zone. + * + *

note

+ * + * This is a cached collection */ Set listAssignableLocations(); diff --git a/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java index f39e820e43..f56c24ceb6 100644 --- a/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/ComputeServiceAdapter.java @@ -20,14 +20,19 @@ package org.jclouds.compute; import static com.google.common.base.Preconditions.checkNotNull; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.Template; import org.jclouds.domain.LoginCredentials; import org.jclouds.javax.annotation.Nullable; /** - * A means of specifying the interface between the {@link ComputeService - * ComputeServices} and a concrete compute cloud implementation, jclouds or - * otherwise. + * A means of specifying the interface between the {@link ComputeService ComputeServices} and a + * concrete compute cloud implementation, jclouds or otherwise. + * + *

Important

+ * + * While implementations may cache results of calls to this interface, it is important to not cache + * within this. Otherwise, status updates will not be visible immediately. * * @author Adrian Cole * @@ -35,33 +40,29 @@ import org.jclouds.javax.annotation.Nullable; public interface ComputeServiceAdapter { /** - * {@link ComputeService#createNodesInGroup(String, int, Template)} generates - * the parameters passed into this method such that each node in the set has - * a unique name. + * {@link ComputeService#createNodesInGroup(String, int, Template)} generates the parameters + * passed into this method such that each node in the set has a unique name. * - *

note

It is intentional to return the library native node object, - * as generic type {@code N}. If you are not using library-native objects - * (such as libvirt {@code Domain}) use + *

note

It is intentional to return the library native node object, as generic type + * {@code N}. If you are not using library-native objects (such as libvirt {@code Domain}) use * {@link JCloudsNativeComputeServiceAdapter} instead. * - *

note

Your responsibility is to create a node with the underlying - * library and return after storing its credentials in the supplied map - * corresponding to {@link ComputeServiceContext#getCredentialStore - * credentialStore} + *

note

Your responsibility is to create a node with the underlying library and return + * after storing its credentials in the supplied map corresponding to + * {@link ComputeServiceContext#getCredentialStore credentialStore} * - * @param tag + * @param group * used to aggregate nodes with identical configuration * @param name - * unique supplied name for the node, which has the tag encoded - * into it. + * unique supplied name for the node, which has the group encoded into it. * @param template - * includes {@code imageId}, {@code locationId}, and - * {@code hardwareId} used to resume the instance. - * @return library-native representation of a node. - * TODO: return typed exception on createNodeFailure + * includes {@code imageId}, {@code locationId}, and {@code hardwareId} used to resume + * the instance. + * @return library-native representation of a node. TODO: return typed exception on + * createNodeFailure * @see ComputeService#createNodesInGroup(String, int, Template) */ - NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String tag, String name, Template template); + NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, Template template); public static class NodeAndInitialCredentials { private final N node; @@ -92,8 +93,8 @@ public interface ComputeServiceAdapter { /** * - * @return credentials given by the api for the node, or null if this - * information is not available + * @return credentials given by the api for the node, or null if this information is not + * available */ @Nullable public LoginCredentials getCredentials() { @@ -102,12 +103,11 @@ public interface ComputeServiceAdapter { } /** - * Hardware profiles describe available cpu, memory, and disk configurations - * that can be used to run a node. + * Hardware profiles describe available cpu, memory, and disk configurations that can be used to + * run a node. *

- * To implement this method, return the library native hardware profiles - * available to the user. These will be used to launch nodes as a part of the - * template. + * To implement this method, return the library native hardware profiles available to the user. + * These will be used to launch nodes as a part of the template. * * @return a non-null iterable of available hardware profiles. * @see ComputeService#listHardwareProfiles() @@ -115,22 +115,31 @@ public interface ComputeServiceAdapter { Iterable listHardwareProfiles(); /** - * Images are the available configured operating systems that someone can run - * a node with. * + * Images are the available configured operating systems that someone can run a node with. *

- * To implement this method, return the library native images available to - * the user. These will be used to launch nodes as a part of the template. + * To implement this method, return the library native images available to the user. These will + * be used to launch nodes as a part of the template. * * @return a non-null iterable of available images. * @see ComputeService#listImages() */ Iterable listImages(); + /** + * get a specific image by id + * + * @param id + * {@link Image#getId}, which is not necessarily {@link Image#getProviderId} + * @return image or null if not exists. + */ + @Nullable + I getImage(String id); + Iterable listLocations(); N getNode(String id); - //TODO consider making reboot/resume/suspend return the node they affected + // TODO consider making reboot/resume/suspend return the node they affected void destroyNode(String id); void rebootNode(String id); diff --git a/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java b/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java index b097fc527b..7274f53b23 100644 --- a/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java +++ b/compute/src/main/java/org/jclouds/compute/config/BindComputeStrategiesByClass.java @@ -21,6 +21,7 @@ package org.jclouds.compute.config; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.RebootNodeStrategy; @@ -42,6 +43,7 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule { bindAddNodeWithTagStrategy(defineAddNodeWithTagStrategy()); bindListNodesStrategy(defineListNodesStrategy()); bindGetNodeMetadataStrategy(defineGetNodeMetadataStrategy()); + bindGetImageStrategy(defineGetImageStrategy()); bindRebootNodeStrategy(defineRebootNodeStrategy()); bindStartNodeStrategy(defineStartNodeStrategy()); bindStopNodeStrategy(defineStopNodeStrategy()); @@ -78,7 +80,11 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule { protected void bindGetNodeMetadataStrategy(Class clazz) { bind(GetNodeMetadataStrategy.class).to(clazz).in(Scopes.SINGLETON); } - + + protected void bindGetImageStrategy(Class clazz) { + bind(GetImageStrategy.class).to(clazz).in(Scopes.SINGLETON); + } + protected void bindListNodesStrategy(Class clazz) { bind(ListNodesStrategy.class).to(clazz).in(Scopes.SINGLETON); } @@ -102,5 +108,7 @@ public abstract class BindComputeStrategiesByClass extends AbstractModule { protected abstract Class defineGetNodeMetadataStrategy(); + protected abstract Class defineGetImageStrategy(); + protected abstract Class defineListNodesStrategy(); } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java index 212ab43b6f..cdeb42d309 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceAdapterContextModule.java @@ -35,6 +35,7 @@ import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.ImageBuilder; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy; @@ -161,6 +162,12 @@ public class ComputeServiceAdapterContextModule extends BaseComputeS return in; } + @Provides + @Singleton + protected GetImageStrategy defineGetImageStrategy(AdaptingComputeServiceStrategies in) { + return in; + } + @Provides @Singleton protected ListNodesStrategy defineListNodesStrategy(AdaptingComputeServiceStrategies in) { diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java index 49a0d54de5..b071aacb04 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceProperties.java @@ -18,8 +18,9 @@ */ package org.jclouds.compute.config; +import org.jclouds.ContextBuilder; import org.jclouds.compute.domain.TemplateBuilderSpec; - +import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; /** * @@ -29,31 +30,51 @@ public interface ComputeServiceProperties { public static final String RESOURCENAME_PREFIX = "jclouds.compute.resourcename-prefix"; public static final String RESOURCENAME_DELIMITER = "jclouds.compute.resourcename-delimiter"; - public static final String TIMEOUT_NODE_TERMINATED = "jclouds.compute.timeout.node-terminated"; public static final String TIMEOUT_NODE_RUNNING = "jclouds.compute.timeout.node-running"; public static final String TIMEOUT_NODE_SUSPENDED = "jclouds.compute.timeout.node-suspended"; + public static final String TIMEOUT_NODE_TERMINATED = "jclouds.compute.timeout.node-terminated"; + public static final String TIMEOUT_SCRIPT_COMPLETE = "jclouds.compute.timeout.script-complete"; public static final String TIMEOUT_PORT_OPEN = "jclouds.compute.timeout.port-open"; - + public static final String INIT_STATUS_INITIAL_PERIOD = "jclouds.compute.init-status.initial-period"; public static final String INIT_STATUS_MAX_PERIOD = "jclouds.compute.init-status.max-period"; + + /** + * time in milliseconds to wait for an image to finish creating. + * + * Override {@link Timeouts#imageAvailable default} by setting this property using + * {@link ContextBuilder#overrides} + */ + public static final String TIMEOUT_IMAGE_AVAILABLE = "jclouds.compute.timeout.image-available"; /** - * overrides the default specified in the subclass of {@link BaseComputeServiceContextModule#provideTemplate} + * time in milliseconds to wait for an image to delete. + * + * Override {@link Timeouts#imageDeleted default} by setting this property using + * {@link ContextBuilder#overrides} + */ + public static final String TIMEOUT_IMAGE_DELETED = "jclouds.compute.timeout.image-deleted"; + + /** + * overrides the default specified in the subclass of + * {@link BaseComputeServiceContextModule#provideTemplate} + * * @see TemplateBuilderSpec */ public static final String TEMPLATE = "jclouds.template"; - + /** - * overrides the image specified in the subclass of {@link BaseComputeServiceContextModule#provideTemplate} + * overrides the image specified in the subclass of + * {@link BaseComputeServiceContextModule#provideTemplate} */ public static final String IMAGE_ID = "jclouds.image-id"; /** - * username and, if colon delimited, password of the default user on the image that is or can become root + * username and, if colon delimited, password of the default user on the image that is or can + * become root *

- * ex. {@code ubuntu} - * ex. {@code toor:password} + * ex. {@code ubuntu} ex. {@code toor:password} */ public static final String IMAGE_LOGIN_USER = "jclouds.image.login-user"; @@ -63,8 +84,8 @@ public interface ComputeServiceProperties { public static final String IMAGE_AUTHENTICATE_SUDO = "jclouds.image.authenticate-sudo"; /** - * comma-separated nodes that we shouldn't attempt to list as they are dead - * in the provider for some reason. + * comma-separated nodes that we shouldn't attempt to list as they are dead in the provider for + * some reason. */ public static final String BLACKLIST_NODES = "jclouds.compute.blacklist-nodes"; diff --git a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java index 99dc468af4..39a81956a2 100644 --- a/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java +++ b/compute/src/main/java/org/jclouds/compute/config/ComputeServiceTimeoutsModule.java @@ -17,19 +17,27 @@ * under the License. */ package org.jclouds.compute.config; - import static com.google.common.base.Predicates.not; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_DELETED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE; import java.util.concurrent.atomic.AtomicReference; import javax.inject.Named; import javax.inject.Singleton; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.predicates.AtomicImageAvailable; +import org.jclouds.compute.predicates.AtomicImageDeleted; import org.jclouds.compute.predicates.AtomicNodeRunning; import org.jclouds.compute.predicates.AtomicNodeSuspended; -import org.jclouds.compute.predicates.ScriptStatusReturnsZero; import org.jclouds.compute.predicates.AtomicNodeTerminated; +import org.jclouds.compute.predicates.ScriptStatusReturnsZero; import org.jclouds.compute.predicates.ScriptStatusReturnsZero.CommandUsingClient; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.predicates.RetryablePredicate; @@ -47,37 +55,53 @@ public class ComputeServiceTimeoutsModule extends AbstractModule { @Provides @Singleton - @Named("NODE_RUNNING") - protected Predicate> nodeRunning(AtomicNodeRunning stateRunning, Timeouts timeouts) { - return timeouts.nodeRunning == 0 ? stateRunning : new RetryablePredicate>(stateRunning, + @Named(TIMEOUT_NODE_RUNNING) + protected Predicate> nodeRunning(AtomicNodeRunning statusRunning, Timeouts timeouts) { + return timeouts.nodeRunning == 0 ? statusRunning : new RetryablePredicate>(statusRunning, timeouts.nodeRunning); } @Provides @Singleton - @Named("NODE_TERMINATED") - protected Predicate> serverTerminated(AtomicNodeTerminated stateTerminated, Timeouts timeouts) { - return timeouts.nodeTerminated == 0 ? stateTerminated : new RetryablePredicate>(stateTerminated, + @Named(TIMEOUT_NODE_TERMINATED) + protected Predicate> serverTerminated(AtomicNodeTerminated statusTerminated, Timeouts timeouts) { + return timeouts.nodeTerminated == 0 ? statusTerminated : new RetryablePredicate>(statusTerminated, timeouts.nodeTerminated); } @Provides @Singleton - @Named("NODE_SUSPENDED") - protected Predicate> serverSuspended(AtomicNodeSuspended stateSuspended, Timeouts timeouts) { - return timeouts.nodeSuspended == 0 ? stateSuspended : new RetryablePredicate>(stateSuspended, + @Named(TIMEOUT_NODE_SUSPENDED) + protected Predicate> serverSuspended(AtomicNodeSuspended statusSuspended, Timeouts timeouts) { + return timeouts.nodeSuspended == 0 ? statusSuspended : new RetryablePredicate>(statusSuspended, timeouts.nodeSuspended); } @Provides @Singleton - @Named("SCRIPT_COMPLETE") - protected Predicate runScriptRunning(ScriptStatusReturnsZero stateRunning, Timeouts timeouts) { - return timeouts.scriptComplete == 0 ? not(stateRunning) : new RetryablePredicate( - not(stateRunning), timeouts.scriptComplete); + @Named(TIMEOUT_SCRIPT_COMPLETE) + protected Predicate runScriptRunning(ScriptStatusReturnsZero statusRunning, Timeouts timeouts) { + return timeouts.scriptComplete == 0 ? not(statusRunning) : new RetryablePredicate( + not(statusRunning), timeouts.scriptComplete); + } + + @Provides + @Singleton + @Named(TIMEOUT_IMAGE_AVAILABLE) + protected Predicate> imageAvailable(AtomicImageAvailable statusAvailable, Timeouts timeouts) { + return timeouts.imageAvailable == 0 ? statusAvailable : new RetryablePredicate>(statusAvailable, + timeouts.imageAvailable); } + @Provides + @Singleton + @Named(TIMEOUT_IMAGE_DELETED) + protected Predicate> serverDeleted(AtomicImageDeleted statusDeleted, Timeouts timeouts) { + return timeouts.imageDeleted == 0 ? statusDeleted : new RetryablePredicate>(statusDeleted, + timeouts.imageDeleted); + } + @Override protected void configure() { diff --git a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java index 8c74e9837f..ae62ff51ad 100644 --- a/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java +++ b/compute/src/main/java/org/jclouds/compute/internal/BaseComputeService.java @@ -17,7 +17,6 @@ * under the License. */ package org.jclouds.compute.internal; - import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.and; import static com.google.common.base.Predicates.not; @@ -27,6 +26,9 @@ import static com.google.common.collect.Maps.newLinkedHashMap; import static com.google.common.collect.Sets.filter; import static com.google.common.collect.Sets.newLinkedHashSet; import static com.google.common.util.concurrent.Futures.immediateFuture; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; import static org.jclouds.compute.predicates.NodePredicates.TERMINATED; import static org.jclouds.compute.predicates.NodePredicates.all; import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus; @@ -72,6 +74,7 @@ import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; @@ -119,6 +122,7 @@ public class BaseComputeService implements ComputeService { private final Supplier> images; private final Supplier> hardwareProfiles; private final Supplier> locations; + private final GetImageStrategy getImageStrategy; private final ListNodesStrategy listNodesStrategy; private final GetNodeMetadataStrategy getNodeMetadataStrategy; private final CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy; @@ -141,26 +145,29 @@ public class BaseComputeService implements ComputeService { @Inject protected BaseComputeService(ComputeServiceContext context, Map credentialStore, - @Memoized Supplier> images, @Memoized Supplier> hardwareProfiles, - @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, - RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, - ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy, - Provider templateBuilderProvider, Provider templateOptionsProvider, - @Named("NODE_RUNNING") Predicate> nodeRunning, - @Named("NODE_TERMINATED") Predicate> nodeTerminated, - @Named("NODE_SUSPENDED") Predicate> nodeSuspended, - InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, - RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials, - Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, - Optional imageExtension) { + @Memoized Supplier> images, + @Memoized Supplier> hardwareProfiles, + @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, + GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, + CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, + DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy resumeNodeStrategy, + SuspendNodeStrategy suspendNodeStrategy, Provider templateBuilderProvider, + Provider templateOptionsProvider, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, + @Named(TIMEOUT_NODE_TERMINATED) Predicate> nodeTerminated, + @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, + RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials, + Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, + Optional imageExtension) { this.context = checkNotNull(context, "context"); this.credentialStore = checkNotNull(credentialStore, "credentialStore"); this.images = checkNotNull(images, "images"); this.hardwareProfiles = checkNotNull(hardwareProfiles, "hardwareProfiles"); this.locations = checkNotNull(locations, "locations"); - this.listNodesStrategy = checkNotNull(listNodesStrategy, "listNodesStrategy"); this.getNodeMetadataStrategy = checkNotNull(getNodeMetadataStrategy, "getNodeMetadataStrategy"); + this.listNodesStrategy = checkNotNull(listNodesStrategy, "listNodesStrategy"); + this.getImageStrategy = checkNotNull(getImageStrategy, "getImageStrategy"); this.runNodesAndAddToSetStrategy = checkNotNull(runNodesAndAddToSetStrategy, "runNodesAndAddToSetStrategy"); this.rebootNodeStrategy = checkNotNull(rebootNodeStrategy, "rebootNodeStrategy"); this.resumeNodeStrategy = checkNotNull(resumeNodeStrategy, "resumeNodeStrategy"); @@ -390,6 +397,15 @@ public class BaseComputeService implements ComputeService { return getNodeMetadataStrategy.getNode(id); } + /** + * {@inheritDoc} + */ + @Override + public Image getImage(String id) { + checkNotNull(id, "id"); + return getImageStrategy.getImage(id); + } + /** * {@inheritDoc} */ diff --git a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java index 002948dce6..ba39b1f700 100644 --- a/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java +++ b/compute/src/main/java/org/jclouds/compute/reference/ComputeServiceConstants.java @@ -25,6 +25,8 @@ import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_LOGIN_US import static org.jclouds.compute.config.ComputeServiceProperties.INIT_STATUS_INITIAL_PERIOD; import static org.jclouds.compute.config.ComputeServiceProperties.INIT_STATUS_MAX_PERIOD; import static org.jclouds.compute.config.ComputeServiceProperties.OS_VERSION_MAP_JSON; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_DELETED; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; @@ -32,6 +34,7 @@ import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_O import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE; import java.security.SecureRandom; +import java.util.concurrent.TimeUnit; import javax.inject.Named; import javax.inject.Singleton; @@ -113,7 +116,7 @@ public interface ComputeServiceConstants { @Singleton public static class NamingConvention { - + @Inject(optional = true) public final Supplier randomSuffix = new Supplier() { final SecureRandom random = new SecureRandom(); @@ -124,7 +127,7 @@ public interface ComputeServiceConstants { } }; } - + @Singleton public static class InitStatusProperties { @Inject(optional = true) @@ -166,6 +169,21 @@ public interface ComputeServiceConstants { @Inject(optional = true) @Named(TIMEOUT_PORT_OPEN) public long portOpen = 600 * 1000; + + /** + * current value of {@link ComputeServiceProperties#TIMEOUT_IMAGE_DELETED} defaults to 30 + * seconds. + */ + @Inject(optional = true) + @Named(TIMEOUT_IMAGE_DELETED) + public long imageDeleted = TimeUnit.SECONDS.toMillis(30); + /** + * current value of {@link ComputeServiceProperties#TIMEOUT_IMAGE_AVAILABLE} defaults to 45 + * minutes. + */ + @Inject(optional = true) + @Named(TIMEOUT_IMAGE_AVAILABLE) + public long imageAvailable = TimeUnit.MINUTES.toMillis(45); } } diff --git a/compute/src/main/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.java b/compute/src/main/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.java index 6cfd54ecd8..616f39eb33 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.java @@ -17,11 +17,11 @@ * under the License. */ package org.jclouds.compute.strategy; - import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Throwables.getRootCause; import static java.lang.String.format; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import static org.jclouds.compute.util.ComputeServiceUtils.formatStatus; import java.util.Map; @@ -88,7 +88,7 @@ public class CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap implements Cal @AssistedInject public CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap( - @Named("NODE_RUNNING") Predicate> nodeRunning, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, OpenSocketFinder openSocketFinder, Timeouts timeouts, Function templateOptionsToStatement, InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, @Assisted TemplateOptions options, @@ -110,7 +110,7 @@ public class CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap implements Cal @AssistedInject public CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap( - @Named("NODE_RUNNING") Predicate> nodeRunning, GetNodeMetadataStrategy getNode, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, GetNodeMetadataStrategy getNode, OpenSocketFinder openSocketFinder, Timeouts timeouts, Function templateOptionsToStatement, InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, @Assisted TemplateOptions options, diff --git a/providers/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceContextModuleTest.java b/compute/src/main/java/org/jclouds/compute/strategy/GetImageStrategy.java similarity index 64% rename from providers/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceContextModuleTest.java rename to compute/src/main/java/org/jclouds/compute/strategy/GetImageStrategy.java index 0d80742c2d..2ce3f1e2ef 100644 --- a/providers/rimuhosting/src/test/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceContextModuleTest.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/GetImageStrategy.java @@ -16,22 +16,17 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.rimuhosting.miro.compute.config; +package org.jclouds.compute.strategy; -import org.jclouds.rimuhosting.miro.domain.internal.RunningState; -import org.testng.annotations.Test; +import org.jclouds.compute.domain.Image; /** + * returns all details associated to the image below. + * * @author Adrian Cole */ -@Test(groups = "unit") -public class RimuHostingComputeServiceContextModuleTest { +public interface GetImageStrategy { - public void testAllStatusCovered() { + Image getImage(String id); - for (RunningState state : RunningState.values()) { - assert RimuHostingComputeServiceDependenciesModule.runningStateToNodeStatus.containsKey(state) : state; - } - - } -} +} \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java b/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java index a337a85fe7..7a3d27288c 100644 --- a/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java +++ b/compute/src/main/java/org/jclouds/compute/strategy/impl/AdaptingComputeServiceStrategies.java @@ -32,6 +32,7 @@ import javax.inject.Singleton; import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceAdapter.NodeAndInitialCredentials; import org.jclouds.compute.domain.ComputeMetadata; +import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; import org.jclouds.compute.domain.NodeMetadataBuilder; import org.jclouds.compute.domain.Template; @@ -40,6 +41,7 @@ import org.jclouds.compute.predicates.NodePredicates; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.ListNodesStrategy; import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate; @@ -61,8 +63,9 @@ import com.google.common.collect.Iterables; */ @Singleton public class AdaptingComputeServiceStrategies implements CreateNodeWithGroupEncodedIntoName, - DestroyNodeStrategy, GetNodeMetadataStrategy, ListNodesStrategy, RebootNodeStrategy, ResumeNodeStrategy, - SuspendNodeStrategy { + DestroyNodeStrategy, GetNodeMetadataStrategy, GetImageStrategy, ListNodesStrategy, RebootNodeStrategy, + ResumeNodeStrategy, SuspendNodeStrategy { + @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; @@ -71,17 +74,20 @@ public class AdaptingComputeServiceStrategies implements CreateNodeW private final PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate; private final ComputeServiceAdapter client; private final Function nodeMetadataAdapter; + private final Function imageAdapter; @Inject public AdaptingComputeServiceStrategies(Map credentialStore, PrioritizeCredentialsFromTemplate prioritizeCredentialsFromTemplate, - ComputeServiceAdapter client, Function nodeMetadataAdapter) { + ComputeServiceAdapter client, Function nodeMetadataAdapter, + Function imageAdapter) { this.credentialStore = checkNotNull(credentialStore, "credentialStore"); this.prioritizeCredentialsFromTemplate = checkNotNull(prioritizeCredentialsFromTemplate, "prioritizeCredentialsFromTemplate"); this.client = checkNotNull(client, "client"); this.nodeMetadataAdapter = Functions.compose(addLoginCredentials, checkNotNull(nodeMetadataAdapter, "nodeMetadataAdapter")); + this.imageAdapter = checkNotNull(imageAdapter, "imageAdapter"); } private final Function addLoginCredentials = new Function() { @@ -108,7 +114,15 @@ public class AdaptingComputeServiceStrategies implements CreateNodeW public Iterable listDetailsOnNodesMatching(Predicate filter) { return Iterables.filter(Iterables.transform(client.listNodes(), nodeMetadataAdapter), filter); } - + + @Override + public Image getImage(String id) { + I image = client.getImage(checkNotNull(id, "id")); + if (image == null) + return null; + return imageAdapter.apply(image); + } + @Override public NodeMetadata getNode(String id) { N node = client.getNode(checkNotNull(id, "id")); diff --git a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java index 6f3b9a43c9..590b757414 100644 --- a/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java +++ b/compute/src/main/java/org/jclouds/compute/stub/config/StubComputeServiceAdapter.java @@ -42,6 +42,7 @@ import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.NodeMetadata.Status; +import org.jclouds.compute.predicates.ImagePredicates; import org.jclouds.domain.Location; import org.jclouds.domain.LoginCredentials; import org.jclouds.location.suppliers.all.JustProvider; @@ -51,6 +52,7 @@ import com.google.common.base.Supplier; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; import com.google.common.collect.ImmutableList.Builder; /** @@ -156,7 +158,12 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda } return images.build(); } - + + @Override + public Image getImage(String id) { + return Iterables.find(listImages(), ImagePredicates.idEquals(id), null); + } + @Override public Iterable listNodes() { return nodes.values(); @@ -230,4 +237,5 @@ public class StubComputeServiceAdapter implements JCloudsNativeComputeServiceAda setStateOnNode(Status.PENDING, node); setStateOnNodeAfterDelay(Status.SUSPENDED, node, 50); } + } \ No newline at end of file diff --git a/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java b/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java index efe3b84bee..ee2821706e 100644 --- a/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java +++ b/compute/src/main/java/org/jclouds/compute/util/ConcurrentOpenSocketFinder.java @@ -4,6 +4,7 @@ import static com.google.common.base.Preconditions.checkState; 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 org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import java.util.Collection; import java.util.NoSuchElementException; @@ -33,7 +34,6 @@ import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; import com.google.inject.Inject; - public class ConcurrentOpenSocketFinder implements OpenSocketFinder { @Resource @@ -46,7 +46,7 @@ public class ConcurrentOpenSocketFinder implements OpenSocketFinder { @Inject public ConcurrentOpenSocketFinder(SocketOpen socketTester, - @Named("NODE_RUNNING") final Predicate> nodeRunning, + @Named(TIMEOUT_NODE_RUNNING) final Predicate> nodeRunning, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService userThreads) { this.socketTester = socketTester; this.nodeRunning = nodeRunning; diff --git a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java index 3212e32ec6..207b92fc92 100644 --- a/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java +++ b/compute/src/test/java/org/jclouds/compute/internal/BaseComputeServiceLiveTest.java @@ -207,6 +207,11 @@ public abstract class BaseComputeServiceLiveTest extends BaseComputeServiceConte client.runScriptOnNodesMatching(runningInGroup("zebras-are-awesome"), InstallJDK.fromOpenJDK()); } + public void testImageById() { + Template defaultTemplate = view.getComputeService().templateBuilder().build(); + assertEquals(view.getComputeService().getImage(defaultTemplate.getImage().getId()), defaultTemplate.getImage()); + } + // since surefire and eclipse don't otherwise guarantee the order, we are // starting this one alphabetically before create2nodes.. @Test(enabled = true, dependsOnMethods = { "testCompareSizes" }) diff --git a/labs/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java b/labs/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java index 386b2c474c..0cb9f73bfb 100644 --- a/labs/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java +++ b/labs/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java @@ -194,7 +194,20 @@ public class GleSYSComputeServiceAdapter implements ComputeServiceAdapter listImages() { return client.getServerClient().listTemplates(); } + + // cheat until we have a getTemplate command + @Override + public OSTemplate getImage(final String id) { + return Iterables.find(listImages(), new Predicate(){ + @Override + public boolean apply(OSTemplate input) { + return input.getName().equals(id); + } + + }, null); + } + @Override public Iterable listNodes() { return Iterables2.concreteCopy(transformParallel(client.getServerClient().listServers(), new Function>() { diff --git a/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java b/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java index 9c6b6ea457..04934dcbe0 100644 --- a/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java +++ b/labs/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java @@ -47,8 +47,8 @@ import org.jclouds.savvis.vpdc.reference.VCloudMediaType; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.ImmutableSet.Builder; import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableSet.Builder; import com.google.inject.Inject; ; @@ -124,6 +124,19 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter() { + + @Override + public boolean apply(CIMOperatingSystem input) { + return (input.getOsType().getCode() + "").equals(id); + } + + }, null); + } + @Override public Iterable listNodes() { Builder builder = ImmutableSet.builder(); diff --git a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java index e2e1d21a1c..2bba7189bd 100644 --- a/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java +++ b/labs/virtualbox/src/main/java/org/jclouds/virtualbox/compute/VirtualBoxComputeServiceAdapter.java @@ -186,6 +186,14 @@ public class VirtualBoxComputeServiceAdapter implements ComputeServiceAdapter credentialStore, @Memoized Supplier> images, @Memoized Supplier> sizes, @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, + GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy, Provider templateBuilderProvider, Provider templateOptionsProvider, - @Named("NODE_RUNNING") Predicate> nodeRunning, - @Named("NODE_TERMINATED") Predicate> nodeTerminated, - @Named("NODE_SUSPENDED") Predicate> nodeSuspended, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, + @Named(TIMEOUT_NODE_TERMINATED) Predicate> nodeTerminated, + @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, @@ -116,7 +120,7 @@ public class AWSEC2ComputeService extends EC2ComputeService { @Named("DELETED") Predicate placementGroupDeleted, @Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames, AWSEC2AsyncClient aclient, Optional imageExtension, GroupNamingConvention.Factory namingConvention) { - super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, + super(context, credentialStore, images, sizes, locations, listNodesStrategy, getImageStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, initScriptRunnerFactory, runScriptOnNodeFactory, initAdminAccess, persistNodeCredentials, diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java index 81fa5b4128..f8c1538bbb 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/config/AWSEC2ComputeServiceDependenciesModule.java @@ -51,6 +51,7 @@ import org.jclouds.ec2.compute.domain.RegionAndName; import org.jclouds.ec2.compute.extensions.EC2ImageExtension; import org.jclouds.ec2.compute.functions.CreateUniqueKeyPair; import org.jclouds.ec2.compute.functions.CredentialsForInstance; +import org.jclouds.ec2.compute.functions.EC2ImageParser; import org.jclouds.ec2.compute.internal.EC2TemplateBuilderImpl; import org.jclouds.ec2.compute.loaders.CreateSecurityGroupIfNeeded; import org.jclouds.ec2.compute.loaders.LoadPublicIpForInstanceOrNull; @@ -98,6 +99,8 @@ public class AWSEC2ComputeServiceDependenciesModule extends EC2ComputeServiceDep bind(new TypeLiteral>() { }).to(RegionAndIdToImage.class); install(new FactoryModuleBuilder().build(CallForImages.Factory.class)); + bind(new TypeLiteral>() { + }).to(EC2ImageParser.class); bind(new TypeLiteral() { }).to(EC2ImageExtension.class); bind(new TypeLiteral>() { diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java index fdfbcf8e72..06d7fcf58d 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2CreateNodesInGroupThenAddToSet.java @@ -17,10 +17,10 @@ * under the License. */ package org.jclouds.aws.ec2.compute.strategy; - import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.transform; import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_GENERATE_INSTANCE_NAMES; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsValuesOfEmptyString; import java.util.Map; @@ -81,7 +81,7 @@ public class AWSEC2CreateNodesInGroupThenAddToSet extends EC2CreateNodesInGroupT protected AWSEC2CreateNodesInGroupThenAddToSet( AWSEC2Client client, @Named("ELASTICIP") LoadingCache elasticIpCache, - @Named("NODE_RUNNING") Predicate> nodeRunning, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, AWSEC2AsyncClient aclient, @Named(PROPERTY_EC2_GENERATE_INSTANCE_NAMES) boolean generateInstanceNames, Provider templateBuilderProvider, diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java index 138b64accc..c8efd53f1f 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java @@ -17,6 +17,9 @@ * under the License. */ package org.jclouds.gogrid.compute; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; import java.util.Map; import java.util.Set; @@ -43,6 +46,7 @@ import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts; import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; import org.jclouds.compute.strategy.DestroyNodeStrategy; +import org.jclouds.compute.strategy.GetImageStrategy; import org.jclouds.compute.strategy.GetNodeMetadataStrategy; import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap; import org.jclouds.compute.strategy.ListNodesStrategy; @@ -65,23 +69,26 @@ import com.google.common.base.Supplier; public class GoGridComputeService extends BaseComputeService { @Inject protected GoGridComputeService(ComputeServiceContext context, Map credentialStore, - @Memoized Supplier> images, @Memoized Supplier> hardwareProfiles, - @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, - GetNodeMetadataStrategy getNodeMetadataStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, - RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, - ResumeNodeStrategy resumeNodeStrategy, SuspendNodeStrategy suspendNodeStrategy, - Provider templateBuilderProvider, Provider templateOptionsProvider, - @Named("NODE_RUNNING") Predicate> nodeRunning, - @Named("NODE_TERMINATED") Predicate> nodeTerminated, - @Named("NODE_SUSPENDED") Predicate> nodeSuspended, - InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, - RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, - @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, Optional imageExtension) { - super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getNodeMetadataStrategy, - runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, resumeNodeStrategy, - suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, - nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, timeouts, - executor, imageExtension); + @Memoized Supplier> images, + @Memoized Supplier> hardwareProfiles, + @Memoized Supplier> locations, ListNodesStrategy listNodesStrategy, + GetImageStrategy getImageStrategy, GetNodeMetadataStrategy getNodeMetadataStrategy, + CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, + DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy resumeNodeStrategy, + SuspendNodeStrategy suspendNodeStrategy, Provider templateBuilderProvider, + Provider templateOptionsProvider, + @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, + @Named(TIMEOUT_NODE_TERMINATED) Predicate> nodeTerminated, + @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, + RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials, + Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, + Optional imageExtension) { + super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getImageStrategy, + getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, + resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, + nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, + persistNodeCredentials, timeouts, executor, imageExtension); } /** diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/GoGridComputeServiceAdapter.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/GoGridComputeServiceAdapter.java index 17624ff252..cda9ba5ffc 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/GoGridComputeServiceAdapter.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/strategy/GoGridComputeServiceAdapter.java @@ -21,7 +21,6 @@ package org.jclouds.gogrid.compute.strategy; import static com.google.common.base.Preconditions.checkNotNull; import java.security.SecureRandom; -import java.util.NoSuchElementException; import java.util.Set; import javax.annotation.Resource; @@ -143,13 +142,16 @@ public class GoGridComputeServiceAdapter implements ComputeServiceAdapter defineAddNodeWithTagStrategy() { - return RimuHostingCreateNodeWithGroupEncodedIntoName.class; - } - - @Override - protected Class defineDestroyNodeStrategy() { - return RimuHostingDestroyNodeStrategy.class; - } - - @Override - protected Class defineGetNodeMetadataStrategy() { - return RimuHostingGetNodeMetadataStrategy.class; - } - - @Override - protected Class defineListNodesStrategy() { - return RimuHostingListNodesStrategy.class; - } - - @Override - protected Class defineRebootNodeStrategy() { - return RimuHostingLifeCycleStrategy.class; - } - - @Override - protected Class defineStartNodeStrategy() { - return RimuHostingLifeCycleStrategy.class; - } - - @Override - protected Class defineStopNodeStrategy() { - return RimuHostingLifeCycleStrategy.class; - } -} \ No newline at end of file diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingBindComputeSuppliersByClass.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingBindComputeSuppliersByClass.java deleted file mode 100644 index bdb9a62efa..0000000000 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingBindComputeSuppliersByClass.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.rimuhosting.miro.compute.config; - -import java.util.Set; - -import org.jclouds.compute.config.BindComputeSuppliersByClass; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.Image; -import org.jclouds.rimuhosting.miro.compute.suppliers.RimuHostingHardwareSupplier; -import org.jclouds.rimuhosting.miro.compute.suppliers.RimuHostingImageSupplier; - -import com.google.common.base.Supplier; - -public class RimuHostingBindComputeSuppliersByClass extends BindComputeSuppliersByClass { - - @Override - protected Class>> defineHardwareSupplier() { - return RimuHostingHardwareSupplier.class; - } - - @Override - protected Class>> defineImageSupplier() { - return RimuHostingImageSupplier.class; - } -} \ No newline at end of file diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceContextModule.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceContextModule.java index 905ac27c50..db0b91e344 100755 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceContextModule.java +++ b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceContextModule.java @@ -18,22 +18,90 @@ */ package org.jclouds.rimuhosting.miro.compute.config; -import org.jclouds.compute.config.BaseComputeServiceContextModule; +import java.util.Map; + +import javax.inject.Singleton; + +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.config.ComputeServiceAdapterContextModule; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadata.Status; +import org.jclouds.compute.internal.BaseComputeService; +import org.jclouds.domain.Location; +import org.jclouds.functions.IdentityFunction; +import org.jclouds.rimuhosting.miro.compute.functions.RimuHostingImageToImage; +import org.jclouds.rimuhosting.miro.compute.functions.ServerToNodeMetadata; +import org.jclouds.rimuhosting.miro.compute.strategy.RimuHostingComputeServiceAdapter; +import org.jclouds.rimuhosting.miro.domain.Server; +import org.jclouds.rimuhosting.miro.domain.internal.RunningState; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.inject.Provides; +import com.google.inject.TypeLiteral; /** - * Configures the {@link RimuHostingComputeServiceContext}; requires - * {@link RimuHostingComputeService} bound. + * Configures the {@link RimuHostingComputeServiceContext}; requires {@link BaseComputeService} + * bound. * * @author Adrian Cole */ -public class RimuHostingComputeServiceContextModule extends BaseComputeServiceContextModule { +public class RimuHostingComputeServiceContextModule extends + ComputeServiceAdapterContextModule { + @SuppressWarnings("unchecked") @Override protected void configure() { - install(new RimuHostingComputeServiceDependenciesModule()); - install(new RimuHostingBindComputeStrategiesByClass()); - install(new RimuHostingBindComputeSuppliersByClass()); super.configure(); + bind( + new TypeLiteral>() { + }).to(RimuHostingComputeServiceAdapter.class); + + bind(new TypeLiteral>() { + }).to(ServerToNodeMetadata.class); + bind(new TypeLiteral>>() { + }).to(ServerToPublicAddresses.class); + + bind(new TypeLiteral>() { + }).to(RimuHostingImageToImage.class); + + bind(new TypeLiteral>() { + }).to((Class) IdentityFunction.class); + + // we aren't converting location from a provider-specific type + bind(new TypeLiteral>() { + }).to((Class) IdentityFunction.class); + + } + + @VisibleForTesting + static final Map runningStateToNodeStatus = ImmutableMap. builder().put( + RunningState.RUNNING, Status.RUNNING)// + .put(RunningState.NOTRUNNING, Status.SUSPENDED)// + .put(RunningState.POWERCYCLING, Status.PENDING)// + .put(RunningState.RESTARTING, Status.PENDING)// + .put(RunningState.UNRECOGNIZED, Status.UNRECOGNIZED)// + .build(); + + @Singleton + @Provides + Map provideServerToNodeStatus() { + return runningStateToNodeStatus; + } + + @Singleton + private static class ServerToPublicAddresses implements Function> { + @Override + public Iterable apply(Server server) { + return server.getIpAddresses() == null ? ImmutableSet. of() : Iterables.concat(ImmutableList.of(server + .getIpAddresses().getPrimaryIp()), server.getIpAddresses().getSecondaryIps()); + } } } diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceDependenciesModule.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceDependenciesModule.java deleted file mode 100644 index 5e47072577..0000000000 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/config/RimuHostingComputeServiceDependenciesModule.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.rimuhosting.miro.compute.config; - -import java.util.Map; - -import javax.inject.Singleton; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.NodeMetadata.Status; -import org.jclouds.rimuhosting.miro.compute.functions.ServerToNodeMetadata; -import org.jclouds.rimuhosting.miro.domain.Server; -import org.jclouds.rimuhosting.miro.domain.internal.RunningState; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.inject.AbstractModule; -import com.google.inject.Provides; -import com.google.inject.TypeLiteral; - -/** - * Configures the {@link RimuHostingComputeServiceContext}; requires - * {@link RimuHostingComputeService} bound. - * - * @author Adrian Cole - */ -public class RimuHostingComputeServiceDependenciesModule extends AbstractModule { - - @Override - protected void configure() { - bind(new TypeLiteral>() { - }).to(ServerToNodeMetadata.class); - bind(new TypeLiteral>>() { - }).to(ServerToPublicAddresses.class); - } - - @VisibleForTesting - static final Map runningStateToNodeStatus = ImmutableMap. builder() - .put(RunningState.RUNNING, Status.RUNNING)// - .put(RunningState.NOTRUNNING, Status.SUSPENDED)// - .put(RunningState.POWERCYCLING, Status.PENDING)// - .put(RunningState.RESTARTING, Status.PENDING)// - .put(RunningState.UNRECOGNIZED, Status.UNRECOGNIZED)// - .build(); - - @Singleton - @Provides - Map provideServerToNodeStatus() { - return runningStateToNodeStatus; - } - - @Singleton - private static class ServerToPublicAddresses implements Function> { - @Override - public Iterable apply(Server server) { - return server.getIpAddresses() == null ? ImmutableSet. of() : Iterables.concat(ImmutableList.of(server - .getIpAddresses().getPrimaryIp()), server.getIpAddresses().getSecondaryIps()); - } - } -} diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/suppliers/RimuHostingImageSupplier.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/functions/RimuHostingImageToImage.java similarity index 66% rename from providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/suppliers/RimuHostingImageSupplier.java rename to providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/functions/RimuHostingImageToImage.java index 0af668e5b3..10325167de 100644 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/suppliers/RimuHostingImageSupplier.java +++ b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/functions/RimuHostingImageToImage.java @@ -16,14 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.jclouds.rimuhosting.miro.compute.suppliers; +package org.jclouds.rimuhosting.miro.compute.functions; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.Resource; -import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; @@ -34,46 +32,31 @@ import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Image.Status; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.logging.Logger; -import org.jclouds.rimuhosting.miro.RimuHostingClient; -import com.google.common.base.Supplier; -import com.google.common.collect.Sets; +import com.google.common.base.Function; /** * * @author Adrian Cole */ @Singleton -public class RimuHostingImageSupplier implements Supplier> { - public static final Pattern RIMU_PATTERN = Pattern.compile("([a-zA-Z]+) ?([0-9.]+) .*"); - private final RimuHostingClient sync; - - @Inject - RimuHostingImageSupplier(RimuHostingClient sync) { - this.sync = sync; - } - +public class RimuHostingImageToImage implements Function { @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; + private Logger logger = Logger.NULL; - @Override - public Set get() { - final Set images = Sets.newHashSet(); - logger.debug(">> providing images"); - for (org.jclouds.rimuhosting.miro.domain.Image from : sync.getImageList()) { - ImageBuilder builder = new ImageBuilder(); - builder.ids(from.getId() + ""); - builder.name(from.getDescription()); - builder.description(from.getDescription()); - builder.operatingSystem(parseOs(from)); - builder.status(Status.AVAILABLE); - images.add(builder.build()); - } - logger.debug("<< images(%d)", images.size()); - return images; + public Image apply(org.jclouds.rimuhosting.miro.domain.Image from) { + ImageBuilder builder = new ImageBuilder(); + builder.ids(from.getId() + ""); + builder.name(from.getDescription()); + builder.description(from.getDescription()); + builder.operatingSystem(parseOs(from)); + builder.status(Status.AVAILABLE); + return builder.build(); } + public static final Pattern RIMU_PATTERN = Pattern.compile("([a-zA-Z]+) ?([0-9.]+) .*"); + protected OperatingSystem parseOs(final org.jclouds.rimuhosting.miro.domain.Image from) { OsFamily osFamily = null; String osName = from.getId(); diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingComputeServiceAdapter.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingComputeServiceAdapter.java new file mode 100644 index 0000000000..a74ce81ea2 --- /dev/null +++ b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingComputeServiceAdapter.java @@ -0,0 +1,172 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.rimuhosting.miro.compute.strategy; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.collect.Memoized; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.Volume; +import org.jclouds.compute.domain.internal.VolumeImpl; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.Location; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.logging.Logger; +import org.jclouds.rimuhosting.miro.RimuHostingClient; +import org.jclouds.rimuhosting.miro.domain.Image; +import org.jclouds.rimuhosting.miro.domain.NewServerResponse; +import org.jclouds.rimuhosting.miro.domain.PricingPlan; +import org.jclouds.rimuhosting.miro.domain.Server; +import org.jclouds.util.Iterables2; + +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Sets; + +/** + * defines the connection between the {@link RimuHostingClient} implementation and the jclouds + * {@link ComputeService} + * + */ +@Singleton +public class RimuHostingComputeServiceAdapter implements ComputeServiceAdapter { + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + private Logger logger = Logger.NULL; + + private final RimuHostingClient client; + private final Supplier> locations; + + @Inject + protected RimuHostingComputeServiceAdapter(RimuHostingClient client, + @Memoized Supplier> locations) { + this.client = checkNotNull(client, "client"); + this.locations = checkNotNull(locations, "locations"); + } + + @Override + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, + Template template) { + NewServerResponse server = client.createServer(name, + checkNotNull(template.getImage().getProviderId(), "imageId"), checkNotNull(template.getHardware() + .getProviderId(), "hardwareId")); + + return new NodeAndInitialCredentials(server.getServer(), server.getServer().getId() + "", + LoginCredentials.builder().password(server.getNewInstanceRequest().getCreateOptions().getPassword()) + .build()); + } + + @Override + public Iterable listHardwareProfiles() { + final Set sizes = Sets.newHashSet(); + for (final PricingPlan from : client.getPricingPlanList()) { + try { + + final Location location = Iterables.find(locations.get(), new Predicate() { + + @Override + public boolean apply(Location input) { + return input.getId().equals(from.getDataCenter().getId()); + } + + }); + sizes.add(new HardwareBuilder().ids(from.getId()).location(location).processors( + ImmutableList.of(new Processor(1, 1.0))).ram(from.getRam()).volumes( + ImmutableList. of(new VolumeImpl((float) from.getDiskSize(), true, true))).build()); + } catch (NullPointerException e) { + logger.warn("datacenter not present in " + from.getId()); + } + } + return sizes; + } + + @Override + public Iterable listImages() { + return Iterables2.concreteCopy(client.getImageList()); + } + + @Override + public Iterable listNodes() { + return Iterables2.concreteCopy(client.getServerList()); + } + + @Override + public Iterable listLocations() { + // Not using the adapter to determine locations + return ImmutableSet. of(); + } + + @Override + public Server getNode(String id) { + long serverId = Long.parseLong(id); + return client.getServer(serverId); + } + + // cheat until we have a getImage command + @Override + public Image getImage(final String id) { + return Iterables.find(listImages(), new Predicate() { + + @Override + public boolean apply(Image input) { + return input.getId().equals(id); + } + + }, null); + } + + @Override + public void destroyNode(String id) { + Long serverId = Long.parseLong(id); + client.destroyServer(serverId); + } + + @Override + public void rebootNode(String id) { + Long serverId = Long.parseLong(id); + // if false server wasn't around in the first place + client.restartServer(serverId).getState(); + } + + @Override + public void resumeNode(String id) { + throw new UnsupportedOperationException("suspend not supported"); + } + + @Override + public void suspendNode(String id) { + throw new UnsupportedOperationException("suspend not supported"); + } + +} \ No newline at end of file diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingCreateNodeWithGroupEncodedIntoName.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingCreateNodeWithGroupEncodedIntoName.java deleted file mode 100644 index b5ab1043a1..0000000000 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingCreateNodeWithGroupEncodedIntoName.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.rimuhosting.miro.compute.strategy; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName; -import org.jclouds.domain.Credentials; -import org.jclouds.rimuhosting.miro.RimuHostingClient; -import org.jclouds.rimuhosting.miro.domain.NewServerResponse; -import org.jclouds.rimuhosting.miro.domain.Server; - -import com.google.common.base.Function; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class RimuHostingCreateNodeWithGroupEncodedIntoName implements CreateNodeWithGroupEncodedIntoName { - protected final RimuHostingClient client; - protected final Map credentialStore; - protected final Function serverToNodeMetadata; - - @Inject - protected RimuHostingCreateNodeWithGroupEncodedIntoName(RimuHostingClient client, Map credentialStore, - Function serverToNodeMetadata) { - this.client = client; - this.credentialStore = credentialStore; - this.serverToNodeMetadata = serverToNodeMetadata; - } - - @Override - public NodeMetadata createNodeWithGroupEncodedIntoName(String group, String name, Template template) { - NewServerResponse serverResponse = client.createServer(name, checkNotNull(template.getImage().getProviderId(), - "imageId"), checkNotNull(template.getHardware().getProviderId(), "hardwareId")); - Server from = client.getServer(serverResponse.getServer().getId()); - credentialStore.put("node#" + from.getId(), new Credentials("root", serverResponse.getNewInstanceRequest() - .getCreateOptions().getPassword())); - return serverToNodeMetadata.apply(from); - } - -} \ No newline at end of file diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingDestroyNodeStrategy.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingDestroyNodeStrategy.java deleted file mode 100644 index 2d7ccfe822..0000000000 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingDestroyNodeStrategy.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.rimuhosting.miro.compute.strategy; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.strategy.DestroyNodeStrategy; -import org.jclouds.compute.strategy.GetNodeMetadataStrategy; -import org.jclouds.rimuhosting.miro.RimuHostingClient; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class RimuHostingDestroyNodeStrategy implements DestroyNodeStrategy { - private final RimuHostingClient client; - private final GetNodeMetadataStrategy getNode; - - @Inject - protected RimuHostingDestroyNodeStrategy(RimuHostingClient client, GetNodeMetadataStrategy getNode) { - this.client = client; - this.getNode = getNode; - } - - @Override - public NodeMetadata destroyNode(String id) { - Long serverId = Long.parseLong(id); - client.destroyServer(serverId); - return getNode.getNode(id); - } - -} \ No newline at end of file diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingLifeCycleStrategy.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingLifeCycleStrategy.java deleted file mode 100644 index cdc3a052d1..0000000000 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingLifeCycleStrategy.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.rimuhosting.miro.compute.strategy; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.strategy.GetNodeMetadataStrategy; -import org.jclouds.compute.strategy.RebootNodeStrategy; -import org.jclouds.compute.strategy.ResumeNodeStrategy; -import org.jclouds.compute.strategy.SuspendNodeStrategy; -import org.jclouds.rimuhosting.miro.RimuHostingClient; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class RimuHostingLifeCycleStrategy implements RebootNodeStrategy, SuspendNodeStrategy, ResumeNodeStrategy { - private final RimuHostingClient client; - private final GetNodeMetadataStrategy getNode; - - @Inject - protected RimuHostingLifeCycleStrategy(RimuHostingClient client, GetNodeMetadataStrategy getNode) { - this.client = client; - this.getNode = getNode; - } - - @Override - public NodeMetadata rebootNode(String id) { - Long serverId = Long.parseLong(id); - // if false server wasn't around in the first place - client.restartServer(serverId).getState(); - return getNode.getNode(id); - } - - @Override - public NodeMetadata suspendNode(String id) { - throw new UnsupportedOperationException("suspend not supported"); - } - - @Override - public NodeMetadata resumeNode(String id) { - throw new UnsupportedOperationException("resume not supported"); - } - -} \ No newline at end of file diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingListNodesStrategy.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingListNodesStrategy.java deleted file mode 100644 index c16e07af4e..0000000000 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/strategy/RimuHostingListNodesStrategy.java +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.rimuhosting.miro.compute.strategy; - -import javax.inject.Inject; -import javax.inject.Singleton; - -import org.jclouds.compute.domain.ComputeMetadata; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.predicates.NodePredicates; -import org.jclouds.compute.strategy.ListNodesStrategy; -import org.jclouds.rimuhosting.miro.RimuHostingClient; -import org.jclouds.rimuhosting.miro.domain.Server; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class RimuHostingListNodesStrategy implements ListNodesStrategy { - private final RimuHostingClient client; - private final Function serverToNodeMetadata; - - @Inject - protected RimuHostingListNodesStrategy(RimuHostingClient client, - Function serverToNodeMetadata) { - this.client = client; - this.serverToNodeMetadata = serverToNodeMetadata; - } - - @Override - public Iterable listNodes() { - return listDetailsOnNodesMatching(NodePredicates.all()); - } - - @Override - public Iterable listDetailsOnNodesMatching(Predicate filter) { - return Iterables.filter(Iterables.transform(client.getServerList(), serverToNodeMetadata), filter); - } - -} \ No newline at end of file diff --git a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/suppliers/RimuHostingHardwareSupplier.java b/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/suppliers/RimuHostingHardwareSupplier.java deleted file mode 100644 index b435ee960b..0000000000 --- a/providers/rimuhosting/src/main/java/org/jclouds/rimuhosting/miro/compute/suppliers/RimuHostingHardwareSupplier.java +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.rimuhosting.miro.compute.suppliers; - -import java.util.Set; - -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.collect.Memoized; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.HardwareBuilder; -import org.jclouds.compute.domain.Processor; -import org.jclouds.compute.domain.Volume; -import org.jclouds.compute.domain.internal.VolumeImpl; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.domain.Location; -import org.jclouds.logging.Logger; -import org.jclouds.rimuhosting.miro.RimuHostingClient; -import org.jclouds.rimuhosting.miro.domain.PricingPlan; - -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Sets; - -/** - * - * @author Adrian Cole - */ -@Singleton -public class RimuHostingHardwareSupplier implements Supplier> { - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final RimuHostingClient sync; - private final Supplier> locations; - - @Inject - RimuHostingHardwareSupplier(RimuHostingClient sync, @Memoized Supplier> locations) { - this.sync = sync; - this.locations = locations; - } - - @Override - public Set get() { - final Set sizes = Sets.newHashSet(); - logger.debug(">> providing sizes"); - for (final PricingPlan from : sync.getPricingPlanList()) { - try { - - final Location location = Iterables.find(locations.get(), new Predicate() { - - @Override - public boolean apply(Location input) { - return input.getId().equals(from.getDataCenter().getId()); - } - - }); - sizes.add(new HardwareBuilder().ids(from.getId()).location(location).processors( - ImmutableList.of(new Processor(1, 1.0))).ram(from.getRam()).volumes( - ImmutableList. of(new VolumeImpl((float) from.getDiskSize(), true, true))).build()); - } catch (NullPointerException e) { - logger.warn("datacenter not present in " + from.getId()); - } - } - logger.debug("<< sizes(%d)", sizes.size()); - return sizes; - } -} \ No newline at end of file diff --git a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java index e83b28ba70..8b74c1ec26 100644 --- a/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java +++ b/providers/slicehost/src/main/java/org/jclouds/slicehost/compute/strategy/SlicehostComputeServiceAdapter.java @@ -64,7 +64,6 @@ public class SlicehostComputeServiceAdapter implements ComputeServiceAdapter listHardwareProfiles() { return client.listFlavors(); - } @Override @@ -88,7 +87,13 @@ public class SlicehostComputeServiceAdapter implements ComputeServiceAdapter listImages() { return filter(productPackageSupplier.get().getItems(), categoryCode("os")); } + + // cheat until we have a getProductItem command + @Override + public ProductItem getImage(final String id) { + return Iterables.find(listImages(), new Predicate(){ + @Override + public boolean apply(ProductItem input) { + return ProductItemToImage.imageId().apply(input).equals(id); + } + + }, null); + } + @Override public Iterable listNodes() { return Iterables.filter(client.getVirtualGuestClient().listVirtualGuests(), new Predicate() { diff --git a/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java b/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java index 9e5b0b619e..aeeb00c1de 100644 --- a/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java +++ b/skeletons/standalone-compute/src/main/java/org/jclouds/servermanager/compute/strategy/ServerManagerComputeServiceAdapter.java @@ -69,6 +69,12 @@ public class ServerManagerComputeServiceAdapter implements ComputeServiceAdapter return client.listImages(); } + @Override + public Image getImage(String id) { + int imageId = Integer.parseInt(id); + return client.getImage(imageId); + } + @Override public Iterable listNodes() { return client.listServers();