mirror of https://github.com/apache/jclouds.git
Issue 129, Issue 130: added ec2 to abstraction and ant tool
git-svn-id: http://jclouds.googlecode.com/svn/trunk@2446 3d8758e0-26b5-11de-8745-db77d3ebf521
This commit is contained in:
parent
54e1ddbda0
commit
0dc9f42502
|
@ -0,0 +1,227 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.aws.ec2.compute;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.aws.ec2.options.RunInstancesOptions.Builder.withKeyName;
|
||||||
|
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.SortedSet;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.aws.AWSResponseException;
|
||||||
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
import org.jclouds.aws.ec2.domain.InstanceType;
|
||||||
|
import org.jclouds.aws.ec2.domain.IpProtocol;
|
||||||
|
import org.jclouds.aws.ec2.domain.KeyPair;
|
||||||
|
import org.jclouds.aws.ec2.domain.Reservation;
|
||||||
|
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.domain.CreateServerResponse;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.LoginType;
|
||||||
|
import org.jclouds.compute.domain.Profile;
|
||||||
|
import org.jclouds.compute.domain.ServerIdentity;
|
||||||
|
import org.jclouds.compute.domain.ServerMetadata;
|
||||||
|
import org.jclouds.compute.domain.internal.CreateServerResponseImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.ServerIdentityImpl;
|
||||||
|
import org.jclouds.compute.domain.internal.ServerMetadataImpl;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.google.inject.internal.ImmutableSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class EC2ComputeService implements ComputeService {
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
private final EC2Client ec2Client;
|
||||||
|
private final Predicate<RunningInstance> instanceStateRunning;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public EC2ComputeService(EC2Client tmClient, Predicate<RunningInstance> instanceStateRunning) {
|
||||||
|
this.ec2Client = tmClient;
|
||||||
|
this.instanceStateRunning = instanceStateRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<Image, String> imageAmiIdMap = ImmutableMap.<Image, String> builder().put(
|
||||||
|
Image.CENTOS_53, "ami-b0a84ad9").put(Image.RHEL_53, "ami-368b685f").build();// todo ami
|
||||||
|
// matrix of
|
||||||
|
// region
|
||||||
|
// 32/64 bit
|
||||||
|
|
||||||
|
private Map<Profile, InstanceType> profileInstanceTypeMap = ImmutableMap
|
||||||
|
.<Profile, InstanceType> builder().put(Profile.SMALLEST, InstanceType.M1_SMALL).build();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CreateServerResponse createServer(String name, Profile profile, Image image) {
|
||||||
|
String ami = checkNotNull(imageAmiIdMap.get(image), "image not supported: " + image);
|
||||||
|
InstanceType type = checkNotNull(profileInstanceTypeMap.get(profile),
|
||||||
|
"profile not supported: " + profile);
|
||||||
|
KeyPair keyPair = createKeyPair(name);
|
||||||
|
String securityGroupName = name;
|
||||||
|
createSecurityGroup(securityGroupName, 22, 80, 443);
|
||||||
|
|
||||||
|
logger.debug(">> running instance ami(%s) type(%s) keyPair(%s) securityGroup(%s)", ami, type,
|
||||||
|
keyPair.getKeyName(), securityGroupName);
|
||||||
|
|
||||||
|
RunningInstance runningInstance = Iterables.getLast(ec2Client.runInstances(
|
||||||
|
ami,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
withKeyName(keyPair.getKeyName()).asType(type).withSecurityGroup(securityGroupName)
|
||||||
|
.withAdditionalInfo(name)).getRunningInstances());
|
||||||
|
logger.debug("<< started instance(%s)", runningInstance.getInstanceId());
|
||||||
|
instanceStateRunning.apply(runningInstance);
|
||||||
|
logger.debug("<< running instance(%s)", runningInstance.getInstanceId());
|
||||||
|
|
||||||
|
// refresh to get IP address
|
||||||
|
runningInstance = getRunningInstance(runningInstance.getInstanceId());
|
||||||
|
|
||||||
|
Set<InetAddress> publicAddresses = runningInstance.getIpAddress() == null ? ImmutableSet
|
||||||
|
.<InetAddress> of() : ImmutableSet.<InetAddress> of(runningInstance.getIpAddress());
|
||||||
|
Set<InetAddress> privateAddresses = runningInstance.getPrivateIpAddress() == null ? ImmutableSet
|
||||||
|
.<InetAddress> of()
|
||||||
|
: ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress());
|
||||||
|
return new CreateServerResponseImpl(runningInstance.getInstanceId(), name, publicAddresses,
|
||||||
|
privateAddresses, 22, LoginType.SSH, new Credentials("root", keyPair
|
||||||
|
.getKeyMaterial()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private KeyPair createKeyPair(String name) {
|
||||||
|
logger.debug(">> creating keyPair name(%s)", name);
|
||||||
|
KeyPair keyPair;
|
||||||
|
try {
|
||||||
|
keyPair = ec2Client.createKeyPair(name);
|
||||||
|
logger.debug("<< created keyPair(%s)", keyPair.getKeyName());
|
||||||
|
|
||||||
|
} catch (AWSResponseException e) {
|
||||||
|
if (e.getError().getCode().equals("InvalidKeyPair.Duplicate")) {
|
||||||
|
keyPair = ec2Client.describeKeyPairs(name).last();
|
||||||
|
logger.debug("<< reused keyPair(%s)", keyPair.getKeyName());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keyPair;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createSecurityGroup(String name, int... ports) {
|
||||||
|
logger.debug(">> creating securityGroup name(%s)", name);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ec2Client.createSecurityGroup(name, name);
|
||||||
|
logger.debug("<< created securityGroup(%s)", name);
|
||||||
|
logger.debug(">> authorizing securityGroup name(%s) ports(%s)", name, ImmutableSet
|
||||||
|
.of(ports));
|
||||||
|
for (int port : ports) {
|
||||||
|
ec2Client.authorizeSecurityGroupIngress(name, IpProtocol.TCP, port, port, "0.0.0.0/0");
|
||||||
|
}
|
||||||
|
logger.debug("<< authorized securityGroup(%s)", name);
|
||||||
|
} catch (AWSResponseException e) {
|
||||||
|
if (e.getError().getCode().equals("InvalidGroup.Duplicate")) {
|
||||||
|
logger.debug("<< reused securityGroup(%s)", name);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServerMetadata getServerMetadata(String id) {
|
||||||
|
RunningInstance runningInstance = getRunningInstance(id);
|
||||||
|
return new ServerMetadataImpl(runningInstance.getInstanceId(), runningInstance
|
||||||
|
.getInstanceId(), ImmutableSet.<InetAddress> of(runningInstance.getIpAddress()),
|
||||||
|
ImmutableSet.<InetAddress> of(runningInstance.getPrivateIpAddress()), 22,
|
||||||
|
LoginType.SSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private RunningInstance getRunningInstance(String id) {
|
||||||
|
RunningInstance runningInstance = Iterables.getLast(Iterables.getLast(
|
||||||
|
ec2Client.describeInstances(id)).getRunningInstances());
|
||||||
|
return runningInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SortedSet<ServerIdentity> getServerByName(final String name) {
|
||||||
|
return Sets.newTreeSet(Iterables.filter(listServers(), new Predicate<ServerIdentity>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(ServerIdentity input) {
|
||||||
|
return input.getName().equalsIgnoreCase(name);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hack alert. can't find a good place to store the original servername, so we are reusing the
|
||||||
|
* keyname. This will break.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public SortedSet<ServerIdentity> listServers() {
|
||||||
|
logger.debug(">> listing servers");
|
||||||
|
SortedSet<ServerIdentity> servers = Sets.newTreeSet();
|
||||||
|
for (Reservation reservation : ec2Client.describeInstances()) {
|
||||||
|
Iterables.addAll(servers, Iterables.transform(reservation.getRunningInstances(),
|
||||||
|
new Function<RunningInstance, ServerIdentity>() {
|
||||||
|
@Override
|
||||||
|
public ServerIdentity apply(RunningInstance from) {
|
||||||
|
return new ServerIdentityImpl(from.getInstanceId(), from.getKeyName());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
logger.debug("<< list(%d)", servers.size());
|
||||||
|
return servers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroyServer(String id) {
|
||||||
|
RunningInstance runningInstance = getRunningInstance(id);
|
||||||
|
// grab the old keyname
|
||||||
|
String name = runningInstance.getKeyName();
|
||||||
|
logger.debug(">> terminating instance(%s)", runningInstance.getInstanceId());
|
||||||
|
ec2Client.terminateInstances(id);
|
||||||
|
logger.debug("<< terminated instance(%s)", runningInstance.getInstanceId());
|
||||||
|
logger.debug(">> deleting keyPair(%s)", name);
|
||||||
|
ec2Client.deleteKeyPair(name);
|
||||||
|
logger.debug("<< deleted keyPair(%s)", name);
|
||||||
|
logger.debug(">> deleting securityGroup(%s)", name);
|
||||||
|
ec2Client.deleteSecurityGroup(name);
|
||||||
|
logger.debug("<< deleted securityGroup(%s)", name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,9 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.aws.ec2.EC2;
|
import org.jclouds.aws.ec2.EC2;
|
||||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
import org.jclouds.aws.ec2.compute.EC2ComputeService;
|
||||||
import org.jclouds.aws.reference.AWSConstants;
|
import org.jclouds.aws.reference.AWSConstants;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.http.functions.config.ParserModule.CDateAdapter;
|
import org.jclouds.http.functions.config.ParserModule.CDateAdapter;
|
||||||
import org.jclouds.http.functions.config.ParserModule.DateAdapter;
|
import org.jclouds.http.functions.config.ParserModule.DateAdapter;
|
||||||
import org.jclouds.lifecycle.Closer;
|
import org.jclouds.lifecycle.Closer;
|
||||||
|
@ -50,6 +52,7 @@ public class EC2ContextModule extends AbstractModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(DateAdapter.class).to(CDateAdapter.class);
|
bind(DateAdapter.class).to(CDateAdapter.class);
|
||||||
|
bind(ComputeService.class).to(EC2ComputeService.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
@ -25,6 +25,7 @@ package org.jclouds.aws.ec2.config;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
@ -32,7 +33,9 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.aws.ec2.EC2;
|
import org.jclouds.aws.ec2.EC2;
|
||||||
import org.jclouds.aws.ec2.EC2AsyncClient;
|
import org.jclouds.aws.ec2.EC2AsyncClient;
|
||||||
import org.jclouds.aws.ec2.EC2Client;
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||||
import org.jclouds.aws.ec2.filters.FormSigner;
|
import org.jclouds.aws.ec2.filters.FormSigner;
|
||||||
|
import org.jclouds.aws.ec2.predicates.InstanceStateRunning;
|
||||||
import org.jclouds.aws.ec2.reference.EC2Constants;
|
import org.jclouds.aws.ec2.reference.EC2Constants;
|
||||||
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
|
import org.jclouds.aws.handlers.AWSClientErrorRetryHandler;
|
||||||
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
|
import org.jclouds.aws.handlers.AWSRedirectionRetryHandler;
|
||||||
|
@ -47,9 +50,11 @@ import org.jclouds.http.RequiresHttp;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
import org.jclouds.http.annotation.ServerError;
|
import org.jclouds.http.annotation.ServerError;
|
||||||
|
import org.jclouds.predicates.RetryablePredicate;
|
||||||
import org.jclouds.rest.ConfiguresRestClient;
|
import org.jclouds.rest.ConfiguresRestClient;
|
||||||
import org.jclouds.rest.RestClientFactory;
|
import org.jclouds.rest.RestClientFactory;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
|
||||||
|
@ -61,6 +66,11 @@ import com.google.inject.Provides;
|
||||||
@RequiresHttp
|
@RequiresHttp
|
||||||
@ConfiguresRestClient
|
@ConfiguresRestClient
|
||||||
public class EC2RestClientModule extends AbstractModule {
|
public class EC2RestClientModule extends AbstractModule {
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
protected Predicate<RunningInstance> instanceStateRunning(InstanceStateRunning stateRunning) {
|
||||||
|
return new RetryablePredicate<RunningInstance>(stateRunning, 600, 3, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package org.jclouds.aws.ec2.predicates;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.jclouds.aws.ec2.EC2Client;
|
||||||
|
import org.jclouds.aws.ec2.domain.InstanceState;
|
||||||
|
import org.jclouds.aws.ec2.domain.RunningInstance;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Tests to see if a task succeeds.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
public class InstanceStateRunning implements Predicate<RunningInstance> {
|
||||||
|
|
||||||
|
private final EC2Client client;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InstanceStateRunning(EC2Client client) {
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean apply(RunningInstance instance) {
|
||||||
|
logger.trace("looking for state on instance %s", instance);
|
||||||
|
|
||||||
|
instance = refresh(instance.getInstanceId());
|
||||||
|
logger.trace("%s: looking for instance state %s: currently: %s", instance.getInstanceId(),
|
||||||
|
InstanceState.RUNNING, instance.getInstanceState());
|
||||||
|
return instance.getInstanceState() == InstanceState.RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RunningInstance refresh(String instanceId) {
|
||||||
|
return Iterables.getLast(Iterables.getLast(client.describeInstances(instanceId))
|
||||||
|
.getRunningInstances());
|
||||||
|
}
|
||||||
|
}
|
|
@ -103,8 +103,7 @@ public class ExpensiveEC2ClientLiveTest {
|
||||||
|
|
||||||
client.createSecurityGroup(securityGroupName, securityGroupName);
|
client.createSecurityGroup(securityGroupName, securityGroupName);
|
||||||
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
|
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 80, 80, "0.0.0.0/0");
|
||||||
client
|
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 443, 443,
|
||||||
.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 443, 443,
|
|
||||||
"0.0.0.0/0");
|
"0.0.0.0/0");
|
||||||
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
client.authorizeSecurityGroupIngress(securityGroupName, IpProtocol.TCP, 22, 22, "0.0.0.0/0");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
* ====================================================================
|
||||||
|
*/
|
||||||
|
package org.jclouds.aws.ec2.compute;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import 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.aws.ec2.EC2ContextBuilder;
|
||||||
|
import org.jclouds.aws.ec2.EC2PropertiesBuilder;
|
||||||
|
import org.jclouds.compute.domain.CreateServerResponse;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.LoginType;
|
||||||
|
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;
|
||||||
|
import org.jclouds.ssh.SshClient;
|
||||||
|
import org.jclouds.ssh.SshException;
|
||||||
|
import org.jclouds.ssh.jsch.config.JschSshClientModule;
|
||||||
|
import org.jclouds.util.Utils;
|
||||||
|
import org.testng.annotations.AfterTest;
|
||||||
|
import org.testng.annotations.BeforeGroups;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Generally disabled, as it incurs higher fees.
|
||||||
|
*
|
||||||
|
* @author Adrian Cole
|
||||||
|
*/
|
||||||
|
@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 RetryablePredicate<InetSocketAddress> socketTester;
|
||||||
|
private CreateServerResponse server;
|
||||||
|
|
||||||
|
@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");
|
||||||
|
Injector injector = new EC2ContextBuilder(new EC2PropertiesBuilder(user, password).build())
|
||||||
|
.withModules(new Log4JLoggingModule(), new JschSshClientModule()).buildInjector();
|
||||||
|
client = injector.getInstance(EC2ComputeService.class);
|
||||||
|
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 {
|
||||||
|
server = client.createServer(serverPrefix, Profile.SMALLEST, Image.CENTOS_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);
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testList() throws Exception {
|
||||||
|
for (ServerIdentity server : client.listServers()) {
|
||||||
|
assert server.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(server.getPublicAddresses().last(), server
|
||||||
|
.getLoginPort());
|
||||||
|
socketTester.apply(socket);
|
||||||
|
SshClient connection = sshFactory.create(socket, server.getCredentials().account, server
|
||||||
|
.getCredentials().key.getBytes());
|
||||||
|
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 (server != null)
|
||||||
|
client.destroyServer(server.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -74,6 +74,27 @@
|
||||||
-->
|
-->
|
||||||
</layout>
|
</layout>
|
||||||
</appender>
|
</appender>
|
||||||
|
<!-- A time/date based rolling appender -->
|
||||||
|
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
|
<param name="File" value="target/test-data/jclouds-compute.log" />
|
||||||
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
|
<!-- Rollover at midnight each day -->
|
||||||
|
<param name="DatePattern" value="'.'yyyy-MM-dd" />
|
||||||
|
|
||||||
|
<param name="Threshold" value="TRACE" />
|
||||||
|
|
||||||
|
<layout class="org.apache.log4j.PatternLayout">
|
||||||
|
<!-- The default pattern: Date Priority [Category] Message\n -->
|
||||||
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
||||||
|
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
||||||
|
%m%n"/>
|
||||||
|
-->
|
||||||
|
</layout>
|
||||||
|
</appender>
|
||||||
|
|
||||||
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
|
||||||
<appender-ref ref="FILE" />
|
<appender-ref ref="FILE" />
|
||||||
|
@ -83,6 +104,9 @@
|
||||||
<appender-ref ref="WIREFILE" />
|
<appender-ref ref="WIREFILE" />
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
|
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||||
|
<appender-ref ref="COMPUTEFILE" />
|
||||||
|
</appender>
|
||||||
<!-- ================ -->
|
<!-- ================ -->
|
||||||
<!-- Limit categories -->
|
<!-- Limit categories -->
|
||||||
<!-- ================ -->
|
<!-- ================ -->
|
||||||
|
@ -97,6 +121,11 @@
|
||||||
<appender-ref ref="ASYNCWIRE" />
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
|
<category name="org.jclouds.aws.ec2.compute.EC2ComputeService">
|
||||||
|
<priority value="TRACE" />
|
||||||
|
<appender-ref ref="ASYNCCOMPUTE" />
|
||||||
|
</category>
|
||||||
|
|
||||||
<category name="jclouds.http.wire">
|
<category name="jclouds.http.wire">
|
||||||
<priority value="DEBUG" />
|
<priority value="DEBUG" />
|
||||||
<appender-ref ref="ASYNCWIRE" />
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
|
|
|
@ -4,3 +4,5 @@ terremark.contextbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudContextBuil
|
||||||
terremark.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudPropertiesBuilder
|
terremark.propertiesbuilder=org.jclouds.vcloud.terremark.TerremarkVCloudPropertiesBuilder
|
||||||
hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudContextBuilder
|
hostingdotcom.contextbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudContextBuilder
|
||||||
hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder
|
hostingdotcom.propertiesbuilder=org.jclouds.vcloud.hostingdotcom.HostingDotComVCloudPropertiesBuilder
|
||||||
|
ec2.contextbuilder=org.jclouds.aws.ec2.EC2ContextBuilder
|
||||||
|
ec2.propertiesbuilder=org.jclouds.aws.ec2.EC2PropertiesBuilder
|
|
@ -30,6 +30,7 @@
|
||||||
<artifact:dependencies pathId="jclouds.classpath">
|
<artifact:dependencies pathId="jclouds.classpath">
|
||||||
<dependency groupId="org.jclouds" artifactId="jclouds-ant-plugin" version="1.0-SNAPSHOT" />
|
<dependency groupId="org.jclouds" artifactId="jclouds-ant-plugin" version="1.0-SNAPSHOT" />
|
||||||
<dependency groupId="org.jclouds" artifactId="jclouds-terremark" version="1.0-SNAPSHOT" />
|
<dependency groupId="org.jclouds" artifactId="jclouds-terremark" version="1.0-SNAPSHOT" />
|
||||||
|
<dependency groupId="org.jclouds" artifactId="jclouds-aws" version="1.0-SNAPSHOT" />
|
||||||
<dependency groupId="org.jclouds" artifactId="jclouds-hostingdotcom" version="1.0-SNAPSHOT" />
|
<dependency groupId="org.jclouds" artifactId="jclouds-hostingdotcom" version="1.0-SNAPSHOT" />
|
||||||
<dependency groupId="org.jclouds" artifactId="jclouds-rimuhosting" version="1.0-SNAPSHOT" />
|
<dependency groupId="org.jclouds" artifactId="jclouds-rimuhosting" version="1.0-SNAPSHOT" />
|
||||||
<localRepository refid="local.repository" />
|
<localRepository refid="local.repository" />
|
||||||
|
|
|
@ -80,8 +80,8 @@
|
||||||
|
|
||||||
|
|
||||||
<!-- A time/date based rolling appender -->
|
<!-- A time/date based rolling appender -->
|
||||||
<appender name="VCLOUDFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
<param name="File" value="target/test-data/jclouds-vcloud.log" />
|
<param name="File" value="target/test-data/jclouds-compute.log" />
|
||||||
<param name="Append" value="true" />
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
<!-- Rollover at midnight each day -->
|
<!-- Rollover at midnight each day -->
|
||||||
|
@ -110,8 +110,8 @@
|
||||||
<appender-ref ref="WIREFILE" />
|
<appender-ref ref="WIREFILE" />
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="ASYNCVCLOUD" class="org.apache.log4j.AsyncAppender">
|
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||||
<appender-ref ref="VCLOUDFILE" />
|
<appender-ref ref="COMPUTEFILE" />
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- ================ -->
|
<!-- ================ -->
|
||||||
|
@ -132,7 +132,7 @@
|
||||||
|
|
||||||
<category name="org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeClient">
|
<category name="org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeClient">
|
||||||
<priority value="TRACE" />
|
<priority value="TRACE" />
|
||||||
<appender-ref ref="ASYNCVCLOUD" />
|
<appender-ref ref="ASYNCCOMPUTE" />
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,34 +1,32 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
|
Copyright (C) 2009 Cloud Conscious, LLC.
|
||||||
|
<info@cloudconscious.com>
|
||||||
|
|
||||||
====================================================================
|
====================================================================
|
||||||
Licensed to the Apache Software Foundation (ASF) under one
|
Licensed to the Apache Software Foundation (ASF) under one or
|
||||||
or more contributor license agreements. See the NOTICE file
|
more contributor license agreements. See the NOTICE file
|
||||||
distributed with this work for additional information
|
distributed with this work for additional information regarding
|
||||||
regarding copyright ownership. The ASF licenses this file
|
copyright ownership. The ASF licenses this file to you under the
|
||||||
to you under the Apache License, Version 2.0 (the
|
Apache License, Version 2.0 (the "License"); you may not use
|
||||||
"License"); you may not use this file except in compliance
|
this file except in compliance with the License. You may obtain
|
||||||
with the License. You may obtain a copy of the License at
|
a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0 Unless required by
|
||||||
|
applicable law or agreed to in writing, software distributed
|
||||||
Unless required by applicable law or agreed to in writing,
|
under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
software distributed under the License is distributed on an
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
See the License for the specific language governing permissions
|
||||||
KIND, either express or implied. See the License for the
|
and limitations under the License.
|
||||||
specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
====================================================================
|
====================================================================
|
||||||
|
-->
|
||||||
-->
|
|
||||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
For more configuration infromation and examples see the Apache Log4j
|
For more configuration infromation and examples see the Apache
|
||||||
website: http://logging.apache.org/log4j/
|
Log4j website: http://logging.apache.org/log4j/
|
||||||
-->
|
-->
|
||||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"
|
||||||
debug="false">
|
debug="false">
|
||||||
|
@ -48,9 +46,9 @@
|
||||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
The full pattern: Date MS Priority [Category]
|
||||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
%m%n"/>
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
-->
|
-->
|
||||||
</layout>
|
</layout>
|
||||||
</appender>
|
</appender>
|
||||||
|
@ -70,9 +68,9 @@
|
||||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
The full pattern: Date MS Priority [Category]
|
||||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
%m%n"/>
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
-->
|
-->
|
||||||
</layout>
|
</layout>
|
||||||
</appender>
|
</appender>
|
||||||
|
@ -80,8 +78,8 @@
|
||||||
|
|
||||||
|
|
||||||
<!-- A time/date based rolling appender -->
|
<!-- A time/date based rolling appender -->
|
||||||
<appender name="VCLOUDFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
<appender name="COMPUTEFILE" class="org.apache.log4j.DailyRollingFileAppender">
|
||||||
<param name="File" value="target/test-data/jclouds-vcloud.log" />
|
<param name="File" value="target/test-data/jclouds-compute.log" />
|
||||||
<param name="Append" value="true" />
|
<param name="Append" value="true" />
|
||||||
|
|
||||||
<!-- Rollover at midnight each day -->
|
<!-- Rollover at midnight each day -->
|
||||||
|
@ -94,9 +92,9 @@
|
||||||
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
<param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n" />
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
|
The full pattern: Date MS Priority [Category]
|
||||||
<param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x)
|
(Thread:NDC) Message\n <param name="ConversionPattern"
|
||||||
%m%n"/>
|
value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
|
||||||
-->
|
-->
|
||||||
</layout>
|
</layout>
|
||||||
</appender>
|
</appender>
|
||||||
|
@ -110,8 +108,8 @@
|
||||||
<appender-ref ref="WIREFILE" />
|
<appender-ref ref="WIREFILE" />
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<appender name="ASYNCVCLOUD" class="org.apache.log4j.AsyncAppender">
|
<appender name="ASYNCCOMPUTE" class="org.apache.log4j.AsyncAppender">
|
||||||
<appender-ref ref="VCLOUDFILE" />
|
<appender-ref ref="COMPUTEFILE" />
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<!-- ================ -->
|
<!-- ================ -->
|
||||||
|
@ -128,14 +126,12 @@
|
||||||
<appender-ref ref="ASYNCWIRE" />
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
|
<category
|
||||||
|
name="org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeClient">
|
||||||
<category name="org.jclouds.vcloud.terremark.compute.TerremarkVCloudComputeClient">
|
|
||||||
<priority value="TRACE" />
|
<priority value="TRACE" />
|
||||||
<appender-ref ref="ASYNCVCLOUD" />
|
<appender-ref ref="ASYNCCOMPUTE" />
|
||||||
</category>
|
</category>
|
||||||
|
|
||||||
|
|
||||||
<category name="org.jclouds.predicates.SocketOpen">
|
<category name="org.jclouds.predicates.SocketOpen">
|
||||||
<priority value="TRACE" />
|
<priority value="TRACE" />
|
||||||
<appender-ref ref="ASYNCWIRE" />
|
<appender-ref ref="ASYNCWIRE" />
|
||||||
|
|
Loading…
Reference in New Issue