Issue 130: properly modeled node and templates

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2702 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2010-01-20 11:34:24 +00:00
parent 2c373ed68e
commit 2e213ae223
38 changed files with 1936 additions and 508 deletions

View File

@ -24,7 +24,6 @@ import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyNam
import static org.jclouds.scriptbuilder.domain.Statements.exec;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
@ -32,26 +31,26 @@ import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.aws.AWSResponseException;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.domain.InstanceState;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.aws.ec2.domain.IpProtocol;
import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
@ -62,7 +61,6 @@ import org.jclouds.scriptbuilder.ScriptBuilder;
import org.jclouds.scriptbuilder.domain.OsFamily;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
@ -78,67 +76,40 @@ public class EC2ComputeService implements ComputeService {
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final EC2Client ec2Client;
private final Set<EC2Size> sizes;
private final Provider<Set<EC2Template>> templates;
private final Predicate<RunningInstance> instanceStateRunning;
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
private final Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap;
@Inject
public EC2ComputeService(EC2Client tmClient, Predicate<RunningInstance> instanceStateRunning,
public EC2ComputeService(EC2Client client, Set<EC2Size> sizes,
Provider<Set<EC2Template>> templates,
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
Predicate<RunningInstance> instanceStateRunning,
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
this.ec2Client = tmClient;
this.ec2Client = client;
this.sizes = sizes;
this.templates = templates; // delayed intentionally, as generation is slow
this.imageAmiIdMap = imageAmiIdMap;
this.instanceStateRunning = instanceStateRunning;
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
}
private Map<InstanceType, Map<Image, Map<Region, String>>> imageAmiIdMap = ImmutableMap
.<InstanceType, Map<Image, Map<Region, String>>> of(InstanceType.M1_SMALL,//
ImmutableMap.<Image, Map<Region, String>> builder().put(
Image.UBUNTU_90,
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
Region.EU_WEST_1, "ami-a62a01d2")).put(
Image.RHEL_53,
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
"ami-368b685f")).build(),//
InstanceType.C1_MEDIUM,//
ImmutableMap.<Image, Map<Region, String>> builder().put(
Image.UBUNTU_90,
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
Region.EU_WEST_1, "ami-a62a01d2")).put(
Image.RHEL_53,
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
"ami-368b685f")).build(), //
InstanceType.C1_XLARGE,//
ImmutableMap.<Image, Map<Region, String>> builder().put(
Image.UBUNTU_90,
ImmutableMap.of(Region.DEFAULT, "ami-ab15f6c2", Region.US_EAST_1,
"ami-ab15f6c2", Region.US_WEST_1, "ami-7b3c6d3e",
Region.EU_WEST_1, "ami-9a2a01ee")).build());// todo ami
private Map<Profile, InstanceType> profileInstanceTypeMap = ImmutableMap
.<Profile, InstanceType> builder().put(Profile.SMALLEST, InstanceType.M1_SMALL).put(
Profile.MEDIUM, InstanceType.C1_MEDIUM).put(Profile.FASTEST,
InstanceType.C1_XLARGE).build();
private static Map<InstanceState, NodeState> instanceToNodeState = ImmutableMap
.<InstanceState, NodeState> builder().put(InstanceState.PENDING, NodeState.PENDING)
.put(InstanceState.RUNNING, NodeState.RUNNING).put(InstanceState.SHUTTING_DOWN,
NodeState.PENDING).put(InstanceState.TERMINATED, NodeState.TERMINATED).build();
@Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
Image image) {
Region region = Region.fromValue(location);
public CreateNodeResponse runNode(String name, Template template) {
checkArgument(template instanceof EC2Template,
"unexpected template type. should be EC2Template, was: " + template.getClass());
EC2Template ec2Template = (EC2Template) template;
InstanceType type = checkNotNull(profileInstanceTypeMap.get(profile),
"profile not supported: " + profile);
String ami = checkNotNull(checkNotNull(
checkNotNull(imageAmiIdMap.get(type), "type not supported: " + type).get(image),
"image not supported: " + image).get(region), "region not supported: " + region);
KeyPair keyPair = createKeyPairInRegion(region, name);
KeyPair keyPair = createKeyPairInRegion(ec2Template.getRegion(), name);
String securityGroupName = name;
createSecurityGroupInRegion(region, securityGroupName, 22, 80, 8080, 443);
createSecurityGroupInRegion(ec2Template.getRegion(), securityGroupName, 22, 80, 8080, 443);
String script = new ScriptBuilder() // update and install jdk
.addStatement(exec("apt-get update"))//
@ -149,35 +120,45 @@ public class EC2ComputeService implements ComputeService {
.build(OsFamily.UNIX);
logger.debug(">> running instance region(%s) ami(%s) type(%s) keyPair(%s) securityGroup(%s)",
region, ami, type, keyPair.getKeyName(), securityGroupName);
ec2Template.getRegion(), ec2Template.getImage().getId(), ec2Template.getSize()
.getInstanceType(), keyPair.getKeyName(), securityGroupName);
RunningInstance runningInstance = Iterables.getOnlyElement(ec2Client.getInstanceServices()
.runInstancesInRegion(region, null, ami, 1, 1, withKeyName(keyPair.getKeyName())// key
// I
// created
// above
.asType(type)// instance size
.withSecurityGroup(securityGroupName)// group I created above
.withAdditionalInfo(name)// description
.withUserData(script.getBytes()) // script to run as root
.runInstancesInRegion(ec2Template.getRegion(), null, ec2Template.getImage().getId(),
1, 1, withKeyName(keyPair.getKeyName())// key
.asType(ec2Template.getSize().getInstanceType())// instance size
.withSecurityGroup(securityGroupName)// group I created above
.withAdditionalInfo(name)// description
.withUserData(script.getBytes()) // script to run as root
));
logger.debug("<< started instance(%s)", runningInstance.getId());
instanceStateRunning.apply(runningInstance);
logger.debug("<< running instance(%s)", runningInstance.getId());
// refresh to get IP address
runningInstance = getOnlyRunningInstanceInRegion(region, runningInstance.getId());
runningInstance = getOnlyRunningInstanceInRegion(ec2Template.getRegion(), runningInstance
.getId());
Set<InetAddress> publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet
.<InetAddress> of() : ImmutableSet.<InetAddress> of(runningInstance.getIpAddress());
Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet
.<InetAddress> of()
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
return new CreateNodeResponseImpl(runningInstance.getId(), name, runningInstance.getRegion()
.toString(), null, ImmutableMap.<String, String> of(), instanceToNodeState
.get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22,
LoginType.SSH, new Credentials(image == Image.UBUNTU_90 ? "ubuntu" : "root", keyPair
.getKeyMaterial()), ImmutableMap.<String, String> of());
return new CreateNodeResponseImpl(
runningInstance.getId(),
name,
runningInstance.getRegion().toString(),
null,
ImmutableMap.<String, String> of(),
instanceToNodeState.get(runningInstance.getInstanceState()),
publicAddresses,
privateAddresses,
22,
LoginType.SSH,
new Credentials(
ec2Template.getImage().getOperatingSystem() == OperatingSystem.UBUNTU ? "ubuntu"
: "root", keyPair.getKeyMaterial()), ImmutableMap
.<String, String> of());
}
private KeyPair createKeyPairInRegion(Region region, String name) {
@ -205,13 +186,13 @@ public class EC2ComputeService implements ComputeService {
try {
ec2Client.getSecurityGroupServices().createSecurityGroupInRegion(region, name, name);
logger.debug("<< created securityGroup(%s)", name);
logger.debug(">> authorizing securityGroup region(%s) name(%s) ports(%s)", region, name,
Joiner.on(',').join(Arrays.asList(ports)));
for (int port : ports) {
logger.debug(">> authorizing securityGroup region(%s) name(%s) port(%s)", region, name,
port);
ec2Client.getSecurityGroupServices().authorizeSecurityGroupIngressInRegion(region,
name, IpProtocol.TCP, port, port, "0.0.0.0/0");
logger.debug("<< authorized securityGroup(%s)", name);
}
logger.debug("<< authorized securityGroup(%s)", name);
} catch (AWSResponseException e) {
if (e.getError().getCode().equals("InvalidGroup.Duplicate")) {
logger.debug("<< reused securityGroup(%s)", name);
@ -335,7 +316,17 @@ public class EC2ComputeService implements ComputeService {
}
@Override
public Map<String, Size> getSizes() {
throw new UnsupportedOperationException();
public Set<EC2Size> listSizes() {
return sizes;
}
@Override
public Set<EC2Template> listTemplates() {
return templates.get();
}
@Override
public Template createTemplateInLocation(String location) {
return new EC2Template(ec2Client, imageAmiIdMap, location);
}
}

View File

@ -0,0 +1,88 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute;
import org.jclouds.aws.ec2.domain.InstanceType;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.internal.SizeImpl;
import com.google.common.collect.ImmutableSet;
/**
*
* @author Adrian Cole
*/
public class EC2Size extends SizeImpl {
private final InstanceType instanceType;
EC2Size(InstanceType instanceType, Integer cores, Integer ram, Integer disk,
Iterable<Architecture> supportedArchitectures) {
super(cores, ram, disk, supportedArchitectures);
this.instanceType = instanceType;
}
/**
* Returns the EC2 InstanceType associated with this size.
*/
public InstanceType getInstanceType() {
return instanceType;
}
/**
* @see InstanceType#M1_SMALL
*/
public static final EC2Size M1_SMALL = new EC2Size(InstanceType.M1_SMALL, 1, 1740, 160,
ImmutableSet.of(Architecture.X86_32));
/**
* @see InstanceType#M1_LARGE
*/
public static final EC2Size M1_LARGE = new EC2Size(InstanceType.M1_LARGE, 4, 7680, 850,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#M1_XLARGE
*/
public static final EC2Size M1_XLARGE = new EC2Size(InstanceType.M1_XLARGE, 8, 15360, 1690,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#M2_2XLARGE
*/
public static final EC2Size M2_2XLARGE = new EC2Size(InstanceType.M2_2XLARGE, 13, 35020, 850,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#M2_4XLARGE
*/
public static final EC2Size M2_4XLARGE = new EC2Size(InstanceType.M2_4XLARGE, 26, 70041, 1690,
ImmutableSet.of(Architecture.X86_64));
/**
* @see InstanceType#C1_MEDIUM
*/
public static final EC2Size C1_MEDIUM = new EC2Size(InstanceType.C1_MEDIUM, 5, 1740, 350,
ImmutableSet.of(Architecture.X86_32));
/**
* @see InstanceType#C1_XLARGE
*/
public static final EC2Size C1_XLARGE = new EC2Size(InstanceType.C1_XLARGE, 20, 7168, 1690,
ImmutableSet.of(Architecture.X86_64));
}

View File

@ -0,0 +1,233 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.aws.ec2.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Map;
import javax.annotation.Nullable;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Template;
import com.google.common.annotations.VisibleForTesting;
/**
*
* @author Adrian Cole
*/
public class EC2Template implements Template {
private final EC2Client client;
private final Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap;
private EC2Size size;
private OperatingSystem operatingSystem;
private Region region;
private transient Image image;
public EC2Template(EC2Client client,
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
EC2Size size, OperatingSystem operatingSystem, Region region, @Nullable Image image) {
this.client = client;
this.size = size;
this.operatingSystem = operatingSystem;
this.region = region;
this.imageAmiIdMap = imageAmiIdMap;
this.image = image != null ? image : resolveImage();
}
EC2Template(EC2Client client,
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
String location) {
this(client, imageAmiIdMap, EC2Size.M1_SMALL, OperatingSystem.UBUNTU, Region
.fromValue(location), null);
}
/**
* {@inheritDoc}
*/
@Override
public EC2Size getSize() {
return size;
}
/**
* {@inheritDoc}
*/
@Override
public Image getImage() {
return image;
}
@VisibleForTesting
Image resolveImage() {
Architecture architecture = size.supportsArchitecture(Architecture.X86_64) ? Architecture.X86_64
: Architecture.X86_32;
String ami = checkNotNull(
checkNotNull(
checkNotNull(
imageAmiIdMap.get(architecture),
String.format(
"architecture %s not supported. Valid choices %s: ",
architecture, imageAmiIdMap.keySet())).get(
operatingSystem),
String
.format(
"operatingSystem %s not supported for architecture %s. Valid choices %s: ",
operatingSystem, architecture, imageAmiIdMap.get(
architecture).keySet())).get(region),
String
.format(
"region %s not supported for operatingSystem %s, architecture %s. Valid choices %s: ",
region, operatingSystem, architecture, imageAmiIdMap.get(
architecture).get(operatingSystem).keySet()));
return EC2Utils.newImage(client, region, operatingSystem, architecture, ami);
}
public Template asSize(EC2Size size) {
this.size = size;
this.image = resolveImage();
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template smallest() {
return asSize(EC2Size.M1_SMALL);
}
/**
* {@inheritDoc}
*/
@Override
public Template biggest() {
return asSize(EC2Size.M2_4XLARGE);
}
/**
* {@inheritDoc}
*/
@Override
public Template fastest() {
return asSize(EC2Size.C1_XLARGE);
}
/**
* {@inheritDoc}
*/
@Override
public Template inLocation(String location) {
this.region = Region.fromValue(location);
this.image = resolveImage();
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template os(OperatingSystem os) {
this.operatingSystem = os;
this.image = resolveImage();
return this;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((region == null) ? 0 : region.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EC2Template other = (EC2Template) obj;
if (image == null) {
if (other.image != null)
return false;
} else if (!image.equals(other.image))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (region == null) {
if (other.region != null)
return false;
} else if (!region.equals(other.region))
return false;
if (size == null) {
if (other.size != null)
return false;
} else if (!size.equals(other.size))
return false;
return true;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "EC2Template [image=" + image + ", operatingSystem=" + operatingSystem + ", region="
+ region + ", size=" + size + "]";
}
/**
* {@inheritDoc}
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return new EC2Template(client, imageAmiIdMap, size, operatingSystem, region, image);
}
public Region getRegion() {
return region;
}
}

View File

@ -18,17 +18,33 @@
*/
package org.jclouds.aws.ec2.compute.config;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.EC2ComputeService;
import org.jclouds.aws.ec2.compute.EC2Size;
import org.jclouds.aws.ec2.compute.EC2Template;
import org.jclouds.aws.ec2.config.EC2ContextModule;
import org.jclouds.aws.ec2.util.EC2Utils;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestContext;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Provides;
/**
@ -51,4 +67,63 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
return new ComputeServiceContextImpl<EC2AsyncClient, EC2Client>(computeService, context);
}
@Provides
@Singleton
Set<EC2Size> provideSizes() {
return ImmutableSet.<EC2Size> of(EC2Size.C1_MEDIUM, EC2Size.C1_XLARGE, EC2Size.M1_LARGE,
EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE);
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
@Provides
@Singleton
Set<EC2Template> provideTemplates(EC2Client client, Set<EC2Size> sizes,
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> imageAmiIdMap,
LogHolder holder) {
Set<EC2Template> templates = Sets.newHashSet();
holder.logger.debug(">> generating templates");
for (EC2Size size : sizes) {
for (Architecture architecture : imageAmiIdMap.keySet()) {
if (size.supportsArchitecture(architecture)) {
for (OperatingSystem operatingSystem : imageAmiIdMap.get(architecture).keySet()) {
for (Region region : imageAmiIdMap.get(architecture).get(operatingSystem)
.keySet()) {
String ami = imageAmiIdMap.get(architecture).get(operatingSystem).get(region);
templates.add(new EC2Template(client, imageAmiIdMap, size, operatingSystem,
region, EC2Utils.newImage(client, region, operatingSystem,
architecture, ami)));
}
}
}
}
}
holder.logger.debug("<< templates(%d)", templates.size());
return templates;
}
@Provides
@Singleton
Map<Architecture, Map<OperatingSystem, Map<Region, String>>> provideimageAmiIdMap() {
return ImmutableMap.<Architecture, Map<OperatingSystem, Map<Region, String>>> of(
Architecture.X86_32,//
ImmutableMap.<OperatingSystem, Map<Region, String>> builder().put(
OperatingSystem.UBUNTU,
ImmutableMap.of(Region.DEFAULT, "ami-1515f67c", Region.US_EAST_1,
"ami-1515f67c", Region.US_WEST_1, "ami-7d3c6d38",
Region.EU_WEST_1, "ami-a62a01d2")).put(
OperatingSystem.RHEL,
ImmutableMap.of(Region.DEFAULT, "ami-368b685f", Region.US_EAST_1,
"ami-368b685f")).build(),//
Architecture.X86_64,//
ImmutableMap.<OperatingSystem, Map<Region, String>> builder().put(
OperatingSystem.UBUNTU,
ImmutableMap.of(Region.DEFAULT, "ami-ab15f6c2", Region.US_EAST_1,
"ami-ab15f6c2", Region.US_WEST_1, "ami-7b3c6d3e",
Region.EU_WEST_1, "ami-9a2a01ee")).build());// todo ami
}
}

View File

@ -20,16 +20,31 @@ package org.jclouds.aws.ec2.util;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.aws.ec2.options.DescribeImagesOptions.Builder.imageIds;
import org.jclouds.aws.domain.Region;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.domain.AvailabilityZone;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.rest.internal.GeneratedHttpRequest;
import com.google.inject.internal.Iterables;
/**
*
* @author Adrian Cole
*/
public class EC2Utils {
public static Image newImage(EC2Client client, Region region, OperatingSystem os,
Architecture architecture, String ami) {
org.jclouds.aws.ec2.domain.Image image = Iterables.getOnlyElement(client.getAMIServices()
.describeImagesInRegion(region, imageIds(ami)));
return new ImageImpl(ami, image.getDescription(), os, null, region.toString(), architecture);
}
public static void indexStringArrayToFormValuesWithPrefix(GeneratedHttpRequest<?> request,
String prefix, Object input) {
checkArgument(checkNotNull(input, "input") instanceof String[],

View File

@ -19,6 +19,7 @@
package org.jclouds.aws.ec2.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@ -29,15 +30,16 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
@ -61,31 +63,34 @@ import com.google.inject.Injector;
*/
@Test(groups = "live", enabled = true, sequential = true, testName = "ec2.EC2ComputeServiceLiveTest")
public class EC2ComputeServiceLiveTest {
private static final String service = "ec2";
protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name") + ".ec2serv";
private String nodeName = System.getProperty("user.name") + service;
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node;
private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = new ComputeServiceContextFactory().createContext("ec2", user, password,
context = new ComputeServiceContextFactory().createContext(service, user, password,
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
}
public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
Profile.SMALLEST, Image.UBUNTU_90);
Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest();
node = client.runNode(nodeName, template);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
@ -100,7 +105,7 @@ public class EC2ComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
@ -110,13 +115,27 @@ public class EC2ComputeServiceLiveTest {
}
public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) {
for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null;
assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE);
}
}
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException {
try {
doCheckKey();
@ -150,7 +169,7 @@ public class EC2ComputeServiceLiveTest {
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null)
context.getComputeService().destroyNode(node);
client.destroyNode(node);
context.close();
}

View File

@ -46,6 +46,32 @@
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
@ -72,6 +98,12 @@
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!--======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->

View File

@ -18,15 +18,13 @@
*/
package org.jclouds.compute;
import java.util.Map;
import java.util.Set;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
/**
* Provides portable access to launching compute instances.
@ -35,23 +33,34 @@ import org.jclouds.compute.domain.Size;
* @author Ivan Meredith
*/
public interface ComputeService {
/**
* Creates a new template in the specified location.
*
* @param location
* where the template is valid for
*/
Template createTemplateInLocation(String location);
/**
* List all sizes available to the current user
*/
Map<String, Size> getSizes();
Set<? extends Size> listSizes();
/**
* List all templates available to the current user
*/
Set<? extends Template> listTemplates();
/**
* List all nodes available to the current user
*/
Set<ComputeMetadata> listNodes();
Set<? extends ComputeMetadata> listNodes();
/**
* Create a new node given the name, size, and Image
* Create a new node given the name, and template
*
*/
CreateNodeResponse startNodeInLocation(String location, String name, Profile size, Image image);
CreateNodeResponse runNode(String name, Template template);
/**
* destroy the node.

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@ -23,29 +23,19 @@
*/
package org.jclouds.compute.domain;
import java.util.Map;
/**
* Configured operating system used to start nodes.
* Architecture of a node
*
* @author Adrian Cole
*/
public interface Image {
/**
* Unique ID provided by the provider (ami-abcd1234, etc)
*
*/
String getId();
public enum Architecture {
/**
* Name provided by the provider (Ubuntu 8.1)
*
* 32-bit platform
*/
String getName();
X86_32,
/**
* Other variables present that the provider supports
* 64-bit platform
*/
Map<String, String> getExtra();
X86_64;
}

View File

@ -1,26 +1,63 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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.
* 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.compute.domain;
/**
* Running Operating system
*
* @author Adrian Cole
*/
public enum Image {
CENTOS_53, RHEL_53, UBUNTU_90, UBUNTU_JEOS_90, WEBAPPVM_93
public interface Image {
/**
* Unique ID provided by the provider (ami-abcd1234, etc)
*
*/
String getId();
/**
* Description of the image
*/
String getDescription();
/**
* Operating System
*/
OperatingSystem getOperatingSystem();
/**
* Version of the image
*/
String getVersion();
/**
* Geographic location of the image.
*/
String getLocation();
/**
* Operating System
*/
Architecture getArchitecture();
}

View File

@ -1,6 +1,6 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
@ -24,10 +24,11 @@
package org.jclouds.compute.domain;
/**
* Running Operating system
*
* @author Adrian Cole
*/
public interface Profile {
Image getImage();
public enum OperatingSystem {
Size getSize();
CENTOS, RHEL, UBUNTU, WINDOWS, UNKNOWN;
}

View File

@ -1,40 +1,34 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.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
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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.
* 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.compute.domain;
import java.util.Map;
/**
* Configured operating system used to start nodes.
* Size of a node.
*
* @author Adrian Cole
*/
public interface Size {
/**
* provider-specific identifier (m1.small, etc)
*/
String getId();
/**
* Name provided by the provider (Small CPU, etc)
*/
String getName();
public interface Size extends Comparable<Size> {
/**
* Amount of virtual or physical cores provided
@ -44,26 +38,15 @@ public interface Size {
/**
* Amount of RAM provided in MB (256M, 1740)
*/
Long getRam();
Integer getRam();
/**
* Amount of boot disk provided in GB (200)
*/
Long getDisk();
Integer getDisk();
/**
* Amount of total transfer bandwidth in GB
* Determines platforms this can support
*/
Long getBandwidth();
/**
* Hourly price of this server in USD, estimated if monthly.
*/
Float getPrice();
/**
* Other variables present that the provider supports
*/
Map<String, String> getExtra();
boolean supportsArchitecture(Architecture architecture);
}

View File

@ -19,8 +19,46 @@
package org.jclouds.compute.domain;
/**
* Configured operating system used to start nodes.
*
* @author Adrian Cole
*/
public enum Profile {
SMALLEST, MEDIUM, FASTEST
public interface Template extends Cloneable {
/**
* configure this template to the smallest size.
*/
Template smallest();
/**
* configure this template to the fastest size.
*/
Template fastest();
/**
* configure this template to the largest size.
*/
Template biggest();
/**
* Configure this template to use a specific operating system image.
*/
Template os(OperatingSystem os);
/**
* Configure this template to start in a specific location
*/
Template inLocation(String location);
/**
* Image that suits the requirements.
*
*/
Image getImage();
/**
* Size that suits the requirements.
*/
Size getSize();
}

View File

@ -0,0 +1,171 @@
/**
*
* Copyright (C) 2009 Global Cloud Specialists, Inc. <info@globalcloudspecialists.com>
*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*/
package org.jclouds.compute.domain.internal;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
/**
* @author Adrian Cole
*/
public class ImageImpl implements Image {
private final String id;
private final String description;
private final OperatingSystem operatingSystem;
private final String version;
private final String location;
private final Architecture architecture;
public ImageImpl(String id, String description, OperatingSystem operatingSystem, String version,
String location, Architecture architecture) {
this.id = id;
this.description = description;
this.operatingSystem = operatingSystem;
this.version = version;
this.location = location;
this.architecture = architecture;
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((architecture == null) ? 0 : architecture.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((location == null) ? 0 : location.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((version == null) ? 0 : version.hashCode());
return result;
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ImageImpl other = (ImageImpl) obj;
if (architecture == null) {
if (other.architecture != null)
return false;
} else if (!architecture.equals(other.architecture))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (location == null) {
if (other.location != null)
return false;
} else if (!location.equals(other.location))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (version == null) {
if (other.version != null)
return false;
} else if (!version.equals(other.version))
return false;
return true;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "ImageImpl [architecture=" + architecture + ", description=" + description + ", id="
+ id + ", location=" + location + ", operatingSystem=" + operatingSystem
+ ", version=" + version + "]";
}
/**
* {@inheritDoc}
*/
@Override
public String getId() {
return id;
}
/**
* {@inheritDoc}
*/
@Override
public String getDescription() {
return description;
}
/**
* {@inheritDoc}
*/
@Override
public OperatingSystem getOperatingSystem() {
return operatingSystem;
}
/**
* {@inheritDoc}
*/
@Override
public String getVersion() {
return version;
}
/**
* {@inheritDoc}
*/
@Override
public String getLocation() {
return location;
}
/**
* {@inheritDoc}
*/
@Override
public Architecture getArchitecture() {
return architecture;
}
}

View File

@ -0,0 +1,138 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.compute.domain.internal;
import java.util.Set;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Size;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
*/
public class SizeImpl implements Size {
private final Integer cores;
private final Integer ram;
private final Integer disk;
private final Set<Architecture> supportedArchitectures = Sets.newHashSet();
public SizeImpl(Integer cores, Integer ram, Integer disk,
Iterable<Architecture> supportedArchitectures) {
this.cores = cores;
this.ram = ram;
this.disk = disk;
Iterables.addAll(this.supportedArchitectures, supportedArchitectures);
}
/**
* {@inheritDoc}
*/
@Override
public Integer getCores() {
return cores;
}
/**
* {@inheritDoc}
*/
@Override
public Integer getRam() {
return ram;
}
/**
* {@inheritDoc}
*/
@Override
public Integer getDisk() {
return disk;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cores == null) ? 0 : cores.hashCode());
result = prime * result + ((disk == null) ? 0 : disk.hashCode());
result = prime * result + ((ram == null) ? 0 : ram.hashCode());
result = prime * result
+ ((supportedArchitectures == null) ? 0 : supportedArchitectures.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SizeImpl other = (SizeImpl) obj;
if (cores == null) {
if (other.cores != null)
return false;
} else if (!cores.equals(other.cores))
return false;
if (disk == null) {
if (other.disk != null)
return false;
} else if (!disk.equals(other.disk))
return false;
if (ram == null) {
if (other.ram != null)
return false;
} else if (!ram.equals(other.ram))
return false;
if (supportedArchitectures == null) {
if (other.supportedArchitectures != null)
return false;
} else if (!supportedArchitectures.equals(other.supportedArchitectures))
return false;
return true;
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "SizeImpl [cores=" + cores + ", disk=" + disk + ", ram=" + ram + "]";
}
/**
* {@inheritDoc}
*/
@Override
public int compareTo(Size o) {
return (this == o) ? 0 : getCores().compareTo(o.getCores());
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportsArchitecture(Architecture architecture) {
return supportedArchitectures.contains(architecture);
}
}

View File

@ -28,7 +28,7 @@ import com.google.common.collect.Iterables;
* @author Adrian Cole
*/
public class ComputeUtils {
public static Iterable<ComputeMetadata> filterByName(Iterable<ComputeMetadata> nodes,
public static Iterable<? extends ComputeMetadata> filterByName(Iterable<? extends ComputeMetadata> nodes,
final String name) {
return Iterables.filter(nodes, new Predicate<ComputeMetadata>() {
@Override

View File

@ -35,12 +35,12 @@ import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.ComputeMetadataImpl;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -73,17 +73,18 @@ public class RimuHostingComputeService implements ComputeService {
this.rhClient = rhClient;
}
private Map<Image, String> imageNameMap = ImmutableMap.<Image, String> builder().put(
Image.CENTOS_53, "centos53").put(Image.UBUNTU_90, "ubuntu904").build();
private Map<Profile, String> profileNameMap = ImmutableMap.<Profile, String> builder().put(
Profile.SMALLEST, "MIRO1B").build();
private Map<OperatingSystem, String> imageNameMap = ImmutableMap
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "centos53").put(
OperatingSystem.UBUNTU, "ubuntu904").build();
// private Map<Size, String> profileNameMap = ImmutableMap.<Profile, String> builder().put(
// Profile.SMALLEST, "MIRO1B").build();
@Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
Image image) {
public CreateNodeResponse runNode(String name, Template template) {
NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap
.get(image), "image not supported: " + image), checkNotNull(profileNameMap
.get(profile), "profile not supported: " + profile));
.get(template.getImage().getOperatingSystem()), "os not supported: "
+ template.getImage().getOperatingSystem()), "MIRO1B");
return new CreateNodeResponseImpl(serverResponse.getServer().getId().toString(),
serverResponse.getServer().getName(), "default", null, ImmutableMap
.<String, String> of(),
@ -138,7 +139,17 @@ public class RimuHostingComputeService implements ComputeService {
}
@Override
public Map<String, Size> getSizes() {
public Template createTemplateInLocation(String location) {
return null;
}
@Override
public Set<? extends Size> listSizes() {
return null;
}
@Override
public Set<? extends Template> listTemplates() {
return null;
}
}

View File

@ -19,37 +19,30 @@
package org.jclouds.rimuhosting.miro.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.rimuhosting.miro.data.CreateOptions;
import org.jclouds.rimuhosting.miro.data.NewServerData;
import org.jclouds.rimuhosting.miro.domain.IpAddresses;
import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.ssh.ExecResponse;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
@ -59,7 +52,6 @@ import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -68,29 +60,34 @@ import com.google.inject.Injector;
*/
@Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingNodeServiceLiveTest")
public class RimuHostingComputeServiceLiveTest {
private static final String service = "rimuhosting";
protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name") + ".rimuhosting";
private String nodeName = System.getProperty("user.name") + service;
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node;
private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" })
public void setupClient() throws IOException {
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = new ComputeServiceContextFactory().createContext("rimuhosting", key, key,
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = new ComputeServiceContextFactory().createContext(service, user, password,
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
}
public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
Profile.SMALLEST, Image.CENTOS_53);
Template template = client.createTemplateInLocation("default").os(UBUNTU).smallest();
node = client.runNode(nodeName, template);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
@ -105,7 +102,7 @@ public class RimuHostingComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
@ -115,13 +112,27 @@ public class RimuHostingComputeServiceLiveTest {
}
public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) {
for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null;
assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE);
}
}
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException {
try {
doCheckKey();
@ -155,65 +166,8 @@ public class RimuHostingComputeServiceLiveTest {
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null)
context.getComputeService().destroyNode(node);
client.destroyNode(node);
context.close();
}
public void testParseInetAddress() throws UnknownHostException {
Server rhServer = createMock(Server.class);
IpAddresses addresses = createMock(IpAddresses.class);
expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce();
expect(addresses.getPrimaryIp()).andReturn("127.0.0.1");
expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet.of("www.yahoo.com"));
replay(rhServer);
replay(addresses);
// assertEquals(Sets
// .newLinkedHashSet(RimuHostingCreateNodeResponse.getPublicAddresses(rhServer)),
// ImmutableSet.of(InetAddress.getByName("127.0.0.1"), InetAddress
// .getByName("www.yahoo.com")));
}
@Test(enabled = false)
public void test() throws UnknownHostException {
NewServerResponse nsResponse = createMock(NewServerResponse.class);
Server rhServer = createMock(Server.class);
expect(nsResponse.getServer()).andReturn(rhServer).atLeastOnce();
expect(rhServer.getId()).andReturn(new Long(1));
expect(rhServer.getName()).andReturn("name");
IpAddresses addresses = createMock(IpAddresses.class);
expect(rhServer.getIpAddresses()).andReturn(addresses).atLeastOnce();
expect(addresses.getPrimaryIp()).andReturn("127.0.0.1");
expect(addresses.getSecondaryIps()).andReturn(ImmutableSortedSet.<String> of());
NewServerData data = createMock(NewServerData.class);
expect(nsResponse.getNewInstanceRequest()).andReturn(data).atLeastOnce();
CreateOptions options = createMock(CreateOptions.class);
expect(data.getCreateOptions()).andReturn(options);
expect(options.getPassword()).andReturn("password");
replay(nsResponse);
replay(rhServer);
replay(addresses);
replay(data);
replay(options);
// RimuHostingCreateNodeResponse response = new RimuHostingCreateNodeResponse(nsResponse);
// assertEquals(response.getId(), "1");
// assertEquals(response.getName(), "name");
// assertEquals(response.getPublicAddresses(), ImmutableSet.<InetAddress> of(InetAddress
// .getByName("127.0.0.1")));
// assertEquals(response.getPrivateAddresses(), ImmutableSet.<InetAddress> of());
// assertEquals(response.getLoginPort(), 22);
// assertEquals(response.getLoginType(), LoginType.SSH);
// assertEquals(response.getCredentials(), new Credentials("root", "password"));
}
}

View File

@ -72,7 +72,7 @@
<target name="create" description="create the node ${jclouds.compute.nodename}" depends="destroy" >
<compute action="create" provider="${jclouds.compute.url}">
<node name="${jclouds.compute.nodename}" image="UBUNTU_JEOS_90" profile="SMALLEST"
<node name="${jclouds.compute.nodename}" os="UBUNTU" size="SMALLEST"
hostproperty="host" usernameproperty="username" passwordproperty="password" />
</compute>

View File

@ -94,7 +94,7 @@
<property name="location" value="default" />
<target name="create" description="create the node ${nodename}">
<property name="image" value="UBUNTU_90" />
<property name="os" value="UBUNTU" />
<input
message="What do you want to name your node?"
@ -102,7 +102,7 @@
/>
<compute action="create" provider="${jclouds.compute.url}">
<node name="${nodename}" location="${location}" image="${image}" profile="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
<node name="${nodename}" location="${location}" os="${os}" size="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
</compute>
</target>

View File

@ -35,9 +35,9 @@ import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.util.ComputeUtils;
import org.jclouds.http.HttpUtils;
@ -187,12 +187,21 @@ public class ComputeTask extends Task {
}
private void create(ComputeService computeService) {
log(String.format("create name: %s, profile: %s, image: %s", nodeElement.getName(),
nodeElement.getProfile(), nodeElement.getImage()));
CreateNodeResponse createdNode = computeService.startNodeInLocation(
nodeElement.getLocation(), nodeElement.getName(), Profile.valueOf(nodeElement
.getProfile().toUpperCase()), Image.valueOf(nodeElement.getImage()
.toUpperCase()));
log(String.format("create name: %s, size: %s, os: %s", nodeElement.getName(), nodeElement
.getSize(), nodeElement.getOs()));
Template template = computeService.createTemplateInLocation(nodeElement.getLocation());
template.os(OperatingSystem.valueOf(nodeElement.getOs()));
if (nodeElement.getSize().equalsIgnoreCase("smallest")) {
template.smallest();
} else if (nodeElement.getSize().equalsIgnoreCase("fastest")) {
template.fastest();
} else if (nodeElement.getSize().equalsIgnoreCase("biggest")) {
template.biggest();
} else {
throw new BuildException("size: " + nodeElement.getSize()
+ " not supported. valid sizes are smallest, fastest, biggest");
}
CreateNodeResponse createdNode = computeService.runNode(nodeElement.getName(), template);
log(String.format(" id=%s, name=%s, connection=%s://%s:%s@%s:%d", createdNode.getId(),
createdNode.getName(), createdNode.getLoginType().toString().toLowerCase(),
createdNode.getCredentials().account, createdNode.getCredentials().key, createdNode
@ -221,7 +230,7 @@ public class ComputeTask extends Task {
private void destroy(ComputeService computeService) {
log(String.format("destroy name: %s", nodeElement.getName()));
Iterable<ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
.listNodes(), nodeElement.getName());
for (ComputeMetadata node : nodesThatMatch) {
log(String.format(" destroying id=%s, name=%s", node.getId(), node.getName()));
@ -231,7 +240,7 @@ public class ComputeTask extends Task {
private void get(ComputeService computeService) {
log(String.format("get name: %s", nodeElement.getName()));
Iterable<ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
Iterable<? extends ComputeMetadata> nodesThatMatch = ComputeUtils.filterByName(computeService
.listNodes(), nodeElement.getName());
for (ComputeMetadata node : nodesThatMatch) {
logDetails(computeService, node);

View File

@ -24,8 +24,8 @@ package org.jclouds.tools.ant.taskdefs.compute;
*/
public class NodeElement {
private String name;
private String profile;
private String image;
private String size;
private String os;
private String passwordproperty;
private String keyfi1le;
private String hostproperty;
@ -49,22 +49,6 @@ public class NodeElement {
this.name = name;
}
String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
String getUsernameproperty() {
return usernameproperty;
}
@ -124,4 +108,20 @@ public class NodeElement {
return keyfi1le;
}
public void setSize(String size) {
this.size = size;
}
public String getSize() {
return size;
}
public void setOs(String os) {
this.os = os;
}
public String getOs() {
return os;
}
}

View File

@ -26,7 +26,7 @@ import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
@ -49,17 +49,16 @@ public class VCloudComputeClient {
private final VCloudClient tmClient;
@Inject
public VCloudComputeClient(VCloudClient tmClient,
Predicate<String> successTester) {
public VCloudComputeClient(VCloudClient tmClient, Predicate<String> successTester) {
this.tmClient = tmClient;
this.taskTester = successTester;
}
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put(
Image.CENTOS_53, "1").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put(
Image.UBUNTU_JEOS_90, "11").build();
private Map<OperatingSystem, String> imageCatalogIdMap = ImmutableMap
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "1").put(
OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "11").build();
public Map<String, String> start(String name, Image image, int minCores, int minMegs,
public Map<String, String> start(String name, OperatingSystem image, int minCores, int minMegs,
long diskSize, Map<String, String> properties) {
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
String templateId = imageCatalogIdMap.get(image);
@ -68,9 +67,9 @@ public class VCloudComputeClient {
.debug(
">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ",
vDCId, name, templateId, minCores, minMegs, diskSize, properties);
VApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name,
templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores)
.memory(minMegs).disk(diskSize).productProperties(properties));
VApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name, templateId,
InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory(minMegs)
.disk(diskSize).productProperties(properties));
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
logger.debug(">> deploying vApp(%s)", vAppResponse.getId());
@ -85,7 +84,8 @@ public class VCloudComputeClient {
// "powerOn", VAppStatus.ON);
logger.debug("<< on vApp(%s)", vApp.getId());
return ImmutableMap.<String, String> of("id", vApp.getId(), "username", null, "password", null);
return ImmutableMap.<String, String> of("id", vApp.getId(), "username", null, "password",
null);
}
/**

View File

@ -28,7 +28,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.domain.ResourceType;
@ -59,7 +59,8 @@ public class VCloudComputeClientLiveTest {
private String id;
private InetAddress privateAddress;
public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll("\\.","");
public static final String PREFIX = (System.getProperty("user.name") + "-vcloud").replaceAll(
"\\.", "");
private static class Expectation {
final long hardDisk;
@ -71,20 +72,20 @@ public class VCloudComputeClientLiveTest {
}
}
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder()
.put(Image.CENTOS_53,
private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
.<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
Image.RHEL_53,
OperatingSystem.RHEL,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put(
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build();
OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
.build();
private Predicate<InetAddress> addressTester;
@Test
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
Image toTest = Image.CENTOS_53;
OperatingSystem toTest = OperatingSystem.CENTOS;
String serverName = getCompatibleServerName(toTest);
int processorCount = 1;
@ -101,10 +102,10 @@ public class VCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON);
}
private String getCompatibleServerName(Image toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE
.to(CaseFormat.LOWER_CAMEL, toTest.toString()).substring(0,
toTest.toString().length()-1 <= 15 ? toTest.toString().length()-1 : 14);
private String getCompatibleServerName(OperatingSystem toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, toTest.toString())
.substring(0,
toTest.toString().length() - 1 <= 15 ? toTest.toString().length() - 1 : 14);
return serverName;
}
@ -146,8 +147,8 @@ public class VCloudComputeClientLiveTest {
String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
Injector injector = new VCloudContextBuilder(new VCloudPropertiesBuilder(
URI.create(endpoint), account, key).build()).withModules(
new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
URI.create(endpoint), account, key).build()).withModules(new Log4JLoggingModule(),
new JschSshClientModule()).buildInjector();
client = injector.getInstance(VCloudComputeClient.class);
tmClient = injector.getInstance(VCloudClient.class);
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {

View File

@ -18,15 +18,12 @@
*/
package org.jclouds.vcloud.hostingdotcom.compute;
import static com.google.common.base.Preconditions.checkArgument;
import java.net.InetAddress;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Inject;
import org.jclouds.compute.domain.Image;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VApp;
@ -57,34 +54,15 @@ public class HostingDotComVCloudComputeClient {
this.taskTester = successTester;
}
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put(
Image.CENTOS_53, "3").build();
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/1"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="Plesk (Linux) 64-bit Template" />
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/2"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="Windows 2008 Datacenter 64 Bit Template" />
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/3"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="Cent OS 64 Bit Template" />
// <ResourceEntity href="https://vcloud.safesecureweb.com/api/v0.8/vAppTemplate/4"
// type="application/vnd.vmware.vcloud.vAppTemplate+xml"
// name="cPanel (Linux) 64 Bit Template" />
public Map<String, String> start(String name, Image image, int minCores, int minMegs,
long diskSize, Map<String, String> properties) {
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
String templateId = imageCatalogIdMap.get(image);
String vDCId = tmClient.getDefaultVDC().getId();
public Map<String, String> start(String vDCId, String name, String templateId, int minCores,
int minMegs, long diskSize, Map<String, String> properties) {
logger
.debug(
">> instantiating vApp vDC(%s) name(%s) template(%s) minCores(%d) minMegs(%d) diskSize(%d) properties(%s) ",
vDCId, name, templateId, minCores, minMegs, diskSize, properties);
HostingDotComVApp vAppResponse = tmClient.instantiateVAppTemplateInVDC(vDCId, name,
templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores)
.memory(minMegs).disk(diskSize).productProperties(properties));
templateId, InstantiateVAppTemplateOptions.Builder.processorCount(minCores).memory(
minMegs).disk(diskSize).productProperties(properties));
logger.debug("<< instantiated VApp(%s)", vAppResponse.getId());
logger.debug(">> deploying vApp(%s)", vAppResponse.getId());

View File

@ -28,6 +28,7 @@ import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
@ -38,8 +39,8 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -65,6 +66,9 @@ public class HostingDotComVCloudComputeService implements ComputeService {
protected Logger logger = Logger.NULL;
private final HostingDotComVCloudComputeClient computeClient;
private final HostingDotComVCloudClient client;
private final Set<? extends Image> images;
private final Set<? extends Size> sizes;
private final Provider<Set<HostingDotComVCloudTemplate>> templates;
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
@ -74,25 +78,28 @@ public class HostingDotComVCloudComputeService implements ComputeService {
@Inject
public HostingDotComVCloudComputeService(HostingDotComVCloudClient client,
HostingDotComVCloudComputeClient computeClient) {
HostingDotComVCloudComputeClient computeClient, Set<? extends Image> images,
Set<? extends Size> sizes, Provider<Set<HostingDotComVCloudTemplate>> templates) {
this.client = client;
this.computeClient = computeClient;
this.images = images;
this.sizes = sizes;
this.templates = templates;
}
@Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
Image image) {
if (checkNotNull(location, "location").equalsIgnoreCase("default"))
location = client.getDefaultVDC().getId();
Map<String, String> metaMap = computeClient.start(name, image, 1, 512, (10l * 1025 * 1024),
ImmutableMap.<String, String> of());
public CreateNodeResponse runNode(String name, Template template) {
checkNotNull(template.getImage().getLocation(), "location");
Map<String, String> metaMap = computeClient.start(template.getImage().getLocation(), name,
template.getImage().getId(), template.getSize().getCores(), template.getSize()
.getRam(), template.getSize().getDisk(), ImmutableMap.<String, String> of());
VApp vApp = client.getVApp(metaMap.get("id"));
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(),
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), 22,
LoginType.SSH, new Credentials(metaMap.get("username"), metaMap.get("password")),
ImmutableMap.<String, String> of());
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage()
.getLocation(), vApp.getLocation(), ImmutableMap.<String, String> of(),
vAppStatusToNodeState.get(vApp.getStatus()), vApp.getNetworkToAddresses().values(),
ImmutableSet.<InetAddress> of(), 22, LoginType.SSH, new Credentials(metaMap
.get("username"), metaMap.get("password")), ImmutableMap
.<String, String> of());
}
@Override
@ -105,10 +112,10 @@ public class HostingDotComVCloudComputeService implements ComputeService {
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
VApp vApp = client.getVApp(id);
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp
.getLocation(), ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp
.getStatus()), vApp.getNetworkToAddresses().values(), ImmutableSet
.<InetAddress> of(), 22, LoginType.SSH, ImmutableMap.<String, String> of());
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vDCId, vApp.getLocation(),
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
vApp.getNetworkToAddresses().values(), ImmutableSet.<InetAddress> of(), 22,
LoginType.SSH, ImmutableMap.<String, String> of());
}
@Override
@ -132,7 +139,17 @@ public class HostingDotComVCloudComputeService implements ComputeService {
}
@Override
public Map<String, Size> getSizes() {
return null;// TODO
public Template createTemplateInLocation(String location) {
return new HostingDotComVCloudTemplate(client, images, sizes, location);
}
@Override
public Set<? extends Size> listSizes() {
return sizes;
}
@Override
public Set<? extends Template> listTemplates() {
return templates.get();
}
}

View File

@ -0,0 +1,180 @@
package org.jclouds.vcloud.hostingdotcom.compute;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
public class HostingDotComVCloudTemplate implements Template {
private final HostingDotComVCloudClient client;
private final Set<? extends Image> images;
private final Set<? extends Size> sizes;
private Size size;
private String vDC;
private OperatingSystem operatingSystem;
private transient Image image;
public HostingDotComVCloudTemplate(HostingDotComVCloudClient client,
Set<? extends Image> images, Set<? extends Size> sizes, String location,
@Nullable Size size, OperatingSystem operatingSystem, @Nullable Image image) {
this.client = client;
this.images = images;
this.sizes = sizes;
this.vDC = location;
this.image = image != null ? image : resolveTemplate(images, operatingSystem);
this.size = size != null ? size : Iterables.get(sizes, 0);
this.operatingSystem = operatingSystem;
}
private Image resolveTemplate(Set<? extends Image> images, OperatingSystem operatingSystem) {
for (Image image : images) {
if (image.getOperatingSystem() == operatingSystem)
return image;
}
throw new RuntimeException("no configured image matches os: " + operatingSystem);
}
HostingDotComVCloudTemplate(HostingDotComVCloudClient client, Set<? extends Image> images,
Set<? extends Size> sizes, String location) {
this(client, images, sizes, location, null, OperatingSystem.CENTOS, null);// note the default
// os
}
/**
* {@inheritDoc}
*/
@Override
public Size getSize() {
return size;
}
/**
* {@inheritDoc}
*/
@Override
public Image getImage() {
return image;
}
/**
* {@inheritDoc}
*/
@Override
public Template smallest() {
this.size = Iterables.get(sizes, 0);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template biggest() {
this.size = Iterables.getLast(sizes);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template fastest() {
this.size = Iterables.getLast(sizes);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template inLocation(String location) {
if (location.equalsIgnoreCase("default"))
location = client.getDefaultVDC().getId();
this.vDC = location;// TODO match vdc on template as well arch
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template os(OperatingSystem os) {
this.operatingSystem = os;
this.image = resolveTemplate(images, operatingSystem);
return this;
}
/**
* {@inheritDoc}
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return new HostingDotComVCloudTemplate(client, images, sizes, vDC, size, operatingSystem,
image);
}
public String getvDC() {
return vDC;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
HostingDotComVCloudTemplate other = (HostingDotComVCloudTemplate) obj;
if (image == null) {
if (other.image != null)
return false;
} else if (!image.equals(other.image))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (size == null) {
if (other.size != null)
return false;
} else if (!size.equals(other.size))
return false;
if (vDC == null) {
if (other.vDC != null)
return false;
} else if (!vDC.equals(other.vDC))
return false;
return true;
}
@Override
public String toString() {
return "HostingDotComVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
+ ", size=" + size + ", vDC=" + vDC + "]";
}
}

View File

@ -18,16 +18,38 @@
*/
package org.jclouds.vcloud.hostingdotcom.compute.config;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestContext;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeService;
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudTemplate;
import org.jclouds.vcloud.hostingdotcom.config.HostingDotComVCloudContextModule;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.inject.Provides;
/**
@ -48,8 +70,70 @@ public class HostingDotComVCloudComputeServiceContextModule extends
@Provides
@Singleton
ComputeServiceContext provideContext(ComputeService computeService,
RestContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudAsyncClient> context) {
return new ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudAsyncClient>(
RestContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> context) {
return new ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient>(
computeService, context);
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
@Provides
@Singleton
Set<? extends Image> provideImages(VCloudClient client, LogHolder holder) {
Set<Image> images = Sets.newLinkedHashSet();
holder.logger.debug(">> providing images");
Catalog response = client.getDefaultCatalog();
String vDC = client.getDefaultVDC().getId();
for (NamedResource resource : response.values()) {
if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) {
CatalogItem item = client.getCatalogItem(resource.getId());
OperatingSystem myOs = OperatingSystem.UNKNOWN;
for (OperatingSystem os : OperatingSystem.values()) {
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
myOs = os;
}
}
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
: Architecture.X86_64;
if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null,
vDC, arch));
}
}
}
holder.logger.debug("<< images(%d)", images.size());
return images;
}
@Provides
@Singleton
Set<? extends Size> provideSizes(HostingDotComVCloudClient client, Set<? extends Image> images,
LogHolder holder) {
return ImmutableSet.<Size> of(new SizeImpl(1, 512, (int) (10l * 1025 * 1024), ImmutableSet
.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
}
@Provides
@Singleton
Set<HostingDotComVCloudTemplate> provideTemplates(HostingDotComVCloudClient client,
Set<? extends Image> images, Set<? extends Size> sizes, LogHolder holder) {
Set<HostingDotComVCloudTemplate> templates = Sets.newHashSet();
holder.logger.debug(">> generating templates");
String vDC = client.getDefaultVDC().getId();
for (Size size : sizes) {
for (Image image : images) {
templates.add(new HostingDotComVCloudTemplate(client, images, sizes, vDC, size, image
.getOperatingSystem(), image));
}
}
holder.logger.debug("<< templates(%d)", templates.size());
return templates;
}
}

View File

@ -27,7 +27,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.domain.ResourceType;
@ -73,13 +73,9 @@ public class HostingDotComVCloudComputeClientLiveTest {
}
}
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder()
.put(Image.CENTOS_53,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
Image.RHEL_53,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)")).put(
Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put(
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
.<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
new Expectation(4194304 / 2 * 10, "Red Hat Enterprise Linux 5 (64-bit)"))
.build();
private Predicate<InetAddress> addressTester;
@ -87,7 +83,7 @@ public class HostingDotComVCloudComputeClientLiveTest {
@Test(enabled = true)
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
Image toTest = Image.CENTOS_53;
OperatingSystem toTest = OperatingSystem.CENTOS;
String serverName = getCompatibleServerName(toTest);
int processorCount = 1;
@ -95,7 +91,8 @@ public class HostingDotComVCloudComputeClientLiveTest {
long disk = 10 * 1025 * 1024;
Map<String, String> properties = ImmutableMap.of("foo", "bar");
id = client.start(serverName, toTest, processorCount, memory, disk, properties).get("id");
id = client.start(hostingClient.getDefaultVDC().getId(), serverName, "3", processorCount,
memory, disk, properties).get("id");
Expectation expectation = expectationMap.get(toTest);
VApp vApp = hostingClient.getVApp(id);
@ -104,7 +101,7 @@ public class HostingDotComVCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON);
}
private String getCompatibleServerName(Image toTest) {
private String getCompatibleServerName(OperatingSystem toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
toTest.toString().length() <= 15 ? toTest.toString().length() : 14);
@ -148,8 +145,8 @@ public class HostingDotComVCloudComputeClientLiveTest {
String account = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
Injector injector = new HostingDotComVCloudContextBuilder(
new HostingDotComVCloudPropertiesBuilder(account, key).build())
.withModules(new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
new HostingDotComVCloudPropertiesBuilder(account, key).build()).withModules(
new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
client = injector.getInstance(HostingDotComVCloudComputeClient.class);
hostingClient = injector.getInstance(HostingDotComVCloudClient.class);
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {

View File

@ -20,23 +20,28 @@
package org.jclouds.vcloud.hostingdotcom.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OperatingSystem.CENTOS;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
@ -48,6 +53,7 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -59,30 +65,35 @@ import com.google.inject.Injector;
*/
@Test(groups = "live", enabled = true, sequential = true, testName = "compute.HostingDotComVCloudComputeServiceLiveTest")
public class HostingDotComVCloudComputeServiceLiveTest {
private static final String service = "hostingdotcom";
private static final OperatingSystem testOS = CENTOS;
protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name");
private String nodeName = service;
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node;
private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = HostingDotComVCloudComputeServiceContextFactory.createContext(user, password,
new Log4JLoggingModule());
context = new ComputeServiceContextFactory().createContext(service, user, password,
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
}
public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
Profile.SMALLEST, Image.UBUNTU_90);
Template template = client.createTemplateInLocation("default").os(testOS).smallest();
node = client.runNode(nodeName, template);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
@ -97,7 +108,7 @@ public class HostingDotComVCloudComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
@ -107,13 +118,27 @@ public class HostingDotComVCloudComputeServiceLiveTest {
}
public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) {
for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null;
assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE);
}
}
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException {
try {
doCheckKey();
@ -147,7 +172,7 @@ public class HostingDotComVCloudComputeServiceLiveTest {
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null)
context.getComputeService().destroyNode(node);
client.destroyNode(node);
context.close();
}
}

View File

@ -1,32 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
<!--
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
Copyright (C) 2009 Cloud Conscious, LLC.
<info@cloudconscious.com>
====================================================================
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
====================================================================
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.
====================================================================
-->
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.
====================================================================
-->
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!--
For more configuration infromation and examples see the Apache Log4j
website: http://logging.apache.org/log4j/
-->
<!--
For more configuration infromation and examples see the Apache
Log4j website: http://logging.apache.org/log4j/
-->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
debug="false">
debug="false">
<!-- A time/date based rolling appender -->
<appender name="WIREFILE" class="org.apache.log4j.DailyRollingFileAppender">
@ -43,36 +42,34 @@
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- A time/date based rolling appender -->
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
@ -89,70 +86,60 @@
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
The full pattern: Date MS Priority [Category]
(Thread:NDC) Message\n <param name="ConversionPattern"
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
-->
</layout>
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<category name="org.jclouds">
<priority value="DEBUG" />
<appender name="ASYNCWIRE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="WIREFILE" />
</appender>
<!-- ================ -->
<!-- Limit categories -->
<!-- ================ -->
<category name="org.jclouds">
<priority value="DEBUG" />
<appender-ref ref="ASYNC" />
</category>
</category>
<category name="jclouds.http.headers">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeClient">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<category name="org.jclouds.predicates.SocketOpen">
<priority value="TRACE" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="org.jclouds.vcloud.predicates.TaskSuccess">
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCWIRE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<category name="jclouds.http.wire">
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->
<root>
<priority value="WARN" />
</root>
<root>
<priority value="WARN" />
</root>
</log4j:configuration>

View File

@ -31,7 +31,7 @@ import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task;
@ -68,11 +68,13 @@ public class TerremarkVCloudComputeClient {
this.taskTester = successTester;
}
private Map<Image, String> imageCatalogIdMap = ImmutableMap.<Image, String> builder().put(
Image.CENTOS_53, "6").put(Image.RHEL_53, "8").put(Image.UBUNTU_90, "10").put(
Image.UBUNTU_JEOS_90, "11").put(Image.WEBAPPVM_93, "29").build();
private Map<OperatingSystem, String> imageCatalogIdMap = ImmutableMap
.<OperatingSystem, String> builder().put(OperatingSystem.CENTOS, "6").put(
OperatingSystem.RHEL, "8").put(OperatingSystem.UBUNTU, "10").build();
public String start(String name, Image image, int minCores, int minMegs,
// .put( OperatingSystem.UBUNTU_JEOS_90, "11").put(OperatingSystem.WEBAPPVM_93, "29")
public String start(String name, OperatingSystem image, int minCores, int minMegs,
Map<String, String> properties) {
checkArgument(imageCatalogIdMap.containsKey(image), "image not configured: " + image);
return start(name, imageCatalogIdMap.get(image), minCores, minMegs, properties);
@ -80,6 +82,12 @@ public class TerremarkVCloudComputeClient {
public String start(String name, String templateId, int minCores, int minMegs,
Map<String, String> properties) {
return this.start(tmClient.getDefaultVDC().getId(), name, templateId, minCores, minMegs,
properties);
}
public String start(String vdc, String name, String templateId, int minCores, int minMegs,
Map<String, String> properties) {
String vDCId = tmClient.getDefaultVDC().getId();
logger
.debug(

View File

@ -28,6 +28,7 @@ import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
@ -38,8 +39,8 @@ import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
@ -65,6 +66,9 @@ public class TerremarkVCloudComputeService implements ComputeService {
protected Logger logger = Logger.NULL;
private final TerremarkVCloudComputeClient computeClient;
private final TerremarkVCloudClient client;
private Set<? extends Image> images;
private Set<? extends Size> sizes;
private Provider<Set<TerremarkVCloudTemplate>> templates;
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
@ -74,21 +78,25 @@ public class TerremarkVCloudComputeService implements ComputeService {
@Inject
public TerremarkVCloudComputeService(TerremarkVCloudClient tmClient,
TerremarkVCloudComputeClient computeClient) {
TerremarkVCloudComputeClient computeClient, Set<? extends Image> images,
Set<? extends Size> sizes, Provider<Set<TerremarkVCloudTemplate>> templates) {
this.client = tmClient;
this.computeClient = computeClient;
this.images = images;
this.sizes = sizes;
this.templates = templates;
}
@Override
public CreateNodeResponse startNodeInLocation(String location, String name, Profile profile,
Image image) {
if (checkNotNull(location, "location").equalsIgnoreCase("default"))
location = client.getDefaultVDC().getId();
String id = computeClient.start(name, image, 1, 512, ImmutableMap.<String, String> of());
public CreateNodeResponse runNode(String name, Template template) {
checkNotNull(template.getImage().getLocation(), "location");
String id = computeClient.start(template.getImage().getLocation(), name, template.getImage()
.getId(), (int) template.getSize().getCores(), (int) template.getSize().getRam(),
ImmutableMap.<String, String> of());
VApp vApp = client.getVApp(id);
InetAddress publicIp = computeClient
.createPublicAddressMappedToPorts(vApp, 22, 80, 8080, 443);
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), location, vApp.getLocation(),
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), template.getImage().getLocation(), vApp.getLocation(),
ImmutableMap.<String, String> of(), vAppStatusToNodeState.get(vApp.getStatus()),
ImmutableSet.<InetAddress> of(publicIp), vApp.getNetworkToAddresses().values(), 22,
LoginType.SSH, new Credentials("vcloud", "p4ssw0rd"), ImmutableMap
@ -99,8 +107,8 @@ public class TerremarkVCloudComputeService implements ComputeService {
public NodeMetadata getNodeMetadata(ComputeMetadata node) {
checkArgument(node.getType() == ComputeType.NODE, "this is only valid for nodes, not "
+ node.getType());
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(node.getId(),
"node.id"));
return getNodeMetadataByIdInVDC(checkNotNull(node.getLocation(), "location"), checkNotNull(
node.getId(), "node.id"));
}
private NodeMetadata getNodeMetadataByIdInVDC(String vDCId, String id) {
@ -133,7 +141,17 @@ public class TerremarkVCloudComputeService implements ComputeService {
}
@Override
public Map<String, Size> getSizes() {
return null;// TODO
public Template createTemplateInLocation(String location) {
return new TerremarkVCloudTemplate(client, images, sizes, location);
}
@Override
public Set<? extends Size> listSizes() {
return sizes;
}
@Override
public Set<? extends Template> listTemplates() {
return templates.get();
}
}

View File

@ -0,0 +1,178 @@
package org.jclouds.vcloud.terremark.compute;
import java.util.Set;
import javax.annotation.Nullable;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import com.google.common.collect.Iterables;
/**
*
* @author Adrian Cole
*/
public class TerremarkVCloudTemplate implements Template {
private final TerremarkVCloudClient client;
private final Set<? extends Image> images;
private final Set<? extends Size> sizes;
private Size size;
private String vDC;
private OperatingSystem operatingSystem;
private transient Image image;
public TerremarkVCloudTemplate(TerremarkVCloudClient client, Set<? extends Image> images,
Set<? extends Size> sizes, String location, @Nullable Size size,
OperatingSystem operatingSystem, @Nullable Image image) {
this.client = client;
this.images = images;
this.sizes = sizes;
this.vDC = location;
this.image = image != null ? image : resolveTemplate(images, operatingSystem);
this.size = size != null ? size : Iterables.get(sizes, 0);
this.operatingSystem = operatingSystem;
}
private Image resolveTemplate(Set<? extends Image> images, OperatingSystem operatingSystem) {
for (Image image : images) {
if (image.getOperatingSystem() == operatingSystem)
return image;
}
throw new RuntimeException("no configured image matches os: " + operatingSystem);
}
TerremarkVCloudTemplate(TerremarkVCloudClient client, Set<? extends Image> images,
Set<? extends Size> sizes, String location) {
this(client, images, sizes, location, null, OperatingSystem.UBUNTU, null);
}
/**
* {@inheritDoc}
*/
@Override
public Size getSize() {
return size;
}
/**
* {@inheritDoc}
*/
@Override
public Image getImage() {
return image;
}
/**
* {@inheritDoc}
*/
@Override
public Template smallest() {
this.size = Iterables.get(sizes, 0);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template biggest() {
this.size = Iterables.getLast(sizes);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template fastest() {
this.size = Iterables.getLast(sizes);
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template inLocation(String location) {
if (location.equalsIgnoreCase("default"))
location = client.getDefaultVDC().getId();
this.vDC = location;// TODO match vdc on template as well arch
return this;
}
/**
* {@inheritDoc}
*/
@Override
public Template os(OperatingSystem os) {
this.operatingSystem = os;
this.image = resolveTemplate(images, operatingSystem);
return this;
}
/**
* {@inheritDoc}
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return new TerremarkVCloudTemplate(client, images, sizes, vDC, size, operatingSystem, image);
}
public String getvDC() {
return vDC;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((image == null) ? 0 : image.hashCode());
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((size == null) ? 0 : size.hashCode());
result = prime * result + ((vDC == null) ? 0 : vDC.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
TerremarkVCloudTemplate other = (TerremarkVCloudTemplate) obj;
if (image == null) {
if (other.image != null)
return false;
} else if (!image.equals(other.image))
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (size == null) {
if (other.size != null)
return false;
} else if (!size.equals(other.size))
return false;
if (vDC == null) {
if (other.vDC != null)
return false;
} else if (!vDC.equals(other.vDC))
return false;
return true;
}
@Override
public String toString() {
return "TerremarkVCloudTemplate [image=" + image + ", operatingSystem=" + operatingSystem
+ ", size=" + size + ", vDC=" + vDC + "]";
}
}

View File

@ -18,17 +18,42 @@
*/
package org.jclouds.vcloud.terremark.compute.config;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.Architecture;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.internal.ImageImpl;
import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.rest.RestContext;
import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.domain.Catalog;
import org.jclouds.vcloud.domain.CatalogItem;
import org.jclouds.vcloud.domain.NamedResource;
import org.jclouds.vcloud.domain.VAppTemplate;
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeService;
import org.jclouds.vcloud.terremark.compute.TerremarkVCloudTemplate;
import org.jclouds.vcloud.terremark.config.TerremarkVCloudContextModule;
import org.jclouds.vcloud.terremark.domain.ComputeOptions;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import com.google.inject.Provides;
/**
@ -53,4 +78,82 @@ public class TerremarkVCloudComputeServiceContextModule extends TerremarkVCloudC
computeService, context);
}
private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize();
private static class ComputeOptionsToSize implements Function<ComputeOptions, Size> {
@Override
public Size apply(ComputeOptions from) {
return new SizeImpl(from.getProcessorCount(), (int) from.getMemory(), null, ImmutableSet
.<Architecture> of(Architecture.X86_32, Architecture.X86_64));
}
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
@Provides
@Singleton
Set<? extends Image> provideImages(VCloudClient client, LogHolder holder) {
Set<Image> images = Sets.newLinkedHashSet();
holder.logger.debug(">> providing images");
Catalog response = client.getDefaultCatalog();
String vDC = client.getDefaultVDC().getId();
for (NamedResource resource : response.values()) {
if (resource.getType().equals(VCloudMediaType.CATALOGITEM_XML)) {
CatalogItem item = client.getCatalogItem(resource.getId());
OperatingSystem myOs = OperatingSystem.UNKNOWN;
for (OperatingSystem os : OperatingSystem.values()) {
if (resource.getName().toUpperCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
myOs = os;
}
}
Architecture arch = resource.getName().matches("64[- ]bit") ? Architecture.X86_32
: Architecture.X86_64;
if (item.getEntity().getType().equals(VCloudMediaType.VAPPTEMPLATE_XML)) {
VAppTemplate template = client.getVAppTemplate(item.getEntity().getId());
images.add(new ImageImpl(resource.getId(), template.getDescription(), myOs, null,
vDC, arch));
}
}
}
holder.logger.debug("<< images(%d)", images.size());
return images;
}
@Provides
@Singleton
Set<? extends Size> provideSizes(TerremarkVCloudClient client, Set<? extends Image> images,
LogHolder holder) {
Image anyImage = Iterables.get(images, 0);
holder.logger.debug(">> providing sizes");
LinkedHashSet<Size> sizes = Sets.newLinkedHashSet(Iterables.transform(client
.getComputeOptionsOfCatalogItem(anyImage.getId()), sizeConverter));
holder.logger.debug("<< sizes(%d)", sizes.size());
return sizes;
}
@Provides
@Singleton
Set<TerremarkVCloudTemplate> provideTemplates(TerremarkVCloudClient client,
Set<? extends Image> images, Set<? extends Size> sizes, LogHolder holder) {
Set<TerremarkVCloudTemplate> templates = Sets.newHashSet();
holder.logger.debug(">> generating templates");
String vDC = client.getDefaultVDC().getId();
for (Size size : sizes) {
for (Image image : images) {
templates.add(new TerremarkVCloudTemplate(client, images, sizes, vDC, size, image
.getOperatingSystem(), image));
}
}
holder.logger.debug("<< templates(%d)", templates.size());
return templates;
}
}

View File

@ -27,7 +27,7 @@ import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.vcloud.domain.ResourceType;
@ -73,18 +73,20 @@ public class TerremarkVCloudComputeClientLiveTest {
}
}
private Map<Image, Expectation> expectationMap = ImmutableMap.<Image, Expectation> builder()
.put(Image.CENTOS_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)"))
.put(Image.RHEL_53, new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)"))
.put(Image.UBUNTU_90, new Expectation(4194304, "Ubuntu Linux (64-bit)")).put(
Image.UBUNTU_JEOS_90, new Expectation(4194304, "Ubuntu Linux (32-bit)")).build();
private Map<OperatingSystem, Expectation> expectationMap = ImmutableMap
.<OperatingSystem, Expectation> builder().put(OperatingSystem.CENTOS,
new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
OperatingSystem.RHEL,
new Expectation(10485760, "Red Hat Enterprise Linux 5 (64-bit)")).put(
OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (64-bit)"))
.build();
// .put(OperatingSystem.UBUNTU, new Expectation(4194304, "Ubuntu Linux (32-bit)"))
private Predicate<InetAddress> addressTester;
@Test
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
Image toTest = Image.CENTOS_53;
OperatingSystem toTest = OperatingSystem.CENTOS;
String serverName = getCompatibleServerName(toTest);
int processorCount = 1;
@ -100,7 +102,7 @@ public class TerremarkVCloudComputeClientLiveTest {
assertEquals(vApp.getStatus(), VAppStatus.ON);
}
private String getCompatibleServerName(Image toTest) {
private String getCompatibleServerName(OperatingSystem toTest) {
String serverName = CaseFormat.UPPER_UNDERSCORE
.to(CaseFormat.LOWER_HYPHEN, toTest.toString()).substring(0,
toTest.toString().length() <= 15 ? toTest.toString().length() : 14);
@ -115,9 +117,8 @@ public class TerremarkVCloudComputeClientLiveTest {
@Test(dependsOnMethods = "testGetAnyPrivateAddress")
public void testSshLoadBalanceIp() {
InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22,
80,
443, 8080); /// error 500
InetAddress publicIp = client.createPublicAddressMappedToPorts(tmClient.getVApp(id), 22, 80,
443, 8080); // / error 500
assert addressTester.apply(publicIp);
// client.exec(publicIp, "uname -a");
}

View File

@ -20,23 +20,29 @@
package org.jclouds.vcloud.terremark.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.domain.OperatingSystem.CENTOS;
import static org.jclouds.compute.domain.OperatingSystem.UBUNTU;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.ComputeMetadata;
import org.jclouds.compute.domain.ComputeType;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.OperatingSystem;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
@ -48,6 +54,7 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Guice;
import com.google.inject.Injector;
@ -59,30 +66,35 @@ import com.google.inject.Injector;
*/
@Test(groups = "live", enabled = true, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest")
public class TerremarkVCloudComputeServiceLiveTest {
private static final String service = "terremark";
private static final OperatingSystem testOS = UBUNTU;
protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name");
private String nodeName = service;
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node;
private ComputeServiceContext context;
private ComputeService client;
@BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
context = TerremarkVCloudComputeServiceContextFactory.createContext(user, password,
new Log4JLoggingModule());
context = new ComputeServiceContextFactory().createContext(service, user, password,
ImmutableSet.of(new Log4JLoggingModule()), new Properties());
Injector injector = Guice.createInjector(new JschSshClientModule());
sshFactory = injector.getInstance(SshClient.Factory.class);
SocketOpen socketOpen = injector.getInstance(SocketOpen.class);
socketTester = new RetryablePredicate<InetSocketAddress>(socketOpen, 60, 1, TimeUnit.SECONDS);
injector.injectMembers(socketOpen); // add logger
client = context.getComputeService();
}
public void testCreate() throws Exception {
node = context.getComputeService().startNodeInLocation("default", nodePrefix,
Profile.SMALLEST, Image.UBUNTU_90);
Template template = client.createTemplateInLocation("default").os(testOS).smallest();
node = client.runNode(nodeName, template);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
@ -97,7 +109,7 @@ public class TerremarkVCloudComputeServiceLiveTest {
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node);
NodeMetadata metadata = client.getNodeMetadata(node);
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
@ -107,13 +119,27 @@ public class TerremarkVCloudComputeServiceLiveTest {
}
public void testList() throws Exception {
for (ComputeMetadata node : context.getComputeService().listNodes()) {
for (ComputeMetadata node : client.listNodes()) {
assert node.getId() != null;
assert node.getLocation() != null;
assertEquals(node.getType(), ComputeType.NODE);
}
}
public void testListTemplates() throws Exception {
for (Template template : client.listTemplates()) {
assert template.getImage() != null;
System.out.println(template);
}
}
public void testListSizes() throws Exception {
for (Size size : client.listSizes()) {
assert size.getCores() != null;
System.out.println(size);
}
}
private void sshPing() throws IOException {
try {
doCheckKey();
@ -147,7 +173,7 @@ public class TerremarkVCloudComputeServiceLiveTest {
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null)
context.getComputeService().destroyNode(node);
client.destroyNode(node);
context.close();
}
}

View File

@ -67,6 +67,32 @@
</layout>
</appender>
<!-- A time/date based rolling appender -->
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="target/test-data/jclouds-compute.log" />
<param name="Append" value="true" />
<!-- Rollover at midnight each day -->
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<param name="Threshold" value="TRACE" />
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
<!--
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
%m%n"/>
-->
</layout>
</appender>
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="COMPUTEFILE" />
</appender>
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
@ -93,6 +119,11 @@
<priority value="DEBUG" />
<appender-ref ref="ASYNCWIRE" />
</category>
<category name="jclouds.compute">
<priority value="TRACE" />
<appender-ref ref="ASYNCCOMPUTE" />
</category>
<!--======================= -->
<!-- Setup the Root category -->
<!-- ======================= -->