From fa3c226a868463acd1299ed0a03b3d23dfd5a5a6 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 4 Apr 2011 02:24:46 -0700 Subject: [PATCH] added computeservice to delta --- ...CloudServersUSTemplateBuilderLiveTest.java | 19 -- sandbox-apis/deltacloud/pom.xml | 9 +- .../deltacloud/DeltacloudAsyncClient.java | 12 +- .../jclouds/deltacloud/DeltacloudClient.java | 12 +- .../deltacloud/DeltacloudContextBuilder.java | 11 +- .../DeltacloudPropertiesBuilder.java | 2 + ...DeltacloudComputeServiceContextModule.java | 71 +++++++ .../functions/DeltacloudImageToImage.java | 52 ++++++ .../DeltacloudImageToOperatingSystem.java | 90 +++++++++ .../functions/HardwareProfileToHardware.java | 61 ++++++ .../functions/InstanceToNodeMetadata.java | 166 +++++++++++++++++ .../compute/functions/RealmToLocation.java | 62 +++++++ .../DeltacloudComputeServiceAdapter.java | 175 ++++++++++++++++++ .../options/CreateInstanceOptions.java | 33 ++++ .../deltacloud/DeltacloudClientLiveTest.java | 2 +- .../ReadOnlyDeltacloudClientLiveTest.java | 6 +- .../DeltacloudComputeServiceLiveTest.java | 88 +++++++++ .../DeltacloudTemplateBuilderLiveTest.java | 83 +++++++++ 18 files changed, 915 insertions(+), 39 deletions(-) create mode 100644 sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/config/DeltacloudComputeServiceContextModule.java create mode 100644 sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToImage.java create mode 100644 sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToOperatingSystem.java create mode 100644 sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/HardwareProfileToHardware.java create mode 100644 sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/InstanceToNodeMetadata.java create mode 100644 sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/RealmToLocation.java create mode 100644 sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java create mode 100644 sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudComputeServiceLiveTest.java create mode 100644 sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java diff --git a/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java b/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java index 79662b2f66..337dd15933 100644 --- a/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java +++ b/providers/cloudservers-us/src/test/java/org/jclouds/rackspace/cloudservers/compute/CloudServersUSTemplateBuilderLiveTest.java @@ -1,22 +1,3 @@ -/** - * - * Copyright (C) 2010 Cloud Conscious, LLC. - * - * ==================================================================== - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ==================================================================== - */ - package org.jclouds.rackspace.cloudservers.compute; import static org.jclouds.compute.util.ComputeServiceUtils.getCores; diff --git a/sandbox-apis/deltacloud/pom.xml b/sandbox-apis/deltacloud/pom.xml index 11679ed9e6..033ad23fa0 100644 --- a/sandbox-apis/deltacloud/pom.xml +++ b/sandbox-apis/deltacloud/pom.xml @@ -58,7 +58,7 @@ org.jclouds - jclouds-core + jclouds-compute ${project.version} @@ -68,6 +68,13 @@ test-jar test + + org.jclouds + jclouds-compute + ${project.version} + test-jar + test + org.jclouds.driver jclouds-jsch diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java index 36f99ab9e4..83b2e197ca 100644 --- a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudAsyncClient.java @@ -84,7 +84,7 @@ public interface DeltacloudAsyncClient { @GET @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @XMLResponseParser(DeltacloudCollectionsHandler.class) - ListenableFuture> getCollections(); + ListenableFuture> getCollections(); /** * @see DeltacloudClient#getInstanceStates @@ -93,7 +93,7 @@ public interface DeltacloudAsyncClient { @Endpoint(InstanceStates.class) @ExceptionParser(ReturnEmptyMultimapOnNotFoundOr404.class) @XMLResponseParser(InstanceStatesHandler.class) - ListenableFuture> getInstanceStates(); + ListenableFuture> getInstanceStates(); /** * @see DeltacloudClient#listRealms @@ -102,7 +102,7 @@ public interface DeltacloudAsyncClient { @Endpoint(Realms.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @XMLResponseParser(RealmsHandler.class) - ListenableFuture> listRealms(); + ListenableFuture> listRealms(); /** * @see DeltacloudClient#getRealm @@ -119,7 +119,7 @@ public interface DeltacloudAsyncClient { @Endpoint(Images.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @XMLResponseParser(ImagesHandler.class) - ListenableFuture> listImages(); + ListenableFuture> listImages(); /** * @see DeltacloudClient#getImage @@ -136,7 +136,7 @@ public interface DeltacloudAsyncClient { @Endpoint(HardwareProfiles.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @XMLResponseParser(HardwareProfilesHandler.class) - ListenableFuture> listHardwareProfiles(); + ListenableFuture> listHardwareProfiles(); /** * @see DeltacloudClient#getHardwareProfile @@ -153,7 +153,7 @@ public interface DeltacloudAsyncClient { @Endpoint(Instances.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @XMLResponseParser(InstancesHandler.class) - ListenableFuture> listInstances(); + ListenableFuture> listInstances(); /** * @see DeltacloudClient#getInstance diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java index 0ad720ec60..57f68b6462 100644 --- a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudClient.java @@ -52,20 +52,20 @@ public interface DeltacloudClient { * * @return named links to available collections, or empty set, if no collections are found */ - Set getCollections(); + Set getCollections(); /** * * @return The possible states of an instance, and how to traverse between them */ - Multimap getInstanceStates(); + Multimap getInstanceStates(); /** * The realms collection will return a set of all realms available to the current user. * * @return realms viewable to the user or empty set */ - Set listRealms(); + Set listRealms(); /** * @@ -79,7 +79,7 @@ public interface DeltacloudClient { * * @return images viewable to the user or empty set */ - Set listImages(); + Set listImages(); /** * @@ -94,7 +94,7 @@ public interface DeltacloudClient { * * @return hardware profiles viewable to the user or empty set */ - Set listHardwareProfiles(); + Set listHardwareProfiles(); /** * @@ -108,7 +108,7 @@ public interface DeltacloudClient { * * @return instances viewable to the user or empty set */ - Set listInstances(); + Set listInstances(); /** * diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudContextBuilder.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudContextBuilder.java index 7704c625e1..c21aed59b6 100644 --- a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudContextBuilder.java +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudContextBuilder.java @@ -22,8 +22,9 @@ package org.jclouds.deltacloud; import java.util.List; import java.util.Properties; +import org.jclouds.compute.ComputeServiceContextBuilder; +import org.jclouds.deltacloud.compute.config.DeltacloudComputeServiceContextModule; import org.jclouds.deltacloud.config.DeltacloudRestClientModule; -import org.jclouds.rest.RestContextBuilder; import com.google.inject.Module; @@ -31,13 +32,17 @@ import com.google.inject.Module; * * @author Adrian Cole */ -public class DeltacloudContextBuilder extends - RestContextBuilder { +public class DeltacloudContextBuilder extends ComputeServiceContextBuilder { public DeltacloudContextBuilder(Properties props) { super(DeltacloudClient.class, DeltacloudAsyncClient.class, props); } + @Override + protected void addContextModule(List modules) { + modules.add(new DeltacloudComputeServiceContextModule()); + } + protected void addClientModule(List modules) { modules.add(new DeltacloudRestClientModule()); } diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudPropertiesBuilder.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudPropertiesBuilder.java index 129c1cac12..0be8050eaf 100644 --- a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudPropertiesBuilder.java +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/DeltacloudPropertiesBuilder.java @@ -20,6 +20,7 @@ package org.jclouds.deltacloud; import static org.jclouds.Constants.PROPERTY_API_VERSION; +import static org.jclouds.Constants.PROPERTY_ENDPOINT; import java.util.Properties; @@ -35,6 +36,7 @@ public class DeltacloudPropertiesBuilder extends PropertiesBuilder { protected Properties defaultProperties() { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_API_VERSION, "0.3.0"); + properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:3001/api"); return properties; } diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/config/DeltacloudComputeServiceContextModule.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/config/DeltacloudComputeServiceContextModule.java new file mode 100644 index 0000000000..ca696e3f81 --- /dev/null +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/config/DeltacloudComputeServiceContextModule.java @@ -0,0 +1,71 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute.config; + +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.config.ComputeServiceAdapterContextModule; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.deltacloud.DeltacloudAsyncClient; +import org.jclouds.deltacloud.DeltacloudClient; +import org.jclouds.deltacloud.compute.functions.DeltacloudImageToImage; +import org.jclouds.deltacloud.compute.functions.HardwareProfileToHardware; +import org.jclouds.deltacloud.compute.functions.InstanceToNodeMetadata; +import org.jclouds.deltacloud.compute.functions.RealmToLocation; +import org.jclouds.deltacloud.compute.strategy.DeltacloudComputeServiceAdapter; +import org.jclouds.deltacloud.domain.HardwareProfile; +import org.jclouds.deltacloud.domain.Instance; +import org.jclouds.deltacloud.domain.Realm; +import org.jclouds.domain.Location; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +public class DeltacloudComputeServiceContextModule + extends + ComputeServiceAdapterContextModule { + + public DeltacloudComputeServiceContextModule() { + super(DeltacloudClient.class, DeltacloudAsyncClient.class); + } + + @Override + protected void configure() { + super.configure(); + bind( + new TypeLiteral>() { + }).to(DeltacloudComputeServiceAdapter.class); + bind(new TypeLiteral>() { + }).to(InstanceToNodeMetadata.class); + bind(new TypeLiteral>() { + }).to(DeltacloudImageToImage.class); + bind(new TypeLiteral>() { + }).to(HardwareProfileToHardware.class); + bind(new TypeLiteral>() { + }).to(RealmToLocation.class); + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZone.class); + } +} diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToImage.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToImage.java new file mode 100644 index 0000000000..edd28bcb1a --- /dev/null +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToImage.java @@ -0,0 +1,52 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute.functions; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.ImageBuilder; + +import com.google.common.base.Function; + +/** + * @author Adrian Cole + */ +@Singleton +public class DeltacloudImageToImage implements Function { + private final DeltacloudImageToOperatingSystem imageToOperatingSystem; + + @Inject + public DeltacloudImageToImage(DeltacloudImageToOperatingSystem imageToOperatingSystem) { + this.imageToOperatingSystem = imageToOperatingSystem; + } + + @Override + public Image apply(org.jclouds.deltacloud.domain.Image from) { + ImageBuilder builder = new ImageBuilder(); + builder.ids(from.getId()); + builder.uri(from.getHref()); + builder.name(from.getName()); + builder.description(from.getDescription()); + builder.operatingSystem(imageToOperatingSystem.apply(from)); + return builder.build(); + } +} diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToOperatingSystem.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToOperatingSystem.java new file mode 100644 index 0000000000..4270a055db --- /dev/null +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/DeltacloudImageToOperatingSystem.java @@ -0,0 +1,90 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute.functions; + +import java.util.Map; +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; + +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.compute.util.ComputeServiceUtils; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; + +/** + * @author Adrian Cole + */ +@Singleton +public class DeltacloudImageToOperatingSystem implements Function { + public static final Pattern DEFAULT_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)"); + // Windows Server 2008 R2 x64 + public static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows (.*) (x[86][64])"); + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final Map> osVersionMap; + + @Inject + public DeltacloudImageToOperatingSystem(Map> osVersionMap) { + this.osVersionMap = osVersionMap; + } + + public OperatingSystem apply(org.jclouds.deltacloud.domain.Image from) { + OsFamily osFamily = null; + String osName = null; + String osArch = null; + String osVersion = null; + String osDescription = from.getName(); + boolean is64Bit = true; + if (from.getName().indexOf("Red Hat EL") != -1) { + osFamily = OsFamily.RHEL; + } else if (from.getName().indexOf("Oracle EL") != -1) { + osFamily = OsFamily.OEL; + } else if (from.getName().indexOf("Windows") != -1) { + osFamily = OsFamily.WINDOWS; + Matcher matcher = WINDOWS_PATTERN.matcher(from.getName()); + if (matcher.find()) { + osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(1), osVersionMap); + is64Bit = matcher.group(2).equals("x64"); + } + } else { + Matcher matcher = DEFAULT_PATTERN.matcher(from.getName()); + if (matcher.find()) { + try { + osFamily = OsFamily.fromValue(matcher.group(2).toLowerCase()); + } catch (IllegalArgumentException e) { + logger.debug("<< didn't match os(%s)", matcher.group(2)); + } + osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(3), osVersionMap); + } + } + return new OperatingSystem(osFamily, osName, osVersion, osArch, osDescription, is64Bit); + } +} \ No newline at end of file diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/HardwareProfileToHardware.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/HardwareProfileToHardware.java new file mode 100644 index 0000000000..992dbf5505 --- /dev/null +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/HardwareProfileToHardware.java @@ -0,0 +1,61 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute.functions; + +import javax.inject.Singleton; + +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.VolumeBuilder; +import org.jclouds.deltacloud.domain.HardwareProfile; +import org.jclouds.deltacloud.domain.HardwareProperty; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; + +/** + * @author Adrian Cole + */ +@Singleton +public class HardwareProfileToHardware implements Function { + + @Override + public Hardware apply(HardwareProfile from) { + HardwareBuilder builder = new HardwareBuilder(); + builder.ids(from.getId()); + builder.name(from.getName()); + builder.uri(from.getHref()); + + for (HardwareProperty property : from.getProperties()) { + if (property.getName().equals("memory")) { + builder.ram(Integer.parseInt(property.getValue().toString())); + } else if (property.getName().equals("storage")) { + Float gigs = new Float(property.getValue().toString()); + builder.processors(ImmutableList.of(new Processor(gigs / 10.0, 1.0))); + builder.volume(new VolumeBuilder().type(Volume.Type.LOCAL).device("/").size(gigs).bootDevice(true).durable( + true).build()); + } + } + + return builder.build(); + } +} diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/InstanceToNodeMetadata.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/InstanceToNodeMetadata.java new file mode 100644 index 0000000000..efa3e4c9fc --- /dev/null +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/InstanceToNodeMetadata.java @@ -0,0 +1,166 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; + +import java.util.Map; +import java.util.NoSuchElementException; +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.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadataBuilder; +import org.jclouds.compute.domain.NodeState; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.deltacloud.domain.Instance; +import org.jclouds.domain.Credentials; +import org.jclouds.domain.Location; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; + +/** + * @author Adrian Cole + */ +@Singleton +public class InstanceToNodeMetadata implements Function { + + public static final Map instanceToNodeState = ImmutableMap + . builder().put(Instance.State.STOPPED, NodeState.SUSPENDED).put( + Instance.State.RUNNING, NodeState.RUNNING).put(Instance.State.PENDING, NodeState.PENDING).put( + Instance.State.UNRECOGNIZED, NodeState.UNRECOGNIZED).put(Instance.State.SHUTTING_DOWN, + NodeState.PENDING).put(Instance.State.START, NodeState.PENDING).build(); + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + protected final Map credentialStore; + protected final Supplier> locations; + protected final Supplier> images; + protected final Supplier> hardwares; + + private static class FindImageForInstance implements Predicate { + private final Instance instance; + + private FindImageForInstance(Instance instance) { + this.instance = instance; + } + + @Override + public boolean apply(Image input) { + return input.getUri().equals(instance.getImage()); + } + } + + private static class FindHardwareForInstance implements Predicate { + private final Instance instance; + + private FindHardwareForInstance(Instance instance) { + this.instance = instance; + } + + @Override + public boolean apply(Hardware input) { + return input.getUri().equals(instance.getHardwareProfile()); + } + } + + protected Hardware parseHardware(Instance from) { + try { + return Iterables.find(hardwares.get(), new FindHardwareForInstance(from)); + } catch (NoSuchElementException e) { + logger.warn("could not find a matching hardware for instance %s", from); + } + return null; + } + + protected OperatingSystem parseOperatingSystem(Instance from) { + try { + return Iterables.find(images.get(), new FindImageForInstance(from)).getOperatingSystem(); + } catch (NoSuchElementException e) { + logger.warn("could not find a matching image for instance %s", from); + } + return null; + } + + private static class FindLocationForInstance implements Predicate { + private final Instance instance; + + private FindLocationForInstance(Instance instance) { + this.instance = instance; + } + + @Override + public boolean apply(Location input) { + return input.getId().equals(instance.getRealm().toASCIIString()); + } + } + + protected Location parseLocation(Instance from) { + try { + return Iterables.find(locations.get(), new FindLocationForInstance(from)); + } catch (NoSuchElementException e) { + logger.warn("could not find a matching realm for instance %s", from); + } + return null; + } + + @Inject + InstanceToNodeMetadata(Map credentialStore, + @Memoized Supplier> locations, @Memoized Supplier> images, + @Memoized Supplier> hardwares) { + this.credentialStore = checkNotNull(credentialStore, "credentialStore"); + this.images = checkNotNull(images, "images"); + this.locations = checkNotNull(locations, "locations"); + this.hardwares = checkNotNull(hardwares, "hardwares"); + } + + @Override + public NodeMetadata apply(org.jclouds.deltacloud.domain.Instance from) { + NodeMetadataBuilder builder = new NodeMetadataBuilder(); + builder.ids(from.getHref().toASCIIString()); + builder.name(from.getName()); + builder.location(parseLocation(from)); + builder.group(parseGroupFromName(from.getName())); + builder.imageId(from.getImage().toASCIIString()); + builder.operatingSystem(parseOperatingSystem(from)); + builder.hardware(parseHardware(from)); + builder.state(instanceToNodeState.get(from.getState())); + builder.publicAddresses(from.getPublicAddresses()); + builder.privateAddresses(from.getPrivateAddresses()); + builder.credentials(credentialStore.get(from.getHref().toASCIIString())); + return builder.build(); + } +} diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/RealmToLocation.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/RealmToLocation.java new file mode 100644 index 0000000000..55685fde2b --- /dev/null +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/functions/RealmToLocation.java @@ -0,0 +1,62 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.deltacloud.domain.Realm; +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.location.Iso3166; +import org.jclouds.location.Provider; + +import com.google.common.base.Function; + +/** + * @author Adrian Cole + */ +@Singleton +public class RealmToLocation implements Function { + + private final String providerName; + private final URI endpoint; + private final Set isoCodes; + + @Inject + public RealmToLocation(@Iso3166 Set isoCodes, @Provider String providerName, @Provider URI endpoint) { + this.providerName = checkNotNull(providerName, "providerName"); + this.endpoint = checkNotNull(endpoint, "endpoint"); + this.isoCodes = checkNotNull(isoCodes, "isoCodes"); + } + + @Override + public Location apply(Realm from) { + return new LocationBuilder().scope(LocationScope.ZONE).id(from.getHref().toASCIIString()).description(from.getName()).parent( + new LocationBuilder().scope(LocationScope.PROVIDER).iso3166Codes(isoCodes).id(providerName).description( + endpoint.toASCIIString()).parent(null).build()).build(); + } +} diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java new file mode 100644 index 0000000000..b03a7612b5 --- /dev/null +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/compute/strategy/DeltacloudComputeServiceAdapter.java @@ -0,0 +1,175 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute.strategy; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.net.URI; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.deltacloud.DeltacloudClient; +import org.jclouds.deltacloud.domain.HardwareProfile; +import org.jclouds.deltacloud.domain.Instance; +import org.jclouds.deltacloud.domain.PasswordAuthentication; +import org.jclouds.deltacloud.domain.Realm; +import org.jclouds.deltacloud.domain.Transition; +import org.jclouds.deltacloud.domain.TransitionOnAction; +import org.jclouds.deltacloud.domain.Instance.State; +import org.jclouds.deltacloud.options.CreateInstanceOptions; +import org.jclouds.deltacloud.predicates.InstanceFinished; +import org.jclouds.deltacloud.predicates.InstanceRunning; +import org.jclouds.domain.Credentials; +import org.jclouds.http.HttpRequest; +import org.jclouds.logging.Logger; +import org.jclouds.predicates.RetryablePredicate; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; +import com.google.common.collect.Multimap; + +/** + * defines the connection between the {@link DeltacloudClient} implementation and the jclouds + * {@link ComputeService} + * + */ +@Singleton +public class DeltacloudComputeServiceAdapter implements + ComputeServiceAdapter { + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final org.jclouds.deltacloud.DeltacloudClient client; + private final ImmutableMap> stateChanges; + + @Inject + public DeltacloudComputeServiceAdapter(DeltacloudClient client) { + this.client = checkNotNull(client, "client"); + // TODO: parameterize + stateChanges = ImmutableMap.> of(// + Instance.State.RUNNING, new RetryablePredicate(new InstanceRunning(client), 600, 1, + TimeUnit.SECONDS),// + Instance.State.FINISH, new RetryablePredicate(new InstanceFinished(client), 30, 1, + TimeUnit.SECONDS)// + ); + } + + @Override + public Instance createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template, + Map credentialStore) { + Instance instance = client.createInstance(template.getImage().getId(), CreateInstanceOptions.Builder.named(name) + .hardwareProfile(template.getHardware().getId()).realm(template.getLocation().getId())); + if (instance.getAuthentication() != null && instance.getAuthentication() instanceof PasswordAuthentication) { + Credentials creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials(); + // store the credentials so that later functions can use them + credentialStore.put(instance.getHref().toASCIIString(), creds); + } + return instance; + } + + @Override + public Iterable listHardwareProfiles() { + return client.listHardwareProfiles(); + } + + @Override + public Iterable listImages() { + return client.listImages(); + } + + @Override + public Iterable listNodes() { + return client.listInstances(); + } + + @Override + public Iterable listLocations() { + return client.listRealms(); + } + + @Override + public org.jclouds.deltacloud.domain.Instance getNode(String id) { + return client.getInstance(URI.create(checkNotNull(id, "id"))); + } + + @Override + public void destroyNode(String id) { + Instance instance = getNode(id); + for (Transition transition : findChainTo(Instance.State.FINISH, instance.getState(), client.getInstanceStates())) { + instance = getNode(id); + if (instance == null) + break; + if (transition instanceof TransitionOnAction) { + client.performAction(instance.getActions().get(TransitionOnAction.class.cast(transition).getAction())); + } + Predicate stateTester = stateChanges.get(transition.getTo()); + if (stateTester != null) + stateTester.apply(instance); + else + logger.debug(String.format("no state tester for: %s", transition)); + } + } + + Iterable findChainTo(Instance.State desired, Instance.State currentState, + Multimap states) { + for (Transition transition : states.get(currentState)) { + if (currentState.ordinal() >= transition.getTo().ordinal()) + continue; + if (transition.getTo() == desired) + return ImmutableSet. of(transition); + Iterable transitions = findChainTo(desired, transition.getTo(), states); + if (Iterables.size(transitions) > 0) + return Iterables.concat(ImmutableSet.of(transition), transitions); + } + return ImmutableSet. of(); + } + + @Override + public void rebootNode(String id) { + HttpRequest rebootUri = getNode(id).getActions().get(Instance.Action.REBOOT); + if (rebootUri != null) { + client.performAction(rebootUri); + } else { + throw new UnsupportedOperationException(); + } + } + + @Override + public void resumeNode(String id) { + throw new UnsupportedOperationException(); + } + + @Override + public void suspendNode(String id) { + throw new UnsupportedOperationException(); + } +} \ No newline at end of file diff --git a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/options/CreateInstanceOptions.java b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/options/CreateInstanceOptions.java index 25a1a92eb8..5b0f00f251 100644 --- a/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/options/CreateInstanceOptions.java +++ b/sandbox-apis/deltacloud/src/main/java/org/jclouds/deltacloud/options/CreateInstanceOptions.java @@ -32,6 +32,23 @@ public class CreateInstanceOptions extends BaseHttpRequestOptions { return this; } + /** + * The realm in which to launch the instance + * + */ + public CreateInstanceOptions realm(String realmId) { + formParameters.put("realm_id", checkNotNull(realmId, "realmId")); + return this; + } + + /** + * The hardware profile upon which to launch the instance + */ + public CreateInstanceOptions hardwareProfile(String hwpName) { + formParameters.put("hwp_name", checkNotNull(hwpName, "hwpName")); + return this; + } + public String getName() { return this.getFirstFormOrNull("name"); } @@ -46,5 +63,21 @@ public class CreateInstanceOptions extends BaseHttpRequestOptions { return options.named(name); } + /** + * @see CreateInstanceOptions#realm + */ + public static CreateInstanceOptions realm(String realmId) { + CreateInstanceOptions options = new CreateInstanceOptions(); + return options.realm(realmId); + } + + /** + * @see CreateInstanceOptions#hardwareProfile + */ + public static CreateInstanceOptions hardwareProfile(String hwpName) { + CreateInstanceOptions options = new CreateInstanceOptions(); + return options.hardwareProfile(hwpName); + } + } } diff --git a/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudClientLiveTest.java b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudClientLiveTest.java index 508867b742..6e5a35ebfa 100644 --- a/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudClientLiveTest.java +++ b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/DeltacloudClientLiveTest.java @@ -64,7 +64,7 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest { return input.getDescription().toLowerCase().indexOf("fedora") != -1; } - }).getId(), CreateInstanceOptions.Builder.named(prefix)); + }).getId(), CreateInstanceOptions.Builder.named(prefix).hardwareProfile("1").realm("us")); if (instance.getAuthentication() != null && instance.getAuthentication() instanceof PasswordAuthentication) creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials(); refreshInstance(); diff --git a/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java index ac85bd2c50..02a8e3bb69 100644 --- a/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java +++ b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/ReadOnlyDeltacloudClientLiveTest.java @@ -28,6 +28,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import org.jclouds.Constants; +import org.jclouds.compute.ComputeServiceContextFactory; import org.jclouds.deltacloud.domain.DeltacloudCollection; import org.jclouds.deltacloud.domain.HardwareProfile; import org.jclouds.deltacloud.domain.Image; @@ -42,7 +43,6 @@ import org.jclouds.net.IPSocket; import org.jclouds.predicates.InetSocketAddressConnect; import org.jclouds.predicates.RetryablePredicate; import org.jclouds.rest.RestContext; -import org.jclouds.rest.RestContextFactory; import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; @@ -99,8 +99,8 @@ public class ReadOnlyDeltacloudClientLiveTest { public void setupClient() { setupCredentials(); Properties overrides = setupProperties(); - context = new RestContextFactory().createContext(provider, ImmutableSet. of(new Log4JLoggingModule()), - overrides); + context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet. of(new Log4JLoggingModule()), + overrides).getProviderSpecificContext(); client = context.getApi(); socketTester = new RetryablePredicate(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS); diff --git a/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudComputeServiceLiveTest.java b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudComputeServiceLiveTest.java new file mode 100644 index 0000000000..822318cb6e --- /dev/null +++ b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudComputeServiceLiveTest.java @@ -0,0 +1,88 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute; + +import static org.testng.Assert.assertEquals; + +import java.io.IOException; + +import org.jclouds.compute.BaseComputeServiceLiveTest; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.deltacloud.DeltacloudAsyncClient; +import org.jclouds.deltacloud.DeltacloudClient; +import org.jclouds.domain.LocationScope; +import org.jclouds.rest.RestContext; +import org.jclouds.ssh.jsch.config.JschSshClientModule; +import org.testng.annotations.Test; + +/** + * + * + * @author Adrian Cole + */ +@Test(groups = "live", enabled = true, sequential = true) +public class DeltacloudComputeServiceLiveTest extends BaseComputeServiceLiveTest { + public DeltacloudComputeServiceLiveTest() { + provider = "deltacloud"; + } + + @Override + protected JschSshClientModule getSshModule() { + return new JschSshClientModule(); + } + + public void testAssignability() throws Exception { + @SuppressWarnings("unused") + RestContext tmContext = new ComputeServiceContextFactory() + .createContext(provider, identity, credential).getProviderSpecificContext(); + } + + @Override + protected void checkNodes(Iterable nodes, String tag) throws IOException { + super.checkNodes(nodes, tag); + for (NodeMetadata node : nodes) { + assertEquals(node.getLocation().getScope(), LocationScope.HOST); + } + } + + @Test(enabled = true, dependsOnMethods = "testReboot", expectedExceptions = UnsupportedOperationException.class) + public void testSuspendResume() throws Exception { + super.testSuspendResume(); + } + + @Test(enabled = true, dependsOnMethods = "testSuspendResume") + @Override + public void testGetNodesWithDetails() throws Exception { + super.testGetNodesWithDetails(); + } + + @Test(enabled = true, dependsOnMethods = "testSuspendResume") + @Override + public void testListNodes() throws Exception { + super.testListNodes(); + } + + @Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" }) + @Override + public void testDestroyNodes() { + super.testDestroyNodes(); + } +} diff --git a/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java new file mode 100644 index 0000000000..a6e4b76805 --- /dev/null +++ b/sandbox-apis/deltacloud/src/test/java/org/jclouds/deltacloud/compute/DeltacloudTemplateBuilderLiveTest.java @@ -0,0 +1,83 @@ +/** + * + * Copyright (C) 2010 Cloud Conscious, LLC. + * + * ==================================================================== + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +package org.jclouds.deltacloud.compute; + +import static org.jclouds.compute.util.ComputeServiceUtils.getCores; +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.jclouds.compute.BaseTemplateBuilderLiveTest; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.OsFamilyVersion64Bit; +import org.jclouds.compute.domain.Template; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live") +public class DeltacloudTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { + + public DeltacloudTemplateBuilderLiveTest() { + provider = "deltacloud"; + } + + @Override + protected Predicate defineUnsupportedOperatingSystems() { + return new Predicate() { + + @Override + public boolean apply(OsFamilyVersion64Bit input) { + switch (input.family) { + case UBUNTU: + return input.version.equals("11.04") || input.version.equals("8.04") || !input.is64Bit; + case CENTOS: + return input.version.matches("5.[023]") || !input.is64Bit; + case WINDOWS: + return input.version.equals("2008") || input.version.indexOf("2003") != -1 + || (input.version.equals("2008 R2") && !input.is64Bit); + default: + return true; + } + } + + }; + } + + @Test + public void testTemplateBuilder() { + Template defaultTemplate = this.context.getComputeService().templateBuilder().build(); + assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); + assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "10.04"); + assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); + assertEquals(defaultTemplate.getLocation().getId(), "us"); + assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); + } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of(); + } +}