Issue 129 Issue 130: changed naming convention per libcloud; added context object

git-svn-id: http://jclouds.googlecode.com/svn/trunk@2644 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
adrian.f.cole 2010-01-13 01:19:42 +00:00
parent c781f16f0e
commit 6ff6abd36c
56 changed files with 1878 additions and 779 deletions

View File

@ -25,7 +25,6 @@ import static org.jclouds.scriptbuilder.domain.Statements.exec;
import java.net.InetAddress;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -42,17 +41,17 @@ import org.jclouds.aws.ec2.domain.KeyPair;
import org.jclouds.aws.ec2.domain.Reservation;
import org.jclouds.aws.ec2.domain.RunningInstance;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.ServerIdentity;
import org.jclouds.compute.domain.ServerMetadata;
import org.jclouds.compute.domain.ServerState;
import org.jclouds.compute.domain.internal.CreateServerResponseImpl;
import org.jclouds.compute.domain.internal.ServerIdentityImpl;
import org.jclouds.compute.domain.internal.ServerMetadataImpl;
import org.jclouds.compute.reference.ComputeConstants;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeIdentityImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger;
import org.jclouds.scriptbuilder.ScriptBuilder;
@ -71,18 +70,18 @@ import com.google.inject.internal.ImmutableSet;
@Singleton
public class EC2ComputeService implements ComputeService {
@Resource
@Named(ComputeConstants.COMPUTE_LOGGER)
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final EC2Client ec2Client;
private final Predicate<RunningInstance> instanceStateRunning;
private final RunningInstanceToServerMetadata runningInstanceToServerMetadata;
private final RunningInstanceToNodeMetadata runningInstanceToNodeMetadata;
@Inject
public EC2ComputeService(EC2Client tmClient, Predicate<RunningInstance> instanceStateRunning,
RunningInstanceToServerMetadata runningInstanceToServerMetadata) {
RunningInstanceToNodeMetadata runningInstanceToNodeMetadata) {
this.ec2Client = tmClient;
this.instanceStateRunning = instanceStateRunning;
this.runningInstanceToServerMetadata = runningInstanceToServerMetadata;
this.runningInstanceToNodeMetadata = runningInstanceToNodeMetadata;
}
// TODO: handle regions
@ -102,14 +101,13 @@ public class EC2ComputeService implements ComputeService {
Profile.MEDIUM, InstanceType.C1_MEDIUM).put(Profile.FASTEST,
InstanceType.C1_XLARGE).build();
private static Map<InstanceState, ServerState> instanceToServerState = ImmutableMap
.<InstanceState, ServerState> builder().put(InstanceState.PENDING, ServerState.PENDING)
.put(InstanceState.RUNNING, ServerState.RUNNING).put(InstanceState.SHUTTING_DOWN,
ServerState.PENDING).put(InstanceState.TERMINATED, ServerState.TERMINATED)
.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 CreateServerResponse createServer(String name, Profile profile, Image image) {
public CreateNodeResponse createNode(String name, Profile profile, Image image) {
InstanceType type = checkNotNull(profileInstanceTypeMap.get(profile),
"profile not supported: " + profile);
String ami = checkNotNull(imageAmiIdMap.get(type).get(image), "image not supported: " + image);
@ -149,9 +147,10 @@ public class EC2ComputeService implements ComputeService {
Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet
.<InetAddress> of()
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
return new CreateServerResponseImpl(runningInstance.getId(), name, instanceToServerState
return new CreateNodeResponseImpl(runningInstance.getId(), name, instanceToNodeState
.get(runningInstance.getInstanceState()), publicAddresses, privateAddresses, 22,
LoginType.SSH, new Credentials("root", keyPair.getKeyMaterial()));
LoginType.SSH, new Credentials("root", keyPair.getKeyMaterial()), ImmutableMap
.<String, String> of());
}
private KeyPair createKeyPair(String name) {
@ -199,20 +198,20 @@ public class EC2ComputeService implements ComputeService {
}
@Override
public ServerMetadata getServerMetadata(String id) {
public NodeMetadata getNodeMetadata(String id) {
RunningInstance runningInstance = getRunningInstance(id);
return runningInstanceToServerMetadata.apply(runningInstance);
return runningInstanceToNodeMetadata.apply(runningInstance);
}
@Singleton
private static class RunningInstanceToServerMetadata implements
Function<RunningInstance, ServerMetadata> {
private static class RunningInstanceToNodeMetadata implements
Function<RunningInstance, NodeMetadata> {
@Override
public ServerMetadata apply(RunningInstance from) {
return new ServerMetadataImpl(from.getId(), from.getKeyName(), instanceToServerState
.get(from.getInstanceState()), nullSafeSet(from.getIpAddress()), nullSafeSet(from
.getPrivateIpAddress()), 22, LoginType.SSH);
public NodeMetadata apply(RunningInstance from) {
return new NodeMetadataImpl(from.getId(), from.getKeyName(), instanceToNodeState.get(from
.getInstanceState()), nullSafeSet(from.getIpAddress()), nullSafeSet(from
.getPrivateIpAddress()), 22, LoginType.SSH, ImmutableMap.<String, String> of());
}
Set<InetAddress> nullSafeSet(InetAddress in) {
@ -231,10 +230,10 @@ public class EC2ComputeService implements ComputeService {
}
@Override
public SortedSet<ServerIdentity> getServerByName(final String name) {
return Sets.newTreeSet(Iterables.filter(listServers(), new Predicate<ServerIdentity>() {
public Set<NodeIdentity> getNodeByName(final String name) {
return Sets.newHashSet(Iterables.filter(listNodes(), new Predicate<NodeIdentity>() {
@Override
public boolean apply(ServerIdentity input) {
public boolean apply(NodeIdentity input) {
return input.getName().equalsIgnoreCase(name);
}
}));
@ -245,16 +244,16 @@ public class EC2ComputeService implements ComputeService {
* keyname. This will break.
*/
@Override
public SortedSet<ServerIdentity> listServers() {
public Set<NodeIdentity> listNodes() {
logger.debug(">> listing servers");
SortedSet<ServerIdentity> servers = Sets.newTreeSet();
Set<NodeIdentity> servers = Sets.newHashSet();
for (Reservation reservation : ec2Client.getInstanceServices().describeInstancesInRegion(
Region.DEFAULT)) {
Iterables.addAll(servers, Iterables.transform(reservation.getRunningInstances(),
new Function<RunningInstance, ServerIdentity>() {
new Function<RunningInstance, NodeIdentity>() {
@Override
public ServerIdentity apply(RunningInstance from) {
return new ServerIdentityImpl(from.getId(), from.getKeyName());
public NodeIdentity apply(RunningInstance from) {
return new NodeIdentityImpl(from.getId(), from.getKeyName());
}
}));
}
@ -263,7 +262,7 @@ public class EC2ComputeService implements ComputeService {
}
@Override
public void destroyServer(String id) {
public void destroyNode(String id) {
RunningInstance runningInstance = getRunningInstance(id);
// grab the old keyname
String name = runningInstance.getKeyName();

View File

@ -0,0 +1,78 @@
/**
*
* 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.aws.ec2.compute;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.config.EC2ComputeServiceContextModule;
import org.jclouds.aws.ec2.config.EC2RestClientModule;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Creates {@link EC2ComputeServiceContext} or {@link Injector} instances based on the most commonly
* requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see EC2ComputeServiceContext
*/
public class EC2ComputeServiceContextBuilder extends
ComputeServiceContextBuilder<EC2AsyncClient, EC2Client> {
public EC2ComputeServiceContextBuilder(Properties props) {
super(new TypeLiteral<EC2AsyncClient>() {
}, new TypeLiteral<EC2Client>() {
}, props);
}
@Override
public EC2ComputeServiceContextBuilder withExecutorService(ExecutorService service) {
return (EC2ComputeServiceContextBuilder) super.withExecutorService(service);
}
@Override
public EC2ComputeServiceContextBuilder withModules(Module... modules) {
return (EC2ComputeServiceContextBuilder) super.withModules(modules);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new EC2ComputeServiceContextModule());
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new EC2RestClientModule());
}
}

View File

@ -0,0 +1,71 @@
/**
*
* 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.aws.ec2.compute;
import java.net.URI;
import java.util.Properties;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.EC2PropertiesBuilder;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import com.google.inject.Module;
/**
* Creates {@link EC2ComputeServiceContext} instances based on the most commonly requested
* arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see EC2ComputeServiceContext
*/
public class EC2ComputeServiceContextFactory {
public static ComputeServiceContext<EC2AsyncClient, EC2Client> createContext(Properties properties,
Module... modules) {
return new EC2ComputeServiceContextBuilder(new EC2PropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static ComputeServiceContext<EC2AsyncClient, EC2Client> createContext(String awsAccessKeyId,
String awsSecretAccessKey, Module... modules) {
return new EC2ComputeServiceContextBuilder(new EC2PropertiesBuilder(awsAccessKeyId,
awsSecretAccessKey).build()).withModules(modules).buildContext();
}
public static ComputeServiceContext<EC2AsyncClient, EC2Client> createContext(Properties properties,
String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
return new EC2ComputeServiceContextBuilder(new EC2PropertiesBuilder(properties).withCredentials(
awsAccessKeyId, awsSecretAccessKey).build()).withModules(modules).buildContext();
}
public static ComputeServiceContext<EC2AsyncClient, EC2Client> createContext(URI endpoint,
String awsAccessKeyId, String awsSecretAccessKey, Module... modules) {
return new EC2ComputeServiceContextBuilder(new EC2PropertiesBuilder(awsAccessKeyId,
awsSecretAccessKey).withEndpoint(endpoint).build()).withModules(modules)
.buildContext();
}
}

View File

@ -0,0 +1,60 @@
/**
*
* 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.aws.ec2.compute.config;
import java.net.URI;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.aws.ec2.EC2;
import org.jclouds.aws.ec2.EC2AsyncClient;
import org.jclouds.aws.ec2.EC2Client;
import org.jclouds.aws.ec2.compute.EC2ComputeService;
import org.jclouds.aws.reference.AWSConstants;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.lifecycle.Closer;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link EC2ComputeServiceContext}; requires {@link EC2ComputeService} bound.
*
* @author Adrian Cole
*/
public class EC2ComputeServiceContextModule extends AbstractModule {
@Override
protected void configure() {
bind(ComputeService.class).to(EC2ComputeService.class).asEagerSingleton();
}
@Provides
@Singleton
ComputeServiceContext<EC2AsyncClient, EC2Client> provideContext(Closer closer,
ComputeService computeService, EC2AsyncClient asynchApi, EC2Client defaultApi,
@EC2 URI endPoint, @Named(AWSConstants.PROPERTY_AWS_ACCESSKEYID) String account) {
return new ComputeServiceContextImpl<EC2AsyncClient, EC2Client>(closer, computeService,
asynchApi, defaultApi, endPoint, account);
}
}

View File

@ -0,0 +1,81 @@
/**
*
* 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.aws.ec2;
import static org.testng.Assert.assertEquals;
import java.util.List;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
import org.apache.log4j.spi.LoggingEvent;
import org.testng.annotations.Test;
import org.testng.collections.Lists;
import com.google.common.collect.ImmutableList;
/**
*
* @author Adrian Cole
*/
@Test
public class TestLogger {
static class AppenderForTesting extends AppenderSkeleton {
private static List<String> messages = Lists.newArrayList();
protected void append(LoggingEvent event) {
messages.add(event.getLoggerName() + ":" + event.getRenderedMessage());
}
public void close() {
}
public boolean requiresLayout() {
return false;
}
public static List<String> getMessages() {
return messages;
}
public static void clear() {
messages.clear();
}
}
static class LogApples {
final Logger logger = LogManager.getLogger(LogApples.class);
public void log(String in) {
logger.info(in);
}
}
@Test
void testFoo() {
Logger.getRootLogger().addAppender(new AppenderForTesting());
Logger.getRootLogger().addAppender(new ConsoleAppender(new SimpleLayout()));
new LogApples().log("foo");
assertEquals(AppenderForTesting.getMessages(), ImmutableList.of("foo"));
}
}

View File

@ -29,14 +29,14 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.aws.ec2.EC2ContextBuilder;
import org.jclouds.aws.ec2.EC2PropertiesBuilder;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.ServerIdentity;
import org.jclouds.compute.domain.ServerMetadata;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
@ -48,6 +48,7 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
@ -56,23 +57,23 @@ import com.google.inject.Injector;
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = false, sequential = true, testName = "ec2.EC2ComputeServiceLiveTest")
@Test(groups = "live", enabled = true, sequential = true, testName = "ec2.EC2ComputeServiceLiveTest")
public class EC2ComputeServiceLiveTest {
private EC2ComputeService client;
protected SshClient.Factory sshFactory;
private String serverPrefix = System.getProperty("user.name") + ".ec2";
private String nodePrefix = System.getProperty("user.name") + ".ec2";
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateServerResponse server;
private CreateNodeResponse node;
private ComputeServiceContext<?, ?> context;
@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");
Injector injector = new EC2ContextBuilder(new EC2PropertiesBuilder(user, password).build())
.withModules(new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
client = injector.getInstance(EC2ComputeService.class);
context = new ComputeServiceContextFactory().createContext("ec2", user, password,
new Log4JLoggingModule());
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);
@ -80,33 +81,33 @@ public class EC2ComputeServiceLiveTest {
}
public void testCreate() throws Exception {
server = client.createServer(serverPrefix, Profile.SMALLEST, Image.RHEL_53);
assertNotNull(server.getId());
assertEquals(server.getLoginPort(), 22);
assertEquals(server.getLoginType(), LoginType.SSH);
assertNotNull(server.getName());
assertEquals(server.getPrivateAddresses().size(), 1);
assertEquals(server.getPublicAddresses().size(), 1);
assertNotNull(server.getCredentials());
assertNotNull(server.getCredentials().account);
assertNotNull(server.getCredentials().key);
node = context.getComputeService().createNode(nodePrefix, Profile.SMALLEST, Image.RHEL_53);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
assertNotNull(node.getName());
assertEquals(node.getPrivateAddresses().size(), 1);
assertEquals(node.getPublicAddresses().size(), 1);
assertNotNull(node.getCredentials());
assertNotNull(node.getCredentials().account);
assertNotNull(node.getCredentials().key);
sshPing();
}
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
ServerMetadata metadata = client.getServerMetadata(server.getId());
assertEquals(metadata.getId(), server.getId());
assertEquals(metadata.getLoginPort(), server.getLoginPort());
assertEquals(metadata.getLoginType(), server.getLoginType());
assertEquals(metadata.getName(), server.getName());
assertEquals(metadata.getPrivateAddresses(), server.getPrivateAddresses());
assertEquals(metadata.getPublicAddresses(), server.getPublicAddresses());
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node.getId());
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
assertEquals(metadata.getName(), node.getName());
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
}
public void testList() throws Exception {
for (ServerIdentity server : client.listServers()) {
assert server.getId() != null;
for (NodeIdentity node : context.getComputeService().listNodes()) {
assert node.getId() != null;
}
}
@ -123,10 +124,10 @@ public class EC2ComputeServiceLiveTest {
}
private void doCheckKey() throws IOException {
InetSocketAddress socket = new InetSocketAddress(server.getPublicAddresses().last(), server
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
.getLoginPort());
socketTester.apply(socket);
SshClient connection = sshFactory.create(socket, server.getCredentials().account, server
SshClient connection = sshFactory.create(socket, node.getCredentials().account, node
.getCredentials().key.getBytes());
try {
connection.connect();
@ -140,8 +141,9 @@ public class EC2ComputeServiceLiveTest {
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (server != null)
client.destroyServer(server.getId());
if (node != null)
context.getComputeService().destroyNode(node.getId());
context.close();
}
}

View File

@ -0,0 +1,53 @@
/**
*
* 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.aws.ec2.compute;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.aws.ec2.EC2PropertiesBuilder;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.io.Resources;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "compute.PropertiesTest")
public class PropertiesTest {
private Properties properties;
@BeforeTest
public void setUp() throws IOException {
properties = new Properties();
properties.load(Resources.newInputStreamSupplier(Resources.getResource("compute.properties"))
.getInput());
}
public void testProperties() {
assertEquals(properties.getProperty("ec2.contextbuilder"),
EC2ComputeServiceContextBuilder.class.getName());
assertEquals(properties.getProperty("ec2.propertiesbuilder"),
EC2PropertiesBuilder.class.getName());
}
}

View File

@ -59,14 +59,19 @@ public class BlobStoreContextFactory {
return createContext(blobStore, Credentials.parse(blobStore), modules);
}
@SuppressWarnings("unchecked")
public BlobStoreContext<?, ?> createContext(URI blobStore, Credentials creds, Module... modules) {
String hint = checkNotNull(blobStore.getHost(), "host");
String account = checkNotNull(creds.account, "account");
String key = creds.key;
return createContext(checkNotNull(blobStore.getHost(), "host"), checkNotNull(creds.account,
"account"), creds.key, modules);
}
@SuppressWarnings("unchecked")
public BlobStoreContext<?, ?> createContext(String hint, String account, String key,
Module... modules) {
checkNotNull(hint, "hint");
checkNotNull(account, "account");
String propertiesBuilderKey = String.format("%s.propertiesbuilder", hint);
String propertiesBuilderClassName = checkNotNull(
properties.getProperty(propertiesBuilderKey), propertiesBuilderKey);
properties.getProperty(propertiesBuilderKey), hint + " service not supported");
String contextBuilderKey = String.format("%s.contextbuilder", hint);
String contextBuilderClassName = checkNotNull(properties.getProperty(contextBuilderKey),

View File

@ -18,13 +18,13 @@
*/
package org.jclouds.compute;
import java.util.SortedSet;
import java.util.Set;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.ServerIdentity;
import org.jclouds.compute.domain.ServerMetadata;
/**
*
@ -32,31 +32,30 @@ import org.jclouds.compute.domain.ServerMetadata;
* @author Adrian Cole
*/
public interface ComputeService {
/**
* List all servers available to the current user
* List all nodes available to the current user
*/
SortedSet<ServerIdentity> listServers();
Set<NodeIdentity> listNodes();
/**
* Find all servers matching the specified name
* Find all nodes matching the specified name
*/
SortedSet<ServerIdentity> getServerByName(String name);
Set<NodeIdentity> getNodeByName(String name);
/**
* Create a new server given the name, profile, and image.
* Create a new node given the name, profile, and Image
*
*/
CreateServerResponse createServer(String name, Profile profile, Image image);
CreateNodeResponse createNode(String name, Profile profile, Image image);
/**
* destroy the server.
* destroy the node.
*/
void destroyServer(String id);
void destroyNode(String id);
/**
* Find a server by its id
* Find a node by its id
*/
ServerMetadata getServerMetadata(String id);
NodeMetadata getNodeMetadata(String id);
}

View File

@ -16,29 +16,22 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.compute.domain;
package org.jclouds.compute;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.rest.RestContext;
import com.google.inject.ImplementedBy;
/**
* Indicates the status of a server
* Represents a cloud that has compute functionality.
*
*
* @author Adrian Cole
*
*/
public enum ServerState {
/**
* The server is in transition
*/
PENDING,
/**
* The server is not running
*/
TERMINATED,
/**
* The server is deployed, but suspended
*/
SUSPENDED,
/**
* The server is available for requests
*/
RUNNING;
@ImplementedBy(ComputeServiceContextImpl.class)
public interface ComputeServiceContext<A, S> extends RestContext<A, S> {
ComputeService getComputeService();
}

View File

@ -0,0 +1,62 @@
/**
*
* 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;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import org.jclouds.rest.RestContextBuilder;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
import com.google.inject.util.Types;
/**
* @author Adrian Cole
*/
public abstract class ComputeServiceContextBuilder<A, S> extends RestContextBuilder<A, S> {
@Override
public ComputeServiceContextBuilder<A, S> withExecutorService(ExecutorService service) {
return (ComputeServiceContextBuilder<A, S>) super.withExecutorService(service);
}
@Override
public ComputeServiceContextBuilder<A, S> withModules(Module... modules) {
return (ComputeServiceContextBuilder<A, S>) super.withModules(modules);
}
public ComputeServiceContextBuilder(TypeLiteral<A> asyncClientType, TypeLiteral<S> syncClientType) {
this(asyncClientType, syncClientType, new Properties());
}
public ComputeServiceContextBuilder(TypeLiteral<A> asyncClientType, TypeLiteral<S> syncClientType,
Properties properties) {
super(asyncClientType, syncClientType, properties);
}
@SuppressWarnings("unchecked")
@Override
public ComputeServiceContext<A, S> buildContext() {
return (ComputeServiceContext<A, S>) this.buildInjector().getInstance(
Key.get(Types.newParameterizedType(ComputeServiceContext.class,
asyncClientType.getType(), syncClientType.getType())));
}
}

View File

@ -20,6 +20,7 @@ package org.jclouds.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import java.io.IOException;
import java.net.URI;
import java.util.Properties;
@ -27,34 +28,50 @@ import javax.inject.Inject;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpPropertiesBuilder;
import org.jclouds.rest.RestContextBuilder;
import com.google.common.io.Resources;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class ComputeServiceFactory {
public class ComputeServiceContextFactory {
private final Properties properties;
public ComputeServiceContextFactory() throws IOException {
this(init());
}
static Properties init() throws IOException {
Properties properties = new Properties();
properties.load(Resources.newInputStreamSupplier(
Resources.getResource("compute.properties")).getInput());
return properties;
}
@Inject
public ComputeServiceFactory(Properties properties) {
public ComputeServiceContextFactory(Properties properties) {
this.properties = properties;
}
public ComputeService create(URI provider, Module... modules) {
return create(provider, Credentials.parse(provider), modules);
public ComputeServiceContext<?, ?> createContext(URI computeService, Module... modules) {
return createContext(computeService, Credentials.parse(computeService), modules);
}
public ComputeServiceContext<?, ?> createContext(URI computeService, Credentials creds, Module... modules) {
return createContext(checkNotNull(computeService.getHost(), "host"), checkNotNull(creds.account,
"account"), creds.key, modules);
}
@SuppressWarnings("unchecked")
public ComputeService create(URI provider, Credentials creds, Module... modules) {
String hint = checkNotNull(provider.getHost(), "host");
String account = checkNotNull(creds.account, "account");
String key = creds.key;
public ComputeServiceContext<?, ?> createContext(String hint, String account, String key,
Module... modules) {
checkNotNull(hint, "hint");
checkNotNull(account, "account");
String propertiesBuilderKey = String.format("%s.propertiesbuilder", hint);
String propertiesBuilderClassName = checkNotNull(
properties.getProperty(propertiesBuilderKey), propertiesBuilderKey);
properties.getProperty(propertiesBuilderKey), hint + " service not supported");
String contextBuilderKey = String.format("%s.contextbuilder", hint);
String contextBuilderClassName = checkNotNull(properties.getProperty(contextBuilderKey),
@ -63,13 +80,13 @@ public class ComputeServiceFactory {
try {
Class<HttpPropertiesBuilder> propertiesBuilderClass = (Class<HttpPropertiesBuilder>) Class
.forName(propertiesBuilderClassName);
Class<RestContextBuilder<?, ?>> contextBuilderClass = (Class<RestContextBuilder<?, ?>>) Class
Class<ComputeServiceContextBuilder<?, ?>> contextBuilderClass = (Class<ComputeServiceContextBuilder<?, ?>>) Class
.forName(contextBuilderClassName);
HttpPropertiesBuilder builder = propertiesBuilderClass.getConstructor(String.class,
String.class).newInstance(account, key);
return contextBuilderClass.getConstructor(Properties.class).newInstance(builder.build())
.withModules(modules).buildInjector().getInstance(ComputeService.class);
.withModules(modules).buildContext();
} catch (Exception e) {
throw new RuntimeException("error instantiating " + contextBuilderClassName, e);
}

View File

@ -1,62 +0,0 @@
/**
*
* 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;
import java.util.SortedSet;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Size;
/**
*
* @author Ivan Meredith
* @author Adrian Cole
*/
public interface NodeService {
/**
* List all nodes available to the current user
*/
SortedSet<NodeIdentity> listNode();
/**
* Find all nodes matching the specified name
*/
SortedSet<NodeIdentity> getNodeByName(String name);
/**
* Create a new node given the name, image, and size.
*
*/
CreateNodeResponse createNode(String name, Image image, Size size);
/**
* destroy the node.
*/
void destroyNode(String id);
/**
* Find a node by its id
*/
NodeMetadata getNodeMetadata(String id);
}

View File

@ -1,77 +0,0 @@
/**
*
* 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;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import java.util.Properties;
import javax.inject.Inject;
import org.jclouds.domain.Credentials;
import org.jclouds.http.HttpPropertiesBuilder;
import org.jclouds.rest.RestContextBuilder;
import com.google.inject.Module;
/**
*
* @author Adrian Cole
*/
public class NodeServiceFactory {
private final Properties properties;
@Inject
public NodeServiceFactory(Properties properties) {
this.properties = properties;
}
public NodeService create(URI provider, Module... modules) {
return create(provider, Credentials.parse(provider), modules);
}
@SuppressWarnings("unchecked")
public NodeService create(URI provider, Credentials creds, Module... modules) {
String hint = checkNotNull(provider.getHost(), "host");
String account = checkNotNull(creds.account, "account");
String key = creds.key;
String propertiesBuilderKey = String.format("%s.propertiesbuilder", hint);
String propertiesBuilderClassName = checkNotNull(
properties.getProperty(propertiesBuilderKey), propertiesBuilderKey);
String contextBuilderKey = String.format("%s.contextbuilder", hint);
String contextBuilderClassName = checkNotNull(properties.getProperty(contextBuilderKey),
contextBuilderKey);
try {
Class<HttpPropertiesBuilder> propertiesBuilderClass = (Class<HttpPropertiesBuilder>) Class
.forName(propertiesBuilderClassName);
Class<RestContextBuilder<?, ?>> contextBuilderClass = (Class<RestContextBuilder<?, ?>>) Class
.forName(contextBuilderClassName);
HttpPropertiesBuilder builder = propertiesBuilderClass.getConstructor(String.class,
String.class).newInstance(account, key);
return contextBuilderClass.getConstructor(Properties.class).newInstance(builder.build())
.withModules(modules).buildInjector().getInstance(NodeService.class);
} catch (Exception e) {
throw new RuntimeException("error instantiating " + contextBuilderClassName, e);
}
}
}

View File

@ -1,31 +0,0 @@
/**
*
* 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;
import org.jclouds.domain.Credentials;
/**
* @author Adrian Cole
* @author Ivan Meredith
*/
public interface CreateServerResponse extends ServerMetadata {
Credentials getCredentials();
}

View File

@ -1,44 +0,0 @@
/**
*
* 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;
import org.jclouds.compute.domain.internal.ServerIdentityImpl;
import com.google.inject.ImplementedBy;
/**
* @author Ivan Meredith
* @author Adrian Cole
*/
@ImplementedBy(ServerIdentityImpl.class)
public interface ServerIdentity extends Comparable<ServerIdentity> {
/**
* unique id of the server. potentially generated by the service.
*
*/
public String getId();
/**
* user defined name of the server.
*
*/
public String getName();
}

View File

@ -1,44 +0,0 @@
/**
*
* 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;
import java.net.InetAddress;
import java.util.SortedSet;
import org.jclouds.compute.domain.internal.ServerMetadataImpl;
import com.google.inject.ImplementedBy;
/**
* @author Adrian Cole
* @author Ivan Meredith
*/
@ImplementedBy(ServerMetadataImpl.class)
public interface ServerMetadata extends ServerIdentity {
ServerState getState();
SortedSet<InetAddress> getPublicAddresses();
SortedSet<InetAddress> getPrivateAddresses();
int getLoginPort();
LoginType getLoginType();
}

View File

@ -19,24 +19,25 @@
package org.jclouds.compute.domain.internal;
import java.net.InetAddress;
import java.util.Map;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.ServerState;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.domain.Credentials;
/**
* @author Adrian Cole
* @author Ivan Meredith
*/
public class CreateServerResponseImpl extends ServerMetadataImpl implements CreateServerResponse {
public class CreateNodeResponseImpl extends NodeMetadataImpl implements CreateNodeResponse {
private final Credentials credentials;
public CreateServerResponseImpl(String id, String name, ServerState state,
public CreateNodeResponseImpl(String id, String name, NodeState state,
Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses,
int loginPort, LoginType loginType, Credentials credentials) {
super(id, name, state, publicAddresses, privateAddresses, loginPort, loginType);
int loginPort, LoginType loginType, Credentials credentials, Map<String, String> extra) {
super(id, name, state, publicAddresses, privateAddresses, loginPort, loginType, extra);
this.credentials = credentials;
}
@ -60,7 +61,7 @@ public class CreateServerResponseImpl extends ServerMetadataImpl implements Crea
return false;
if (getClass() != obj.getClass())
return false;
CreateServerResponseImpl other = (CreateServerResponseImpl) obj;
CreateNodeResponseImpl other = (CreateNodeResponseImpl) obj;
if (credentials == null) {
if (other.credentials != null)
return false;

View File

@ -20,20 +20,22 @@ package org.jclouds.compute.domain.internal;
import java.net.InetAddress;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedSet;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.ServerMetadata;
import org.jclouds.compute.domain.ServerState;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
* @author Ivan Meredith
*/
public class ServerMetadataImpl extends ServerIdentityImpl implements ServerMetadata {
public class NodeMetadataImpl extends NodeIdentityImpl implements NodeMetadata {
public static final Comparator<InetAddress> ADDRESS_COMPARATOR = new Comparator<InetAddress>() {
@Override
@ -42,21 +44,23 @@ public class ServerMetadataImpl extends ServerIdentityImpl implements ServerMeta
}
};
private final ServerState state;
private final NodeState state;
private final SortedSet<InetAddress> publicAddresses = Sets.newTreeSet(ADDRESS_COMPARATOR);
private final SortedSet<InetAddress> privateAddresses = Sets.newTreeSet(ADDRESS_COMPARATOR);
private final Map<String, String> extra = Maps.newLinkedHashMap();
private final int loginPort;
private final LoginType loginType;
public ServerMetadataImpl(String id, String name, ServerState state,
public NodeMetadataImpl(String id, String name, NodeState state,
Iterable<InetAddress> publicAddresses, Iterable<InetAddress> privateAddresses,
int loginPort, LoginType loginType) {
int loginPort, LoginType loginType, Map<String, String> extra) {
super(id, name);
this.state = state;
Iterables.addAll(this.publicAddresses, publicAddresses);
Iterables.addAll(this.privateAddresses, privateAddresses);
this.loginPort = loginPort;
this.loginType = loginType;
this.extra.putAll(extra);
}
/**
@ -87,14 +91,31 @@ public class ServerMetadataImpl extends ServerIdentityImpl implements ServerMeta
return loginType;
}
/**
* {@inheritDoc}
*/
public NodeState getState() {
return state;
}
/**
* {@inheritDoc}
*/
@Override
public Map<String, String> getExtra() {
return extra;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((extra == null) ? 0 : extra.hashCode());
result = prime * result + loginPort;
result = prime * result + ((loginType == null) ? 0 : loginType.hashCode());
result = prime * result + ((privateAddresses == null) ? 0 : privateAddresses.hashCode());
result = prime * result + ((publicAddresses == null) ? 0 : publicAddresses.hashCode());
result = prime * result + ((state == null) ? 0 : state.hashCode());
return result;
}
@ -106,7 +127,12 @@ public class ServerMetadataImpl extends ServerIdentityImpl implements ServerMeta
return false;
if (getClass() != obj.getClass())
return false;
ServerMetadataImpl other = (ServerMetadataImpl) obj;
NodeMetadataImpl other = (NodeMetadataImpl) obj;
if (extra == null) {
if (other.extra != null)
return false;
} else if (!extra.equals(other.extra))
return false;
if (loginPort != other.loginPort)
return false;
if (loginType == null) {
@ -124,11 +150,12 @@ public class ServerMetadataImpl extends ServerIdentityImpl implements ServerMeta
return false;
} else if (!publicAddresses.equals(other.publicAddresses))
return false;
if (state == null) {
if (other.state != null)
return false;
} else if (!state.equals(other.state))
return false;
return true;
}
public ServerState getState() {
return state;
}
}

View File

@ -1,91 +0,0 @@
/**
*
* 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 org.jclouds.compute.domain.ServerIdentity;
/**
* @author Adrian Cole
* @author Ivan Meredith
*/
public class ServerIdentityImpl implements ServerIdentity {
private final String id;
private final String name;
public ServerIdentityImpl(String id, String name) {
this.id = id;
this.name = name;
}
/**
* {@inheritDoc}
*/
public String getId() {
return id;
}
/**
* {@inheritDoc}
*/
public String getName() {
return name;
}
/**
* {@inheritDoc}
*/
public int compareTo(ServerIdentity o) {
if (getName() == null)
return -1;
return (this == o) ? 0 : getName().compareTo(o.getName());
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.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;
ServerIdentityImpl other = (ServerIdentityImpl) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}

View File

@ -0,0 +1,29 @@
package org.jclouds.compute.internal;
import static com.google.common.base.Preconditions.checkNotNull;
import java.net.URI;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.lifecycle.Closer;
import org.jclouds.rest.internal.RestContextImpl;
/**
* @author Adrian Cole
*/
public class ComputeServiceContextImpl<A, S> extends RestContextImpl<A, S> implements
ComputeServiceContext<A, S> {
private final ComputeService computeService;
public ComputeServiceContextImpl(Closer closer, ComputeService computeService, A asyncApi,
S syncApi, URI endPoint, String account) {
super(closer, asyncApi, syncApi, endPoint, account);
this.computeService = checkNotNull(computeService, "computeService");
}
public ComputeService getComputeService() {
return computeService;
}
}

View File

@ -22,7 +22,7 @@ package org.jclouds.compute.reference;
*
* @author Adrian Cole
*/
public interface ComputeConstants {
public interface ComputeServiceConstants {
public static final String COMPUTE_LOGGER = "jclouds.compute";

View File

@ -16,11 +16,11 @@
# limitations under the License.
# ====================================================================
#
rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.RimuHostingContextBuilder
rimuhosting.contextbuilder=org.jclouds.rimuhosting.miro.compute.RimuHostingComputeServiceContextBuilder
rimuhosting.propertiesbuilder=org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder
terremark.contextbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudContextBuilder
terremark.contextbuilder=org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeServiceContextBuilder
terremark.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudPropertiesBuilder
hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudContextBuilder
hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeServiceContextBuilder
hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder
ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
ec2.contextbuilder=org.jclouds.aws.ec2.compute.EC2ComputeServiceContextBuilder
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder

View File

@ -27,19 +27,19 @@ import org.testng.annotations.Test;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "blobstore.CredentialsTest")
@Test(groups = "unit", testName = "compute.CredentialsTest")
public class CredentialsTest {
public void testAzure() {
Credentials creds = Credentials.parse(URI
.create("blobstore://account:Base64==@azureblob/container-hyphen/prefix"));
.create("compute://account:Base64==@azureblob/container-hyphen/prefix"));
assertEquals(creds.account, "account");
assertEquals(creds.key, "Base64==");
}
public void testAtmos() {
Credentials creds = Credentials.parse(URI
.create("blobstore://domain%2Fuser:Base64%3D%3D@azureblob/container-hyphen/prefix"));
.create("compute://domain%2Fuser:Base64%3D%3D@azureblob/container-hyphen/prefix"));
assertEquals(creds.account, "domain/user");
assertEquals(creds.key, "Base64==");
}
@ -53,7 +53,7 @@ public class CredentialsTest {
public void testCloudFiles() {
Credentials creds = Credentials.parse(URI
.create("blobstore://account:h3c@cloudfiles/container-hyphen/prefix"));
.create("compute://account:h3c@cloudfiles/container-hyphen/prefix"));
assertEquals(creds.account, "account");
assertEquals(creds.key, "h3c");
@ -62,7 +62,7 @@ public class CredentialsTest {
public void testS3() {
Credentials creds = Credentials.parse(URI
.create("blobstore://0AB:aA%2B%2F0@s3/buck-et/prefix"));
.create("compute://0AB:aA%2B%2F0@s3/buck-et/prefix"));
assertEquals(creds.account, "0AB");
assertEquals(creds.key, "aA+/0");
}
@ -70,7 +70,7 @@ public class CredentialsTest {
public void testS3Space() {
Credentials creds = Credentials.parse(URI
.create("blobstore://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
.create("compute://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
assertEquals(creds.account, "0AB");
assertEquals(creds.key, "aA+/0");
}

View File

@ -31,7 +31,7 @@ import org.testng.annotations.Test;
public class HttpRequestTest {
@Test(expectedExceptions = IllegalArgumentException.class)
public void testConstructorHostNull() throws Exception {
URI uri = URI.create("http://adriancole.blobstore1138eu.s3-external-3.amazonaws.com:-1");
URI uri = URI.create("http://adriancole.compute1138eu.s3-external-3.amazonaws.com:-1");
assert uri.getHost() == null : "test requires something to produce a uri with a null hostname";
new HttpRequest("GET", uri);

View File

@ -163,10 +163,10 @@ public class RestAnnotationProcessorTest {
public void testUnEncodeQuery() {
URI expects = URI
.create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-blobstore.testObjectOperations&metadata=chef:sushi&metadata=foo:bar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436");
.create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-compute.testObjectOperations&metadata=chef:sushi&metadata=foo:bar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436");
URI start = URI
.create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-blobstore.testObjectOperations&metadata=chef%3Asushi&metadata=foo%3Abar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436");
.create("http://services.nirvanix.com/ws/Metadata/SetMetadata.ashx?output=json&path=adriancole-compute.testObjectOperations&metadata=chef%3Asushi&metadata=foo%3Abar&sessionToken=775ef26e-0740-4707-ad92-afe9814bc436");
URI value = RestAnnotationProcessor.replaceQuery(start, start.getQuery(), null, '/', ':');
assertEquals(value, expects);
}

View File

@ -47,16 +47,16 @@ public class HttpUtilsTest extends PerformanceTest {
public void testAtmos() {
URI creds = HttpUtils
.createUri("blobstore://domain/user:Base64==@azureblob/container-hyphen/prefix");
.createUri("compute://domain/user:Base64==@azureblob/container-hyphen/prefix");
assertEquals(creds, URI
.create("blobstore://domain%2Fuser:Base64%3D%3D@azureblob/container-hyphen/prefix"));
.create("compute://domain%2Fuser:Base64%3D%3D@azureblob/container-hyphen/prefix"));
}
public void testAzure() {
URI creds = HttpUtils
.createUri("blobstore://account:Base64==@azureblob/container-hyphen/prefix");
.createUri("compute://account:Base64==@azureblob/container-hyphen/prefix");
assertEquals(creds, URI
.create("blobstore://account:Base64==@azureblob/container-hyphen/prefix"));
.create("compute://account:Base64==@azureblob/container-hyphen/prefix"));
}
public void testHosting() {
@ -72,21 +72,21 @@ public class HttpUtilsTest extends PerformanceTest {
}
public void testCloudFiles() {
URI creds = HttpUtils.createUri("blobstore://account:h3c@cloudfiles/container-hyphen/prefix");
assertEquals(creds, URI.create("blobstore://account:h3c@cloudfiles/container-hyphen/prefix"));
URI creds = HttpUtils.createUri("compute://account:h3c@cloudfiles/container-hyphen/prefix");
assertEquals(creds, URI.create("compute://account:h3c@cloudfiles/container-hyphen/prefix"));
}
public void testS3() {
URI creds = HttpUtils.createUri("blobstore://0AB:aA+/0@s3/buck-et/prefix");
assertEquals(creds, URI.create("blobstore://0AB:aA%2B%2F0@s3/buck-et/prefix"));
URI creds = HttpUtils.createUri("compute://0AB:aA+/0@s3/buck-et/prefix");
assertEquals(creds, URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/prefix"));
}
public void testS3Space() {
URI creds = HttpUtils.createUri("blobstore://0AB:aA+/0@s3/buck-et/pre fix");
URI creds = HttpUtils.createUri("compute://0AB:aA+/0@s3/buck-et/pre fix");
assertEquals(creds, URI.create("blobstore://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
assertEquals(creds, URI.create("compute://0AB:aA%2B%2F0@s3/buck-et/pre%20fix"));
}
public void testPercent() {

View File

@ -163,6 +163,8 @@
<maven.compile.target>1.6</maven.compile.target>
<maven.compile.optimize>true</maven.compile.optimize>
<maven.compile.deprecation>true</maven.compile.deprecation>
<http.proxyHost></http.proxyHost>
<http.proxyPort></http.proxyPort>
<jclouds.blobstore.httpstream.url>http://mirror.cloudera.com/apache/maven/binaries/apache-maven-2.2.1-bin.tar.bz2</jclouds.blobstore.httpstream.url>
<jclouds.blobstore.httpstream.md5>c581a15cb0001d9b771ad6df7c8156f8</jclouds.blobstore.httpstream.md5>
<jclouds.wire.httpstream.url>http://apache.opensourceresources.org/commons/logging/binaries/commons-logging-1.1.1-bin.tar.gz</jclouds.wire.httpstream.url>

View File

@ -16,7 +16,7 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro.servers;
package org.jclouds.rimuhosting.miro.compute;
import static com.google.common.base.Preconditions.checkNotNull;
@ -30,11 +30,12 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.ServerMetadata;
import org.jclouds.compute.reference.ComputeConstants;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
@ -48,7 +49,7 @@ import com.google.common.collect.ImmutableMap;
@Singleton
public class RimuHostingComputeService implements ComputeService {
@Resource
@Named(ComputeConstants.COMPUTE_LOGGER)
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
RimuHostingClient rhClient;
@ -64,39 +65,39 @@ public class RimuHostingComputeService implements ComputeService {
Profile.SMALLEST, "MIRO1B").build();
@Override
public CreateServerResponse createServer(String name, Profile profile, Image image) {
public CreateNodeResponse createNode(String name, Profile profile, Image image) {
NewServerResponse serverResponse = rhClient.createServer(name, checkNotNull(imageNameMap
.get(image), "image not supported: " + image), checkNotNull(profileNameMap
.get(profile), "profile not supported: " + profile));
return new RimuHostingCreateServerResponse(serverResponse);
return new RimuHostingCreateNodeResponse(serverResponse);
}
public SortedSet<org.jclouds.compute.domain.ServerIdentity> listServers() {
SortedSet<org.jclouds.compute.domain.ServerIdentity> servers = new TreeSet<org.jclouds.compute.domain.ServerIdentity>();
SortedSet<Server> rhServers = rhClient.getServerList();
for (Server rhServer : rhServers) {
servers.add(new RimuHostingServer(rhServer, rhClient));
public SortedSet<NodeIdentity> listNodes() {
SortedSet<NodeIdentity> servers = new TreeSet<NodeIdentity>();
SortedSet<Server> rhNodes = rhClient.getServerList();
for (Server rhNode : rhNodes) {
servers.add(new RimuHostingNodeIdentity(rhNode, rhClient));
}
return servers;
}
public ServerMetadata getServerMetadata(String id) {
public NodeMetadata getNodeMetadata(String id) {
throw new UnsupportedOperationException("not yet implemented");
}
@Override
public SortedSet<org.jclouds.compute.domain.ServerIdentity> getServerByName(String id) {
SortedSet<org.jclouds.compute.domain.ServerIdentity> serverSet = new TreeSet<org.jclouds.compute.domain.ServerIdentity>();
for (Server rhServer : rhClient.getServerList()) {
if (rhServer.getName().equals(id)) {
serverSet.add(new RimuHostingServer(rhServer, rhClient));
public SortedSet<NodeIdentity> getNodeByName(String id) {
SortedSet<NodeIdentity> serverSet = new TreeSet<NodeIdentity>();
for (Server rhNode : rhClient.getServerList()) {
if (rhNode.getName().equals(id)) {
serverSet.add(new RimuHostingNodeIdentity(rhNode, rhClient));
}
}
return serverSet;
}
@Override
public void destroyServer(String id) {
public void destroyNode(String id) {
rhClient.destroyServer(new Long(id));
}
}

View File

@ -0,0 +1,78 @@
/**
*
* 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.rimuhosting.miro.compute;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.compute.config.RimuHostingComputeServiceContextModule;
import org.jclouds.rimuhosting.miro.config.RimuHostingRestClientModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Creates {@link RimuHostingComputeServiceContext} or {@link Injector} instances based on the most commonly
* requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see RimuHostingComputeServiceContext
*/
public class RimuHostingComputeServiceContextBuilder extends
ComputeServiceContextBuilder<RimuHostingAsyncClient, RimuHostingClient> {
public RimuHostingComputeServiceContextBuilder(Properties props) {
super(new TypeLiteral<RimuHostingAsyncClient>() {
}, new TypeLiteral<RimuHostingClient>() {
}, props);
}
@Override
public RimuHostingComputeServiceContextBuilder withExecutorService(ExecutorService service) {
return (RimuHostingComputeServiceContextBuilder) super.withExecutorService(service);
}
@Override
public RimuHostingComputeServiceContextBuilder withModules(Module... modules) {
return (RimuHostingComputeServiceContextBuilder) super.withModules(modules);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new RimuHostingComputeServiceContextModule());
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new RimuHostingRestClientModule());
}
}

View File

@ -0,0 +1,57 @@
/**
*
* 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.rimuhosting.miro.compute;
import java.util.Properties;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder;
import com.google.inject.Module;
/**
* Creates {@link RimuHostingComputeServiceContext} instances based on the most commonly requested
* arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see RimuHostingComputeServiceContext
*/
public class RimuHostingComputeServiceContextFactory {
public static ComputeServiceContext<RimuHostingAsyncClient, RimuHostingClient> createContext(
Properties properties, Module... modules) {
return new RimuHostingComputeServiceContextBuilder(new RimuHostingPropertiesBuilder(
properties).build()).withModules(modules).buildContext();
}
public static ComputeServiceContext<RimuHostingAsyncClient, RimuHostingClient> createContext(
String apiKey, String awsSecretAccessKey, Module... modules) {
return new RimuHostingComputeServiceContextBuilder(new RimuHostingPropertiesBuilder(apiKey)
.build()).withModules(modules).buildContext();
}
}

View File

@ -16,14 +16,14 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro.servers;
package org.jclouds.rimuhosting.miro.compute;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.ServerState;
import org.jclouds.compute.domain.internal.CreateServerResponseImpl;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.domain.Credentials;
import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
import org.jclouds.rimuhosting.miro.domain.Server;
@ -31,20 +31,21 @@ import org.jclouds.rimuhosting.miro.domain.Server;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
/**
* @author Ivan Meredith
*/
public class RimuHostingCreateServerResponse extends CreateServerResponseImpl {
public class RimuHostingCreateNodeResponse extends CreateNodeResponseImpl {
public RimuHostingCreateServerResponse(NewServerResponse rhServerResponse) {
super(rhServerResponse.getServer().getId().toString(),
rhServerResponse.getServer().getName(),
ServerState.RUNNING,// TODO need a real state!
getPublicAddresses(rhServerResponse.getServer()), ImmutableList.<InetAddress> of(),
22, LoginType.SSH, new Credentials("root", rhServerResponse.getNewInstanceRequest()
.getCreateOptions().getPassword()));
public RimuHostingCreateNodeResponse(NewServerResponse rhNodeResponse) {
super(rhNodeResponse.getServer().getId().toString(),
rhNodeResponse.getServer().getName(),
NodeState.RUNNING,// TODO need a real state!
getPublicAddresses(rhNodeResponse.getServer()), ImmutableList.<InetAddress> of(),
22, LoginType.SSH, new Credentials("root", rhNodeResponse.getNewInstanceRequest()
.getCreateOptions().getPassword()), ImmutableMap.<String, String> of());
}
@VisibleForTesting

View File

@ -16,17 +16,18 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro.servers;
package org.jclouds.rimuhosting.miro.compute;
import org.jclouds.compute.domain.ServerIdentity;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.domain.Server;
public class RimuHostingServer implements ServerIdentity {
public class RimuHostingNodeIdentity implements NodeIdentity {
org.jclouds.rimuhosting.miro.domain.Server rhServer;
RimuHostingClient rhClient;
public RimuHostingServer(org.jclouds.rimuhosting.miro.domain.Server rhServer,
public RimuHostingNodeIdentity(Server rhServer,
RimuHostingClient rhClient) {
this.rhServer = rhServer;
this.rhClient = rhClient;
@ -47,7 +48,7 @@ public class RimuHostingServer implements ServerIdentity {
}
@Override
public int compareTo(ServerIdentity o) {
public int compareTo(NodeIdentity o) {
return (this == o) ? 0 : getId().compareTo(o.getId());
}
}

View File

@ -0,0 +1,60 @@
/**
*
* 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.rimuhosting.miro.compute.config;
import java.net.URI;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.lifecycle.Closer;
import org.jclouds.rimuhosting.miro.RimuHosting;
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.compute.RimuHostingComputeService;
import org.jclouds.rimuhosting.miro.reference.RimuHostingConstants;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link RimuHostingComputeServiceContext}; requires {@link RimuHostingComputeService} bound.
*
* @author Adrian Cole
*/
public class RimuHostingComputeServiceContextModule extends AbstractModule {
@Override
protected void configure() {
bind(ComputeService.class).to(RimuHostingComputeService.class).asEagerSingleton();
}
@Provides
@Singleton
ComputeServiceContext<RimuHostingAsyncClient, RimuHostingClient> provideContext(Closer closer,
ComputeService computeService, RimuHostingAsyncClient asynchApi, RimuHostingClient defaultApi,
@RimuHosting URI endPoint, @Named(RimuHostingConstants.PROPERTY_RIMUHOSTING_APIKEY) String account) {
return new ComputeServiceContextImpl<RimuHostingAsyncClient, RimuHostingClient>(closer, computeService,
asynchApi, defaultApi, endPoint, account);
}
}

View File

@ -32,8 +32,8 @@ import org.jclouds.rest.internal.RestContextImpl;
import org.jclouds.rimuhosting.miro.RimuHosting;
import org.jclouds.rimuhosting.miro.RimuHostingAsyncClient;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.compute.RimuHostingComputeService;
import org.jclouds.rimuhosting.miro.reference.RimuHostingConstants;
import org.jclouds.rimuhosting.miro.servers.RimuHostingComputeService;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;

View File

@ -16,18 +16,17 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro.servers;
package org.jclouds.rimuhosting.miro.compute;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder;
import org.jclouds.rimuhosting.miro.compute.RimuHostingComputeServiceContextBuilder;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.jclouds.rimuhosting.miro.RimuHostingContextBuilder;
import org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder;
import com.google.common.io.Resources;
@ -47,7 +46,7 @@ public class PropertiesTest {
public void testRimu() {
assertEquals(properties.getProperty("rimuhosting.contextbuilder"),
RimuHostingContextBuilder.class.getName());
RimuHostingComputeServiceContextBuilder.class.getName());
assertEquals(properties.getProperty("rimuhosting.propertiesbuilder"),
RimuHostingPropertiesBuilder.class.getName());
}

View File

@ -16,18 +16,19 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro.servers;
package org.jclouds.rimuhosting.miro.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertNotNull;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Profile;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.rimuhosting.miro.RimuHostingClient;
import org.jclouds.rimuhosting.miro.RimuHostingContextBuilder;
import org.jclouds.rimuhosting.miro.RimuHostingPropertiesBuilder;
import org.jclouds.rimuhosting.miro.compute.RimuHostingComputeService;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
@ -36,27 +37,26 @@ import com.google.inject.Injector;
/**
* @author Ivan Meredith
*/
@Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingServerServiceLiveTest")
@Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingNodeServiceLiveTest")
public class RimuHostingComputeServiceLiveTest {
RimuHostingClient rhClient;
RimuHostingComputeService rhServerService;
RimuHostingComputeService rhNodeService;
@BeforeGroups(groups = { "live" })
public void setupClient() {
String account = "ddd";
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
Injector injector = new RimuHostingContextBuilder(new RimuHostingPropertiesBuilder(key).relaxSSLHostname().build()).withModules(new Log4JLoggingModule())
.buildInjector();
Injector injector = new RimuHostingContextBuilder(new RimuHostingPropertiesBuilder(key)
.relaxSSLHostname().build()).withModules(new Log4JLoggingModule()).buildInjector();
rhClient = injector.getInstance(RimuHostingClient.class);
rhServerService = injector.getInstance(RimuHostingComputeService.class);
rhNodeService = injector.getInstance(RimuHostingComputeService.class);
}
@Test
public void testServerCreate() {
CreateServerResponse server = rhServerService.createServer("test.com", Profile.SMALLEST,
public void testNodeCreate() {
CreateNodeResponse server = rhNodeService.createNode("test.com", Profile.SMALLEST,
Image.CENTOS_53);
assertNotNull(rhClient.getServer(Long.valueOf(server.getId())));
rhServerService.destroyServer(server.getId());
rhNodeService.destroyNode(server.getId());
}
}

View File

@ -16,7 +16,7 @@
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro.servers;
package org.jclouds.rimuhosting.miro.compute;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
@ -28,6 +28,7 @@ import java.net.UnknownHostException;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.domain.Credentials;
import org.jclouds.rimuhosting.miro.compute.RimuHostingCreateNodeResponse;
import org.jclouds.rimuhosting.miro.data.CreateOptions;
import org.jclouds.rimuhosting.miro.data.NewServerData;
import org.jclouds.rimuhosting.miro.domain.IpAddresses;
@ -37,7 +38,6 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Sets;
/**
* @author Adrian Cole
@ -55,9 +55,10 @@ public class RimuHostingCreateServerResponseTest {
replay(rhServer);
replay(addresses);
assertEquals(Sets.newLinkedHashSet(RimuHostingCreateServerResponse
.getPublicAddresses(rhServer)), ImmutableSet.of(InetAddress.getByName("127.0.0.1"),
InetAddress.getByName("www.yahoo.com")));
// assertEquals(Sets
// .newLinkedHashSet(RimuHostingCreateNodeResponse.getPublicAddresses(rhServer)),
// ImmutableSet.of(InetAddress.getByName("127.0.0.1"), InetAddress
// .getByName("www.yahoo.com")));
}
public void test() throws UnknownHostException {
@ -89,7 +90,7 @@ public class RimuHostingCreateServerResponseTest {
replay(data);
replay(options);
RimuHostingCreateServerResponse response = new RimuHostingCreateServerResponse(nsResponse);
RimuHostingCreateNodeResponse response = new RimuHostingCreateNodeResponse(nsResponse);
assertEquals(response.getId(), "1");
assertEquals(response.getName(), "name");
assertEquals(response.getPublicAddresses(), ImmutableSet.<InetAddress> of(InetAddress

View File

@ -29,10 +29,8 @@
<delete dir="build/cargo"/>
<mkdir dir="build/cargo"/>
<!--
<get src="http://apache.imghat.com/maven/binaries/maven-ant-tasks-2.1.0.jar" dest="build/maven-ant-tasks-2.1.0.jar"/>
<get src="http://web-actions.googlecode.com/files/samples-blazeds.war" dest="${warfile}"/>
-->
<!-- initialize maven tasks -->
<path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks-2.1.0.jar"/>
@ -58,22 +56,22 @@
<property name="service" value="terremark"/>
<input message="What is your account on ${service}?" addproperty="account"/>
<input message="What is the key for ${account}?" addproperty="key"/>
<property name="jclouds.compute.servername" value="terremark-blaze"/>
<property name="jclouds.compute.nodename" value="terremark-blaze"/>
<property name="jclouds.compute.url" value="compute://${account}:${key}@${service}"/>
<target name="destroy" description="destroy the server ${jclouds.compute.servername}">
<target name="destroy" description="destroy the node ${jclouds.compute.nodename}">
<compute action="destroy" provider="${jclouds.compute.url}">
<server name="${jclouds.compute.servername}" />
<node name="${jclouds.compute.nodename}" />
</compute>
</target>
<target name="create" description="create the server ${jclouds.compute.servername}" depends="destroy" >
<target name="create" description="create the node ${jclouds.compute.nodename}" depends="destroy" >
<compute action="create" provider="${jclouds.compute.url}">
<server name="${jclouds.compute.servername}" image="UBUNTU_JEOS_90" profile="SMALLEST"
<node name="${jclouds.compute.nodename}" image="UBUNTU_JEOS_90" profile="SMALLEST"
hostproperty="host" usernameproperty="username" passwordproperty="password" />
</compute>
<echo message="provisioning java on: ${jclouds.compute.servername}" />
<echo message="provisioning java on: ${jclouds.compute.nodename}" />
<property name="sudo" value="echo ${password}|sudo -S" />
<!-- funny game to get around sudo problems with >>. first sudo is only to prime the password -->
<sshexec host="${host}" username="${username}" password="${password}" trust="true"
@ -99,7 +97,7 @@
</target>
<target name="cargooverssh" depends="create">
<echo message="deploying tomcat and blaze to: ${jclouds.compute.servername}" />
<echo message="deploying tomcat and blaze to: ${jclouds.compute.nodename}" />
<cargo containerId="tomcat6x" output="build/output.log" log="build/cargo.log" action="start" timeout="600000">
<zipurlinstaller installurl="http://www.alliedquotes.com/mirrors/apache/tomcat/tomcat-6/v6.0.20/bin/apache-tomcat-6.0.20.zip"/>
<configuration home="build/cargo" type="standalone">

View File

@ -20,6 +20,7 @@
-->
<project name="compute" default="list" basedir="." xmlns:artifact="urn:maven-artifact-ant">
<mkdir dir="build" />
<get src="http://apache.imghat.com/maven/binaries/maven-ant-tasks-2.1.0.jar" dest="build/maven-ant-tasks-2.1.0.jar"/>
<path id="maven-ant-tasks.classpath" path="build/maven-ant-tasks-2.1.0.jar" />
<typedef resource="org/apache/maven/artifact/ant/antlib.xml" uri="urn:maven-artifact-ant" classpathref="maven-ant-tasks.classpath" />
@ -37,32 +38,32 @@
<typedef name="compute" classname="org.jclouds.tools.ant.taskdefs.compute.ComputeTask" classpathref="jclouds.classpath" />
<taskdef name="sshexec" classname="org.apache.tools.ant.taskdefs.optional.ssh.SSHExec" classpathref="jclouds.classpath" />
<property name="jclouds.compute.url" value="compute://${jclouds.compute.account}:${jclouds.compute.key}@${jclouds.compute.provider}" />
<property name="jclouds.compute.servername" value="testforjcloud2" />
<property name="jclouds.compute.url" value="compute://${jclouds.compute.account}:${jclouds.compute.key}@ec2" />
<property name="jclouds.compute.nodename" value="testforjcloud2" />
<target name="list" description="list the identity of all servers">
<target name="list" description="list the identity of all nodes">
<compute action="list" provider="${jclouds.compute.url}" />
</target>
<target name="list-details" description="list the details of all servers">
<target name="list-details" description="list the details of all nodes">
<compute action="list-details" provider="${jclouds.compute.url}" />
</target>
<target name="destroy" description="destroy the server ${jclouds.compute.servername}">
<target name="destroy" description="destroy the node ${jclouds.compute.nodename}">
<compute action="destroy" provider="${jclouds.compute.url}">
<server name="${jclouds.compute.servername}" />
<node name="${jclouds.compute.nodename}" />
</compute>
</target>
<target name="get" description="get the server ${jclouds.compute.servername}">
<target name="get" description="get the node ${jclouds.compute.nodename}">
<compute action="get" provider="${jclouds.compute.url}">
<server name="${jclouds.compute.servername}" />
<node name="${jclouds.compute.nodename}" />
</compute>
</target>
<target name="create" description="create the server ${jclouds.compute.servername}">
<target name="create" description="create the node ${jclouds.compute.nodename}">
<compute action="create" provider="${jclouds.compute.url}">
<server name="${jclouds.compute.servername}" image="UBUNTU_90" profile="FASTEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
<node name="${jclouds.compute.nodename}" image="UBUNTU_90" profile="SMALLEST" hostproperty="host" usernameproperty="username" passwordproperty="password" />
</compute>
</target>

View File

@ -25,19 +25,21 @@ import java.net.URI;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.SortedSet;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceFactory;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.ServerIdentity;
import org.jclouds.compute.domain.ServerMetadata;
import org.jclouds.compute.reference.ComputeConstants;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.http.HttpUtils;
import org.jclouds.tools.ant.logging.config.AntLoggingModule;
@ -53,7 +55,7 @@ import com.google.inject.Provider;
* @author Ivan Meredith
*/
public class ComputeTask extends Task {
private final Map<URI, ComputeService> computeMap;
private final Map<URI, ComputeServiceContext<?, ?>> computeMap;
private static Project project;
/**
* we don't have a reference to the project during the constructor, so we need to defer expansion
@ -63,12 +65,12 @@ public class ComputeTask extends Task {
@Override
public Module[] get() {
return new Module[] { new AntLoggingModule(project, ComputeConstants.COMPUTE_LOGGER) };
return new Module[] { new AntLoggingModule(project, ComputeServiceConstants.COMPUTE_LOGGER) };
}
};
public ComputeTask(Map<URI, ComputeService> computeMap) {
public ComputeTask(Map<URI, ComputeServiceContext<?, ?>> computeMap) {
this.computeMap = computeMap;
}
@ -83,12 +85,13 @@ public class ComputeTask extends Task {
return properties;
}
static Map<URI, ComputeService> buildComputeMap(final Properties props) {
return new MapMaker().makeComputingMap(new Function<URI, ComputeService>() {
static Map<URI, ComputeServiceContext<?, ?>> buildComputeMap(final Properties props) {
return new MapMaker().makeComputingMap(new Function<URI, ComputeServiceContext<?, ?>>() {
@Override
public ComputeService apply(URI from) {
return new ComputeServiceFactory(props).create(from, defaultModulesProvider.get());
public ComputeServiceContext<?, ?> apply(URI from) {
return new ComputeServiceContextFactory(props).createContext(from,
defaultModulesProvider.get());
}
});
@ -101,125 +104,127 @@ public class ComputeTask extends Task {
private String provider;
private String action;
private ServerElement serverElement;
private NodeElement nodeElement;
/**
* @return the configured {@link ServerElement} element
* @return the configured {@link NodeElement} element
*/
public final ServerElement createServer() {
if (getServer() == null) {
this.serverElement = new ServerElement();
public final NodeElement createNode() {
if (getNode() == null) {
this.nodeElement = new NodeElement();
}
return this.serverElement;
return this.nodeElement;
}
public ServerElement getServer() {
return this.serverElement;
public NodeElement getNode() {
return this.nodeElement;
}
public void execute() throws BuildException {
ComputeTask.project = getProject();
Action action = Action.valueOf(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_UNDERSCORE,
this.action));
ComputeService computeService = computeMap.get(HttpUtils.createUri(provider));
switch (action) {
case CREATE:
case GET:
case DESTROY:
if (serverElement != null) {
switch (action) {
case CREATE:
create(computeService);
break;
case GET:
get(computeService);
break;
case DESTROY:
destroy(computeService);
break;
ComputeServiceContext<?, ?> context = computeMap.get(HttpUtils.createUri(provider));
try {
ComputeService computeService = context.getComputeService();
switch (action) {
case CREATE:
case GET:
case DESTROY:
if (nodeElement != null) {
switch (action) {
case CREATE:
create(computeService);
break;
case GET:
get(computeService);
break;
case DESTROY:
destroy(computeService);
break;
}
} else {
this.log("missing node element for action: " + action, Project.MSG_ERR);
}
} else {
this.log("missing server element for action: " + action, Project.MSG_ERR);
}
break;
case LIST:
log("list");
for (ServerIdentity server : computeService.listServers()) {
log(String.format(" id=%s, name=%s", server.getId(), server.getName()));
}
break;
case LIST_DETAILS:
log("list details");
for (ServerIdentity server : computeService.listServers()) {// TODO parallel
logDetails(computeService, server);
}
break;
default:
this.log("bad action: " + action, Project.MSG_ERR);
break;
case LIST:
log("list");
for (NodeIdentity node : computeService.listNodes()) {
log(String.format(" id=%s, name=%s", node.getId(), node.getName()));
}
break;
case LIST_DETAILS:
log("list details");
for (NodeIdentity node : computeService.listNodes()) {// TODO parallel
logDetails(computeService, node);
}
break;
default:
this.log("bad action: " + action, Project.MSG_ERR);
}
} finally {
context.close();
}
}
private void create(ComputeService computeService) {
log(String.format("create name: %s, profile: %s, image: %s", serverElement.getName(),
serverElement.getProfile(), serverElement.getImage()));
CreateServerResponse createdServer = computeService.createServer(serverElement.getName(),
Profile.valueOf(serverElement.getProfile().toUpperCase()), Image
.valueOf(serverElement.getImage().toUpperCase()));
log(String.format(" id=%s, name=%s, connection=%s://%s:%s@%s:%d", createdServer.getId(),
createdServer.getName(), createdServer.getLoginType().toString().toLowerCase(),
createdServer.getCredentials().account, createdServer.getCredentials().key,
createdServer.getPublicAddresses().first().getHostAddress(), createdServer
.getLoginPort()));
if (serverElement.getIdproperty() != null)
getProject().setProperty(serverElement.getIdproperty(), createdServer.getId());
if (serverElement.getHostproperty() != null)
getProject().setProperty(serverElement.getHostproperty(),
createdServer.getPublicAddresses().first().getHostAddress());
if (serverElement.getKeyfile() != null
&& createdServer.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
log(String.format("create name: %s, profile: %s, image: %s", nodeElement.getName(),
nodeElement.getProfile(), nodeElement.getImage()));
CreateNodeResponse createdNode = computeService.createNode(nodeElement.getName(), Profile
.valueOf(nodeElement.getProfile().toUpperCase()), Image.valueOf(nodeElement
.getImage().toUpperCase()));
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
.getPublicAddresses().first().getHostAddress(), createdNode.getLoginPort()));
if (nodeElement.getIdproperty() != null)
getProject().setProperty(nodeElement.getIdproperty(), createdNode.getId());
if (nodeElement.getHostproperty() != null)
getProject().setProperty(nodeElement.getHostproperty(),
createdNode.getPublicAddresses().first().getHostAddress());
if (nodeElement.getKeyfile() != null
&& createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
try {
Files.write(createdServer.getCredentials().key, new File(serverElement.getKeyfile()),
Files.write(createdNode.getCredentials().key, new File(nodeElement.getKeyfile()),
Charset.defaultCharset());
} catch (IOException e) {
throw new BuildException(e);
}
if (serverElement.getPasswordproperty() != null
&& !createdServer.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
getProject().setProperty(serverElement.getPasswordproperty(),
createdServer.getCredentials().key);
if (serverElement.getUsernameproperty() != null)
getProject().setProperty(serverElement.getUsernameproperty(),
createdServer.getCredentials().account);
if (nodeElement.getPasswordproperty() != null
&& !createdNode.getCredentials().key.startsWith("-----BEGIN RSA PRIVATE KEY-----"))
getProject().setProperty(nodeElement.getPasswordproperty(),
createdNode.getCredentials().key);
if (nodeElement.getUsernameproperty() != null)
getProject().setProperty(nodeElement.getUsernameproperty(),
createdNode.getCredentials().account);
}
private void destroy(ComputeService computeService) {
log(String.format("destroy name: %s", serverElement.getName()));
SortedSet<ServerIdentity> serversThatMatch = computeService.getServerByName(serverElement
.getName());
if (serversThatMatch.size() > 0) {
for (ServerIdentity server : serversThatMatch) {
log(String.format(" destroying id=%s, name=%s", server.getId(), server.getName()));
computeService.destroyServer(server.getId());
log(String.format("destroy name: %s", nodeElement.getName()));
Set<NodeIdentity> nodesThatMatch = computeService.getNodeByName(nodeElement.getName());
if (nodesThatMatch.size() > 0) {
for (NodeIdentity node : nodesThatMatch) {
log(String.format(" destroying id=%s, name=%s", node.getId(), node.getName()));
computeService.destroyNode(node.getId());
}
}
}
private void get(ComputeService computeService) {
log(String.format("get name: %s", serverElement.getName()));
SortedSet<ServerIdentity> serversThatMatch = computeService.getServerByName(serverElement
.getName());
if (serversThatMatch.size() > 0) {
for (ServerIdentity server : serversThatMatch) {
logDetails(computeService, server);
log(String.format("get name: %s", nodeElement.getName()));
Set<NodeIdentity> nodesThatMatch = computeService.getNodeByName(nodeElement.getName());
if (nodesThatMatch.size() > 0) {
for (NodeIdentity node : nodesThatMatch) {
logDetails(computeService, node);
}
}
}
private void logDetails(ComputeService computeService, ServerIdentity server) {
ServerMetadata metadata = computeService.getServerMetadata(server.getId());
log(String.format(" server id=%s, name=%s, state=%s, publicIp=%s, privateIp=%s", metadata
.getId(), server.getName(), metadata.getState(), ipOrEmptyString(metadata
private void logDetails(ComputeService computeService, NodeIdentity node) {
NodeMetadata metadata = computeService.getNodeMetadata(node.getId());
log(String.format(" node id=%s, name=%s, state=%s, publicIp=%s, privateIp=%s", metadata
.getId(), node.getName(), metadata.getState(), ipOrEmptyString(metadata
.getPublicAddresses()), ipOrEmptyString(metadata.getPrivateAddresses())));
}
@ -239,12 +244,12 @@ public class ComputeTask extends Task {
this.action = action;
}
public ServerElement getServerElement() {
return serverElement;
public NodeElement getNodeElement() {
return nodeElement;
}
public void setServerElement(ServerElement serverElement) {
this.serverElement = serverElement;
public void setNodeElement(NodeElement nodeElement) {
this.nodeElement = nodeElement;
}
public void setProvider(String provider) {

View File

@ -21,7 +21,7 @@ package org.jclouds.tools.ant.taskdefs.compute;
/**
* @author Ivan Meredith
*/
public class ServerElement {
public class NodeElement {
private String name;
private String profile;
private String image;
@ -67,7 +67,6 @@ public class ServerElement {
this.usernameproperty = usernameproperty;
}
String getPasswordproperty() {
return passwordproperty;
}

View File

@ -20,7 +20,7 @@ package org.jclouds.vcloud.hostingdotcom.compute;
import java.net.InetAddress;
import java.util.Map;
import java.util.SortedSet;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -28,16 +28,16 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.ServerIdentity;
import org.jclouds.compute.domain.ServerMetadata;
import org.jclouds.compute.domain.ServerState;
import org.jclouds.compute.domain.internal.CreateServerResponseImpl;
import org.jclouds.compute.domain.internal.ServerMetadataImpl;
import org.jclouds.compute.reference.ComputeConstants;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.VCloudMediaType;
@ -58,16 +58,16 @@ import com.google.inject.internal.ImmutableSet;
@Singleton
public class HostingDotComVCloudComputeService implements ComputeService {
@Resource
@Named(ComputeConstants.COMPUTE_LOGGER)
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final HostingDotComVCloudComputeClient computeClient;
private final HostingDotComVCloudClient hostingClient;
private static final Map<VAppStatus, ServerState> vAppStatusToServerState = ImmutableMap
.<VAppStatus, ServerState> builder().put(VAppStatus.OFF, ServerState.TERMINATED).put(
VAppStatus.ON, ServerState.RUNNING).put(VAppStatus.RESOLVED,
ServerState.PENDING).put(VAppStatus.SUSPENDED, ServerState.SUSPENDED).put(
VAppStatus.UNRESOLVED, ServerState.PENDING).build();
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
VAppStatus.ON, NodeState.RUNNING).put(VAppStatus.RESOLVED, NodeState.PENDING)
.put(VAppStatus.SUSPENDED, NodeState.SUSPENDED).put(VAppStatus.UNRESOLVED,
NodeState.PENDING).build();
@Inject
public HostingDotComVCloudComputeService(HostingDotComVCloudClient tmClient,
@ -78,47 +78,47 @@ public class HostingDotComVCloudComputeService implements ComputeService {
}
@Override
public CreateServerResponse createServer(String name, Profile profile, Image image) {
public CreateNodeResponse createNode(String name, Profile profile, Image image) {
Map<String, String> metaMap = computeClient.start(name, image, 1, 512, (10l * 1025 * 1024),
ImmutableMap.<String, String> of());
VApp vApp = hostingClient.getVApp(metaMap.get("id"));
return new CreateServerResponseImpl(vApp.getId(), vApp.getName(), vAppStatusToServerState
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), vAppStatusToNodeState
.get(vApp.getStatus()), vApp.getNetworkToAddresses().values(), ImmutableSet
.<InetAddress> of(), 22, LoginType.SSH, new Credentials(metaMap.get("username"),
metaMap.get("password")));
metaMap.get("password")), ImmutableMap.<String, String> of());
}
@Override
public ServerMetadata getServerMetadata(String id) {
public NodeMetadata getNodeMetadata(String id) {
VApp vApp = hostingClient.getVApp(id);
return new ServerMetadataImpl(vApp.getId(), vApp.getName(), vAppStatusToServerState.get(vApp
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vAppStatusToNodeState.get(vApp
.getStatus()), vApp.getNetworkToAddresses().values(), ImmutableSet
.<InetAddress> of(), 22, LoginType.SSH);
.<InetAddress> of(), 22, LoginType.SSH, ImmutableMap.<String, String> of());
}
@Override
public SortedSet<ServerIdentity> getServerByName(final String name) {
return Sets.newTreeSet(Iterables.filter(listServers(), new Predicate<ServerIdentity>() {
public Set<NodeIdentity> getNodeByName(final String name) {
return Sets.newHashSet(Iterables.filter(listNodes(), new Predicate<NodeIdentity>() {
@Override
public boolean apply(ServerIdentity input) {
public boolean apply(NodeIdentity input) {
return input.getName().equalsIgnoreCase(name);
}
}));
}
@Override
public SortedSet<ServerIdentity> listServers() {
SortedSet<ServerIdentity> servers = Sets.newTreeSet();
public Set<NodeIdentity> listNodes() {
Set<NodeIdentity> servers = Sets.newTreeSet();
for (NamedResource resource : hostingClient.getDefaultVDC().getResourceEntities().values()) {
if (resource.getType().equals(VCloudMediaType.VAPP_XML)) {
servers.add(getServerMetadata(resource.getId()));
servers.add(getNodeMetadata(resource.getId()));
}
}
return servers;
}
@Override
public void destroyServer(String id) {
public void destroyNode(String id) {
computeClient.stop(id);
}
}

View File

@ -0,0 +1,78 @@
/**
*
* 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.vcloud.hostingdotcom.compute;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import org.jclouds.vcloud.hostingdotcom.compute.config.HostingDotComVCloudComputeServiceContextModule;
import org.jclouds.vcloud.hostingdotcom.config.HostingDotComVCloudRestClientModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Creates {@link HostingDotComVCloudComputeServiceContext} or {@link Injector} instances based on the most commonly
* requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see HostingDotComVCloudComputeServiceContext
*/
public class HostingDotComVCloudComputeServiceContextBuilder extends
ComputeServiceContextBuilder<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> {
public HostingDotComVCloudComputeServiceContextBuilder(Properties props) {
super(new TypeLiteral<HostingDotComVCloudAsyncClient>() {
}, new TypeLiteral<HostingDotComVCloudClient>() {
}, props);
}
@Override
public HostingDotComVCloudComputeServiceContextBuilder withExecutorService(ExecutorService service) {
return (HostingDotComVCloudComputeServiceContextBuilder) super.withExecutorService(service);
}
@Override
public HostingDotComVCloudComputeServiceContextBuilder withModules(Module... modules) {
return (HostingDotComVCloudComputeServiceContextBuilder) super.withModules(modules);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new HostingDotComVCloudComputeServiceContextModule());
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new HostingDotComVCloudRestClientModule());
}
}

View File

@ -0,0 +1,70 @@
/**
*
* 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.vcloud.hostingdotcom.compute;
import java.net.URI;
import java.util.Properties;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder;
import com.google.inject.Module;
/**
* Creates {@link HostingDotComVCloudComputeServiceContext} instances based on the most commonly requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see HostingDotComVCloudComputeServiceContext
*/
public class HostingDotComVCloudComputeServiceContextFactory {
public static ComputeServiceContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> createContext(Properties properties,
Module... modules) {
return new HostingDotComVCloudComputeServiceContextBuilder(new HostingDotComVCloudPropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static ComputeServiceContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> createContext(String user,
String key, Module... modules) {
return new HostingDotComVCloudComputeServiceContextBuilder(new HostingDotComVCloudPropertiesBuilder(user,
key).build()).withModules(modules).buildContext();
}
public static ComputeServiceContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> createContext(Properties properties,
String user, String key, Module... modules) {
return new HostingDotComVCloudComputeServiceContextBuilder(new HostingDotComVCloudPropertiesBuilder(properties).withCredentials(
user, key).build()).withModules(modules).buildContext();
}
public static ComputeServiceContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> createContext(URI endpoint,
String user, String key, Module... modules) {
return new HostingDotComVCloudComputeServiceContextBuilder(new HostingDotComVCloudPropertiesBuilder(user,
key).withEndpoint(endpoint).build()).withModules(modules)
.buildContext();
}
}

View File

@ -0,0 +1,62 @@
/**
*
* 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.vcloud.hostingdotcom.compute.config;
import java.net.URI;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.lifecycle.Closer;
import org.jclouds.vcloud.endpoints.VCloud;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeService;
import org.jclouds.vcloud.reference.VCloudConstants;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link HostingDotComVCloudComputeServiceContext}; requires
* {@link HostingDotComVCloudComputeService} bound.
*
* @author Adrian Cole
*/
public class HostingDotComVCloudComputeServiceContextModule extends AbstractModule {
@Override
protected void configure() {
bind(ComputeService.class).to(HostingDotComVCloudComputeService.class).asEagerSingleton();
}
@Provides
@Singleton
ComputeServiceContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> provideContext(
Closer closer, ComputeService computeService, HostingDotComVCloudAsyncClient asynchApi,
HostingDotComVCloudClient defaultApi, @VCloud URI endPoint,
@Named(VCloudConstants.PROPERTY_VCLOUD_USER) String account) {
return new ComputeServiceContextImpl<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient>(
closer, computeService, asynchApi, defaultApi, endPoint, account);
}
}

View File

@ -0,0 +1,151 @@
/**
*
* 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.vcloud.hostingdotcom.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.util.Utils;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudAsyncClient;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudClient;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
*
* Generally disabled, as it incurs higher fees.
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = false, sequential = true, testName = "compute.HostingDotComVCloudComputeServiceLiveTest")
public class HostingDotComVCloudComputeServiceLiveTest {
protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name");
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node;
private ComputeServiceContext<HostingDotComVCloudAsyncClient, HostingDotComVCloudClient> context;
@BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
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());
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
}
public void testCreate() throws Exception {
node = context.getComputeService().createNode(nodePrefix, Profile.SMALLEST, Image.UBUNTU_90);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
assertNotNull(node.getName());
assertEquals(node.getPrivateAddresses().size(), 1);
assertEquals(node.getPublicAddresses().size(), 1);
assertNotNull(node.getCredentials());
assertNotNull(node.getCredentials().account);
assertNotNull(node.getCredentials().key);
sshPing();
}
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node.getId());
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
assertEquals(metadata.getName(), node.getName());
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
}
public void testList() throws Exception {
for (NodeIdentity node : context.getComputeService().listNodes()) {
assert node.getId() != null;
}
}
private void sshPing() throws IOException {
try {
doCheckKey();
} catch (SshException e) {// try twice in case there is a network timeout
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e1) {
}
doCheckKey();
}
}
private void doCheckKey() throws IOException {
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
.getLoginPort());
socketTester.apply(socket);
SshClient connection = sshFactory.create(socket, node.getCredentials().account, node
.getCredentials().key);
try {
connection.connect();
InputStream etcPasswd = connection.get("/etc/passwd");
Utils.toStringAndClose(etcPasswd);
} finally {
if (connection != null)
connection.disconnect();
}
}
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null)
context.getComputeService().destroyNode(node.getId());
context.close();
}
}

View File

@ -0,0 +1,53 @@
/**
*
* 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.vcloud.hostingdotcom.compute;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import com.google.common.io.Resources;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "compute.PropertiesTest")
public class PropertiesTest {
private Properties properties;
@BeforeTest
public void setUp() throws IOException {
properties = new Properties();
properties.load(Resources.newInputStreamSupplier(Resources.getResource("compute.properties"))
.getInput());
}
public void test() {
assertEquals(properties.getProperty("hostingdotcom.contextbuilder"),
HostingDotComVCloudComputeServiceContextBuilder.class.getName());
assertEquals(properties.getProperty("hostingdotcom.propertiesbuilder"),
HostingDotComVCloudPropertiesBuilder.class.getName());
}
}

View File

@ -32,7 +32,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.reference.ComputeConstants;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.domain.Task;
import org.jclouds.vcloud.domain.VAppStatus;
@ -55,7 +55,7 @@ import com.google.common.collect.Sets;
*/
public class TerremarkVCloudComputeClient {
@Resource
@Named(ComputeConstants.COMPUTE_LOGGER)
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
Logger logger = Logger.NULL;
private final Predicate<String> taskTester;
@ -110,22 +110,17 @@ public class TerremarkVCloudComputeClient {
}
public Set<InetAddress> getPublicAddresses(String id) {
TerremarkVApp vApp = tmClient.getVApp(id);
Set<InetAddress> ipAddresses = Sets.newHashSet();
SERVICE: for (InternetService service : tmClient.getAllInternetServicesInVDC(vApp.getVDC()
.getId())) {
for (Node node : tmClient.getNodes(service.getId()))
{
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress()))
{
ipAddresses.add(service.getPublicIpAddress().getAddress());
}
}
}
return ipAddresses;
}
TerremarkVApp vApp = tmClient.getVApp(id);
Set<InetAddress> ipAddresses = Sets.newHashSet();
for (InternetService service : tmClient.getAllInternetServicesInVDC(vApp.getVDC().getId())) {
for (Node node : tmClient.getNodes(service.getId())) {
if (vApp.getNetworkToAddresses().containsValue(node.getIpAddress())) {
ipAddresses.add(service.getPublicIpAddress().getAddress());
}
}
}
return ipAddresses;
}
public void reboot(String id) {
TerremarkVApp vApp = tmClient.getVApp(id);

View File

@ -21,7 +21,6 @@ package org.jclouds.vcloud.terremark.compute;
import java.net.InetAddress;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -29,16 +28,16 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.CreateServerResponse;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.Profile;
import org.jclouds.compute.domain.ServerIdentity;
import org.jclouds.compute.domain.ServerMetadata;
import org.jclouds.compute.domain.ServerState;
import org.jclouds.compute.domain.internal.CreateServerResponseImpl;
import org.jclouds.compute.domain.internal.ServerMetadataImpl;
import org.jclouds.compute.reference.ComputeConstants;
import org.jclouds.compute.domain.internal.CreateNodeResponseImpl;
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.Credentials;
import org.jclouds.logging.Logger;
import org.jclouds.vcloud.VCloudMediaType;
@ -60,70 +59,69 @@ import com.google.inject.internal.ImmutableSet;
@Singleton
public class TerremarkVCloudComputeService implements ComputeService {
@Resource
@Named(ComputeConstants.COMPUTE_LOGGER)
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
private final TerremarkVCloudComputeClient computeClient;
private final TerremarkVCloudClient tmClient;
private static final Map<VAppStatus, ServerState> vAppStatusToServerState = ImmutableMap
.<VAppStatus, ServerState> builder().put(VAppStatus.OFF, ServerState.TERMINATED).put(
VAppStatus.ON, ServerState.RUNNING).put(VAppStatus.RESOLVED,
ServerState.PENDING).put(VAppStatus.SUSPENDED, ServerState.SUSPENDED).put(
VAppStatus.UNRESOLVED, ServerState.PENDING).build();
private static final Map<VAppStatus, NodeState> vAppStatusToNodeState = ImmutableMap
.<VAppStatus, NodeState> builder().put(VAppStatus.OFF, NodeState.TERMINATED).put(
VAppStatus.ON, NodeState.RUNNING).put(VAppStatus.RESOLVED,
NodeState.PENDING).put(VAppStatus.SUSPENDED, NodeState.SUSPENDED).put(
VAppStatus.UNRESOLVED, NodeState.PENDING).build();
@Inject
public TerremarkVCloudComputeService(TerremarkVCloudClient tmClient,
TerremarkVCloudComputeClient computeClient) {
this.tmClient = tmClient;
this.computeClient = computeClient;
}
@Override
public CreateServerResponse createServer(String name, Profile profile, Image image) {
public CreateNodeResponse createNode(String name, Profile profile, Image image) {
String id = computeClient.start(name, image, 1, 512, ImmutableMap.<String, String> of());
TerremarkVApp vApp = tmClient.getVApp(id);
InetAddress publicIp = computeClient
.createPublicAddressMappedToPorts(vApp, 22, 80, 8080, 443);
return new CreateServerResponseImpl(vApp.getId(), vApp.getName(), vAppStatusToServerState
return new CreateNodeResponseImpl(vApp.getId(), vApp.getName(), vAppStatusToNodeState
.get(vApp.getStatus()), ImmutableSet.<InetAddress> of(publicIp), vApp
.getNetworkToAddresses().values(), 22, LoginType.SSH, new Credentials("vcloud",
"p4ssw0rd"));
"p4ssw0rd"), ImmutableMap.<String,String>of());
}
@Override
public ServerMetadata getServerMetadata(String id) {
public NodeMetadata getNodeMetadata(String id) {
VApp vApp = tmClient.getVApp(id);
// TODO
Set<InetAddress> publicAddresses = ImmutableSet.<InetAddress> of();
return new ServerMetadataImpl(vApp.getId(), vApp.getName(), vAppStatusToServerState.get(vApp
return new NodeMetadataImpl(vApp.getId(), vApp.getName(), vAppStatusToNodeState.get(vApp
.getStatus()), publicAddresses, vApp.getNetworkToAddresses().values(), 22,
LoginType.SSH);
LoginType.SSH, ImmutableMap.<String,String>of());
}
@Override
public SortedSet<ServerIdentity> getServerByName(final String name) {
return Sets.newTreeSet(Iterables.filter(listServers(), new Predicate<ServerIdentity>() {
public Set<NodeIdentity> getNodeByName(final String name) {
return Sets.newHashSet(Iterables.filter(listNodes(), new Predicate<NodeIdentity>() {
@Override
public boolean apply(ServerIdentity input) {
public boolean apply(NodeIdentity input) {
return input.getName().equalsIgnoreCase(name);
}
}));
}
@Override
public SortedSet<ServerIdentity> listServers() {
SortedSet<ServerIdentity> servers = Sets.newTreeSet();
public Set<NodeIdentity> listNodes() {
Set<NodeIdentity> nodes = Sets.newHashSet();
for (NamedResource resource : tmClient.getDefaultVDC().getResourceEntities().values()) {
if (resource.getType().equals(VCloudMediaType.VAPP_XML)) {
servers.add(getServerMetadata(resource.getId()));
nodes.add(getNodeMetadata(resource.getId()));
}
}
return servers;
return nodes;
}
@Override
public void destroyServer(String id) {
public void destroyNode(String id) {
computeClient.stop(id);
}
}

View File

@ -0,0 +1,78 @@
/**
*
* 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.vcloud.terremark.compute;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import org.jclouds.compute.ComputeServiceContextBuilder;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.jclouds.vcloud.terremark.compute.config.TerremarkVCloudComputeServiceContextModule;
import org.jclouds.vcloud.terremark.config.TerremarkVCloudRestClientModule;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.TypeLiteral;
/**
* Creates {@link TerremarkVCloudComputeServiceContext} or {@link Injector} instances based on the most commonly
* requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see TerremarkVCloudComputeServiceContext
*/
public class TerremarkVCloudComputeServiceContextBuilder extends
ComputeServiceContextBuilder<TerremarkVCloudAsyncClient, TerremarkVCloudClient> {
public TerremarkVCloudComputeServiceContextBuilder(Properties props) {
super(new TypeLiteral<TerremarkVCloudAsyncClient>() {
}, new TypeLiteral<TerremarkVCloudClient>() {
}, props);
}
@Override
public TerremarkVCloudComputeServiceContextBuilder withExecutorService(ExecutorService service) {
return (TerremarkVCloudComputeServiceContextBuilder) super.withExecutorService(service);
}
@Override
public TerremarkVCloudComputeServiceContextBuilder withModules(Module... modules) {
return (TerremarkVCloudComputeServiceContextBuilder) super.withModules(modules);
}
@Override
protected void addContextModule(List<Module> modules) {
modules.add(new TerremarkVCloudComputeServiceContextModule());
}
@Override
protected void addClientModule(List<Module> modules) {
modules.add(new TerremarkVCloudRestClientModule());
}
}

View File

@ -0,0 +1,70 @@
/**
*
* 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.vcloud.terremark.compute;
import java.net.URI;
import java.util.Properties;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule;
import org.jclouds.logging.jdk.config.JDKLoggingModule;
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudPropertiesBuilder;
import com.google.inject.Module;
/**
* Creates {@link TerremarkVCloudComputeServiceContext} instances based on the most commonly requested arguments.
* <p/>
* Note that Threadsafe objects will be bound as singletons to the Injector or Context provided.
* <p/>
* <p/>
* If no <code>Module</code>s are specified, the default {@link JDKLoggingModule logging} and
* {@link JavaUrlHttpCommandExecutorServiceModule http transports} will be installed.
*
* @author Adrian Cole
* @see TerremarkVCloudComputeServiceContext
*/
public class TerremarkVCloudComputeServiceContextFactory {
public static ComputeServiceContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> createContext(Properties properties,
Module... modules) {
return new TerremarkVCloudComputeServiceContextBuilder(new TerremarkVCloudPropertiesBuilder(properties).build())
.withModules(modules).buildContext();
}
public static ComputeServiceContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> createContext(String user,
String key, Module... modules) {
return new TerremarkVCloudComputeServiceContextBuilder(new TerremarkVCloudPropertiesBuilder(user,
key).build()).withModules(modules).buildContext();
}
public static ComputeServiceContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> createContext(Properties properties,
String user, String key, Module... modules) {
return new TerremarkVCloudComputeServiceContextBuilder(new TerremarkVCloudPropertiesBuilder(properties).withCredentials(
user, key).build()).withModules(modules).buildContext();
}
public static ComputeServiceContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> createContext(URI endpoint,
String user, String key, Module... modules) {
return new TerremarkVCloudComputeServiceContextBuilder(new TerremarkVCloudPropertiesBuilder(user,
key).withEndpoint(endpoint).build()).withModules(modules)
.buildContext();
}
}

View File

@ -0,0 +1,62 @@
/**
*
* 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.vcloud.terremark.compute.config;
import java.net.URI;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.lifecycle.Closer;
import org.jclouds.vcloud.endpoints.VCloud;
import org.jclouds.vcloud.reference.VCloudConstants;
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeService;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/**
* Configures the {@link TerremarkVCloudComputeServiceContext}; requires
* {@link TerremarkVCloudComputeService} bound.
*
* @author Adrian Cole
*/
public class TerremarkVCloudComputeServiceContextModule extends AbstractModule {
@Override
protected void configure() {
bind(ComputeService.class).to(TerremarkVCloudComputeService.class).asEagerSingleton();
}
@Provides
@Singleton
ComputeServiceContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> provideContext(
Closer closer, ComputeService computeService, TerremarkVCloudAsyncClient asynchApi,
TerremarkVCloudClient defaultApi, @VCloud URI endPoint,
@Named(VCloudConstants.PROPERTY_VCLOUD_USER) String account) {
return new ComputeServiceContextImpl<TerremarkVCloudAsyncClient, TerremarkVCloudClient>(
closer, computeService, asynchApi, defaultApi, endPoint, account);
}
}

View File

@ -282,6 +282,7 @@ public class TerremarkVCloudClientLiveTest extends VCloudClientLiveTest {
assertEquals(clone.getStatus(), VAppStatus.ON);
assertEquals(clone.getName(), newName);
assertEquals(clone.getNetworkToAddresses().values().size(), 1);
}
@Test(dependsOnMethods = { "testInstantiateAndPowerOn", "testAddInternetService" })

View File

@ -23,7 +23,6 @@ import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.util.Properties;
import org.jclouds.vcloud.terremark.TerremarkVCloudContextBuilder;
import org.jclouds.vcloud.terremark.TerremarkVCloudPropertiesBuilder;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
@ -46,7 +45,7 @@ public class PropertiesTest {
public void testRimu() {
assertEquals(properties.getProperty("terremark.contextbuilder"),
TerremarkVCloudContextBuilder.class.getName());
TerremarkVCloudComputeServiceContextBuilder.class.getName());
assertEquals(properties.getProperty("terremark.propertiesbuilder"),
TerremarkVCloudPropertiesBuilder.class.getName());
}

View File

@ -0,0 +1,151 @@
/**
*
* 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.vcloud.terremark.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.domain.CreateNodeResponse;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.LoginType;
import org.jclouds.compute.domain.NodeIdentity;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Profile;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.predicates.SocketOpen;
import org.jclouds.ssh.SshClient;
import org.jclouds.ssh.SshException;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.jclouds.util.Utils;
import org.jclouds.vcloud.terremark.TerremarkVCloudAsyncClient;
import org.jclouds.vcloud.terremark.TerremarkVCloudClient;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.inject.Guice;
import com.google.inject.Injector;
/**
*
* Generally disabled, as it incurs higher fees.
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = false, sequential = true, testName = "terremark.TerremarkVCloudComputeServiceLiveTest")
public class TerremarkVCloudComputeServiceLiveTest {
protected SshClient.Factory sshFactory;
private String nodePrefix = System.getProperty("user.name");
private RetryablePredicate<InetSocketAddress> socketTester;
private CreateNodeResponse node;
private ComputeServiceContext<TerremarkVCloudAsyncClient, TerremarkVCloudClient> context;
@BeforeGroups(groups = { "live" })
public void setupClient() throws InterruptedException, ExecutionException, TimeoutException {
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());
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
}
public void testCreate() throws Exception {
node = context.getComputeService().createNode(nodePrefix, Profile.SMALLEST, Image.UBUNTU_90);
assertNotNull(node.getId());
assertEquals(node.getLoginPort(), 22);
assertEquals(node.getLoginType(), LoginType.SSH);
assertNotNull(node.getName());
assertEquals(node.getPrivateAddresses().size(), 1);
assertEquals(node.getPublicAddresses().size(), 1);
assertNotNull(node.getCredentials());
assertNotNull(node.getCredentials().account);
assertNotNull(node.getCredentials().key);
sshPing();
}
@Test(dependsOnMethods = "testCreate")
public void testGet() throws Exception {
NodeMetadata metadata = context.getComputeService().getNodeMetadata(node.getId());
assertEquals(metadata.getId(), node.getId());
assertEquals(metadata.getLoginPort(), node.getLoginPort());
assertEquals(metadata.getLoginType(), node.getLoginType());
assertEquals(metadata.getName(), node.getName());
assertEquals(metadata.getPrivateAddresses(), node.getPrivateAddresses());
assertEquals(metadata.getPublicAddresses(), node.getPublicAddresses());
}
public void testList() throws Exception {
for (NodeIdentity node : context.getComputeService().listNodes()) {
assert node.getId() != null;
}
}
private void sshPing() throws IOException {
try {
doCheckKey();
} catch (SshException e) {// try twice in case there is a network timeout
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e1) {
}
doCheckKey();
}
}
private void doCheckKey() throws IOException {
InetSocketAddress socket = new InetSocketAddress(node.getPublicAddresses().last(), node
.getLoginPort());
socketTester.apply(socket);
SshClient connection = sshFactory.create(socket, node.getCredentials().account, node
.getCredentials().key);
try {
connection.connect();
InputStream etcPasswd = connection.get("/etc/passwd");
Utils.toStringAndClose(etcPasswd);
} finally {
if (connection != null)
connection.disconnect();
}
}
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (node != null)
context.getComputeService().destroyNode(node.getId());
context.close();
}
}