added computeservice to delta

This commit is contained in:
Adrian Cole 2011-04-04 02:24:46 -07:00
parent 1a51fbc8ad
commit fa3c226a86
18 changed files with 915 additions and 39 deletions

View File

@ -1,22 +1,3 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rackspace.cloudservers.compute; package org.jclouds.rackspace.cloudservers.compute;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.jclouds.compute.util.ComputeServiceUtils.getCores;

View File

@ -58,7 +58,7 @@
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>org.jclouds</groupId> <groupId>org.jclouds</groupId>
<artifactId>jclouds-core</artifactId> <artifactId>jclouds-compute</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
@ -68,6 +68,13 @@
<type>test-jar</type> <type>test-jar</type>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.jclouds</groupId>
<artifactId>jclouds-compute</artifactId>
<version>${project.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.jclouds.driver</groupId> <groupId>org.jclouds.driver</groupId>
<artifactId>jclouds-jsch</artifactId> <artifactId>jclouds-jsch</artifactId>

View File

@ -84,7 +84,7 @@ public interface DeltacloudAsyncClient {
@GET @GET
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@XMLResponseParser(DeltacloudCollectionsHandler.class) @XMLResponseParser(DeltacloudCollectionsHandler.class)
ListenableFuture<? extends Set<? extends DeltacloudCollection>> getCollections(); ListenableFuture<Set<DeltacloudCollection>> getCollections();
/** /**
* @see DeltacloudClient#getInstanceStates * @see DeltacloudClient#getInstanceStates
@ -93,7 +93,7 @@ public interface DeltacloudAsyncClient {
@Endpoint(InstanceStates.class) @Endpoint(InstanceStates.class)
@ExceptionParser(ReturnEmptyMultimapOnNotFoundOr404.class) @ExceptionParser(ReturnEmptyMultimapOnNotFoundOr404.class)
@XMLResponseParser(InstanceStatesHandler.class) @XMLResponseParser(InstanceStatesHandler.class)
ListenableFuture<? extends Multimap<State, ? extends Transition>> getInstanceStates(); ListenableFuture<Multimap<State, Transition>> getInstanceStates();
/** /**
* @see DeltacloudClient#listRealms * @see DeltacloudClient#listRealms
@ -102,7 +102,7 @@ public interface DeltacloudAsyncClient {
@Endpoint(Realms.class) @Endpoint(Realms.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@XMLResponseParser(RealmsHandler.class) @XMLResponseParser(RealmsHandler.class)
ListenableFuture<? extends Set<? extends Realm>> listRealms(); ListenableFuture<Set<Realm>> listRealms();
/** /**
* @see DeltacloudClient#getRealm * @see DeltacloudClient#getRealm
@ -119,7 +119,7 @@ public interface DeltacloudAsyncClient {
@Endpoint(Images.class) @Endpoint(Images.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@XMLResponseParser(ImagesHandler.class) @XMLResponseParser(ImagesHandler.class)
ListenableFuture<? extends Set<? extends Image>> listImages(); ListenableFuture<Set<Image>> listImages();
/** /**
* @see DeltacloudClient#getImage * @see DeltacloudClient#getImage
@ -136,7 +136,7 @@ public interface DeltacloudAsyncClient {
@Endpoint(HardwareProfiles.class) @Endpoint(HardwareProfiles.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@XMLResponseParser(HardwareProfilesHandler.class) @XMLResponseParser(HardwareProfilesHandler.class)
ListenableFuture<? extends Set<? extends HardwareProfile>> listHardwareProfiles(); ListenableFuture<Set<HardwareProfile>> listHardwareProfiles();
/** /**
* @see DeltacloudClient#getHardwareProfile * @see DeltacloudClient#getHardwareProfile
@ -153,7 +153,7 @@ public interface DeltacloudAsyncClient {
@Endpoint(Instances.class) @Endpoint(Instances.class)
@ExceptionParser(ReturnEmptySetOnNotFoundOr404.class) @ExceptionParser(ReturnEmptySetOnNotFoundOr404.class)
@XMLResponseParser(InstancesHandler.class) @XMLResponseParser(InstancesHandler.class)
ListenableFuture<? extends Set<? extends Instance>> listInstances(); ListenableFuture<Set<Instance>> listInstances();
/** /**
* @see DeltacloudClient#getInstance * @see DeltacloudClient#getInstance

View File

@ -52,20 +52,20 @@ public interface DeltacloudClient {
* *
* @return named links to available collections, or empty set, if no collections are found * @return named links to available collections, or empty set, if no collections are found
*/ */
Set<? extends DeltacloudCollection> getCollections(); Set<DeltacloudCollection> getCollections();
/** /**
* *
* @return The possible states of an instance, and how to traverse between them * @return The possible states of an instance, and how to traverse between them
*/ */
Multimap<State, ? extends Transition> getInstanceStates(); Multimap<State, Transition> getInstanceStates();
/** /**
* The realms collection will return a set of all realms available to the current user. * The realms collection will return a set of all realms available to the current user.
* *
* @return realms viewable to the user or empty set * @return realms viewable to the user or empty set
*/ */
Set<? extends Realm> listRealms(); Set<Realm> listRealms();
/** /**
* *
@ -79,7 +79,7 @@ public interface DeltacloudClient {
* *
* @return images viewable to the user or empty set * @return images viewable to the user or empty set
*/ */
Set<? extends Image> listImages(); Set<Image> listImages();
/** /**
* *
@ -94,7 +94,7 @@ public interface DeltacloudClient {
* *
* @return hardware profiles viewable to the user or empty set * @return hardware profiles viewable to the user or empty set
*/ */
Set<? extends HardwareProfile> listHardwareProfiles(); Set<HardwareProfile> listHardwareProfiles();
/** /**
* *
@ -108,7 +108,7 @@ public interface DeltacloudClient {
* *
* @return instances viewable to the user or empty set * @return instances viewable to the user or empty set
*/ */
Set<? extends Instance> listInstances(); Set<Instance> listInstances();
/** /**
* *

View File

@ -22,8 +22,9 @@ package org.jclouds.deltacloud;
import java.util.List; import java.util.List;
import java.util.Properties; 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.deltacloud.config.DeltacloudRestClientModule;
import org.jclouds.rest.RestContextBuilder;
import com.google.inject.Module; import com.google.inject.Module;
@ -31,13 +32,17 @@ import com.google.inject.Module;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
public class DeltacloudContextBuilder extends public class DeltacloudContextBuilder extends ComputeServiceContextBuilder<DeltacloudClient, DeltacloudAsyncClient> {
RestContextBuilder<DeltacloudClient, DeltacloudAsyncClient> {
public DeltacloudContextBuilder(Properties props) { public DeltacloudContextBuilder(Properties props) {
super(DeltacloudClient.class, DeltacloudAsyncClient.class, props); super(DeltacloudClient.class, DeltacloudAsyncClient.class, props);
} }
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new DeltacloudComputeServiceContextModule());
}
protected void addClientModule(List<Module> modules) { protected void addClientModule(List<Module> modules) {
modules.add(new DeltacloudRestClientModule()); modules.add(new DeltacloudRestClientModule());
} }

View File

@ -20,6 +20,7 @@
package org.jclouds.deltacloud; package org.jclouds.deltacloud;
import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_API_VERSION;
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
import java.util.Properties; import java.util.Properties;
@ -35,6 +36,7 @@ public class DeltacloudPropertiesBuilder extends PropertiesBuilder {
protected Properties defaultProperties() { protected Properties defaultProperties() {
Properties properties = super.defaultProperties(); Properties properties = super.defaultProperties();
properties.setProperty(PROPERTY_API_VERSION, "0.3.0"); properties.setProperty(PROPERTY_API_VERSION, "0.3.0");
properties.setProperty(PROPERTY_ENDPOINT, "http://localhost:3001/api");
return properties; return properties;
} }

View File

@ -0,0 +1,71 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<DeltacloudClient, DeltacloudAsyncClient, Instance, HardwareProfile, org.jclouds.deltacloud.domain.Image, Realm> {
public DeltacloudComputeServiceContextModule() {
super(DeltacloudClient.class, DeltacloudAsyncClient.class);
}
@Override
protected void configure() {
super.configure();
bind(
new TypeLiteral<ComputeServiceAdapter<Instance, HardwareProfile, org.jclouds.deltacloud.domain.Image, Realm>>() {
}).to(DeltacloudComputeServiceAdapter.class);
bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {
}).to(InstanceToNodeMetadata.class);
bind(new TypeLiteral<Function<org.jclouds.deltacloud.domain.Image, org.jclouds.compute.domain.Image>>() {
}).to(DeltacloudImageToImage.class);
bind(new TypeLiteral<Function<HardwareProfile, org.jclouds.compute.domain.Hardware>>() {
}).to(HardwareProfileToHardware.class);
bind(new TypeLiteral<Function<Realm, Location>>() {
}).to(RealmToLocation.class);
bind(new TypeLiteral<Supplier<Location>>() {
}).to(OnlyLocationOrFirstZone.class);
}
}

View File

@ -0,0 +1,52 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<org.jclouds.deltacloud.domain.Image, Image> {
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();
}
}

View File

@ -0,0 +1,90 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<org.jclouds.deltacloud.domain.Image, OperatingSystem> {
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<OsFamily, Map<String, String>> osVersionMap;
@Inject
public DeltacloudImageToOperatingSystem(Map<OsFamily, Map<String, String>> 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);
}
}

View File

@ -0,0 +1,61 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<HardwareProfile, Hardware> {
@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();
}
}

View File

@ -0,0 +1,166 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Instance, NodeMetadata> {
public static final Map<Instance.State, NodeState> instanceToNodeState = ImmutableMap
.<Instance.State, NodeState> 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<String, Credentials> credentialStore;
protected final Supplier<Set<? extends Location>> locations;
protected final Supplier<Set<? extends Image>> images;
protected final Supplier<Set<? extends Hardware>> hardwares;
private static class FindImageForInstance implements Predicate<Image> {
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<Hardware> {
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<Location> {
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<String, Credentials> credentialStore,
@Memoized Supplier<Set<? extends Location>> locations, @Memoized Supplier<Set<? extends Image>> images,
@Memoized Supplier<Set<? extends Hardware>> 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();
}
}

View File

@ -0,0 +1,62 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Realm, Location> {
private final String providerName;
private final URI endpoint;
private final Set<String> isoCodes;
@Inject
public RealmToLocation(@Iso3166 Set<String> 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();
}
}

View File

@ -0,0 +1,175 @@
/**
*
* Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<Instance, HardwareProfile, org.jclouds.deltacloud.domain.Image, Realm> {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final org.jclouds.deltacloud.DeltacloudClient client;
private final ImmutableMap<State, Predicate<Instance>> stateChanges;
@Inject
public DeltacloudComputeServiceAdapter(DeltacloudClient client) {
this.client = checkNotNull(client, "client");
// TODO: parameterize
stateChanges = ImmutableMap.<Instance.State, Predicate<Instance>> of(//
Instance.State.RUNNING, new RetryablePredicate<Instance>(new InstanceRunning(client), 600, 1,
TimeUnit.SECONDS),//
Instance.State.FINISH, new RetryablePredicate<Instance>(new InstanceFinished(client), 30, 1,
TimeUnit.SECONDS)//
);
}
@Override
public Instance createNodeWithGroupEncodedIntoNameThenStoreCredentials(String tag, String name, Template template,
Map<String, Credentials> 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<HardwareProfile> listHardwareProfiles() {
return client.listHardwareProfiles();
}
@Override
public Iterable<org.jclouds.deltacloud.domain.Image> listImages() {
return client.listImages();
}
@Override
public Iterable<Instance> listNodes() {
return client.listInstances();
}
@Override
public Iterable<Realm> 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<Instance> stateTester = stateChanges.get(transition.getTo());
if (stateTester != null)
stateTester.apply(instance);
else
logger.debug(String.format("no state tester for: %s", transition));
}
}
Iterable<Transition> findChainTo(Instance.State desired, Instance.State currentState,
Multimap<Instance.State, ? extends Transition> states) {
for (Transition transition : states.get(currentState)) {
if (currentState.ordinal() >= transition.getTo().ordinal())
continue;
if (transition.getTo() == desired)
return ImmutableSet.<Transition> of(transition);
Iterable<Transition> transitions = findChainTo(desired, transition.getTo(), states);
if (Iterables.size(transitions) > 0)
return Iterables.concat(ImmutableSet.of(transition), transitions);
}
return ImmutableSet.<Transition> 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();
}
}

View File

@ -32,6 +32,23 @@ public class CreateInstanceOptions extends BaseHttpRequestOptions {
return this; 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() { public String getName() {
return this.getFirstFormOrNull("name"); return this.getFirstFormOrNull("name");
} }
@ -46,5 +63,21 @@ public class CreateInstanceOptions extends BaseHttpRequestOptions {
return options.named(name); 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);
}
} }
} }

View File

@ -64,7 +64,7 @@ public class DeltacloudClientLiveTest extends ReadOnlyDeltacloudClientLiveTest {
return input.getDescription().toLowerCase().indexOf("fedora") != -1; 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) if (instance.getAuthentication() != null && instance.getAuthentication() instanceof PasswordAuthentication)
creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials(); creds = PasswordAuthentication.class.cast(instance.getAuthentication()).getLoginCredentials();
refreshInstance(); refreshInstance();

View File

@ -28,6 +28,7 @@ import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.jclouds.Constants; import org.jclouds.Constants;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.deltacloud.domain.DeltacloudCollection; import org.jclouds.deltacloud.domain.DeltacloudCollection;
import org.jclouds.deltacloud.domain.HardwareProfile; import org.jclouds.deltacloud.domain.HardwareProfile;
import org.jclouds.deltacloud.domain.Image; import org.jclouds.deltacloud.domain.Image;
@ -42,7 +43,6 @@ import org.jclouds.net.IPSocket;
import org.jclouds.predicates.InetSocketAddressConnect; import org.jclouds.predicates.InetSocketAddressConnect;
import org.jclouds.predicates.RetryablePredicate; import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.jclouds.rest.RestContextFactory;
import org.testng.annotations.AfterGroups; import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -99,8 +99,8 @@ public class ReadOnlyDeltacloudClientLiveTest {
public void setupClient() { public void setupClient() {
setupCredentials(); setupCredentials();
Properties overrides = setupProperties(); Properties overrides = setupProperties();
context = new RestContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()), context = new ComputeServiceContextFactory().createContext(provider, ImmutableSet.<Module> of(new Log4JLoggingModule()),
overrides); overrides).getProviderSpecificContext();
client = context.getApi(); client = context.getApi();
socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS); socketTester = new RetryablePredicate<IPSocket>(new InetSocketAddressConnect(), 180, 1, TimeUnit.SECONDS);

View File

@ -0,0 +1,88 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<DeltacloudClient, DeltacloudAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext();
}
@Override
protected void checkNodes(Iterable<? extends NodeMetadata> 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();
}
}

View File

@ -0,0 +1,83 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.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<OsFamilyVersion64Bit> defineUnsupportedOperatingSystems() {
return new Predicate<OsFamilyVersion64Bit>() {
@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<String> getIso3166Codes() {
return ImmutableSet.<String> of();
}
}