Merge branch 'master' of git://github.com/jclouds/jclouds

Conflicts:
	core/src/main/java/org/jclouds/rest/config/ClientProvider.java
	core/src/main/java/org/jclouds/rest/config/CreateClientForCaller.java
This commit is contained in:
ddurnev 2011-10-03 12:53:32 +04:00
commit 1682c06ac3
42 changed files with 1955 additions and 377 deletions

View File

@ -61,7 +61,7 @@ import com.google.inject.Module;
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true)
@Test(groups = "live", singleThreaded = true)
public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public EC2ComputeServiceLiveTest() {

View File

@ -18,6 +18,8 @@
*/
package org.jclouds.eucalyptus.compute;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.ec2.compute.EC2ComputeServiceLiveTest;
import org.jclouds.http.HttpResponseException;
import org.testng.annotations.Test;
@ -70,4 +72,8 @@ public class EucalyptusComputeServiceLiveTest extends EC2ComputeServiceLiveTest
super.testDestroyNodes();
}
protected void checkResponseEqualsHostname(ExecResponse execResponse, NodeMetadata node1) {
// hostname is not predictable based on node metadata
assert execResponse.getOutput().trim().equals("ubuntu");
}
}

View File

@ -44,6 +44,8 @@ import com.google.inject.assistedinject.AssistedInject;
* @author Adrian Cole
*/
public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
public static final String MARKER = "RUN_SCRIPT_AS_ROOT_SSH";
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
@ -102,9 +104,9 @@ public class RunScriptOnNodeUsingSsh implements RunScriptOnNode {
public String execAsRoot(String command) {
if (node.getCredentials().identity.equals("root")) {
} else if (node.getAdminPassword() != null) {
command = String.format("echo '%s'|sudo -S %s", node.getAdminPassword(), command);
command = String.format("sudo -S sh <<'%s'\n%s\n%s%s\n", MARKER, node.getAdminPassword(), command, MARKER);
} else {
command = "sudo " + command;
command = String.format("sudo sh <<'%s'\n%s%s\n", MARKER, command, MARKER);
}
return command;
}

View File

@ -20,6 +20,8 @@ package org.jclouds.compute.predicates;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.Set;
import javax.annotation.Resource;
import javax.inject.Singleton;
@ -29,6 +31,7 @@ import org.jclouds.compute.domain.NodeState;
import org.jclouds.logging.Logger;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
/**
@ -42,13 +45,19 @@ public class NodePresentAndInIntendedState implements Predicate<NodeMetadata> {
private final ComputeService client;
private final NodeState intended;
private final Set<NodeState> invalids;
@Resource
protected Logger logger = Logger.NULL;
@Inject
public NodePresentAndInIntendedState(NodeState intended, ComputeService client) {
this(intended, ImmutableSet.of(NodeState.ERROR), client);
}
public NodePresentAndInIntendedState(NodeState intended, Set<NodeState> invalids, ComputeService client) {
this.intended = intended;
this.client = client;
this.invalids = invalids;
}
public boolean apply(NodeMetadata node) {
@ -57,9 +66,9 @@ public class NodePresentAndInIntendedState implements Predicate<NodeMetadata> {
if (node == null)
return false;
logger.trace("%s: looking for node state %s: currently: %s", node.getId(), intended, node.getState());
if (node.getState() == NodeState.ERROR)
if (invalids.contains(node.getState()))
throw new IllegalStateException("node " + node.getId() + " in location " + node.getLocation()
+ " is in error state");
+ " is in invalid state "+node.getState());
return node.getState() == intended;
}

View File

@ -23,6 +23,7 @@ import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeState;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Inject;
/**
@ -36,6 +37,6 @@ public class NodeRunning extends NodePresentAndInIntendedState {
@Inject
public NodeRunning(ComputeService client) {
super(NodeState.RUNNING, client);
super(NodeState.RUNNING, ImmutableSet.of(NodeState.ERROR, NodeState.TERMINATED), client);
}
}

View File

@ -0,0 +1,139 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.compute.callable;
import com.google.common.base.Function;
import org.jclouds.compute.callables.RunScriptOnNodeUsingSsh;
import org.jclouds.compute.domain.ExecResponse;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.Credentials;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.scriptbuilder.statements.login.UserAdd;
import org.jclouds.ssh.SshClient;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import static org.easymock.EasyMock.*;
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
import static org.jclouds.scriptbuilder.domain.Statements.exec;
/**
* @author Adam Lowe
*/
@Test(groups={"unit"}, singleThreaded = true)
public class RunScriptOnNodeUsingSshTest {
private SshClient sshClient;
private NodeMetadata node;
private Function<NodeMetadata, SshClient> sshFactory;
@BeforeMethod(groups={"unit"})
public void init() {
sshClient = createMock(SshClient.class);
sshFactory = new Function<NodeMetadata, SshClient>() {
@Override
public SshClient apply(@Nullable NodeMetadata nodeMetadata) {
return sshClient;
}
};
node = createMock(NodeMetadata.class);
expect(node.getCredentials()).andReturn(new Credentials("tester", "notalot"));
expect(node.getAdminPassword()).andReturn(null).atLeastOnce();
replay(node);
}
public void simpleTest() {
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node, exec("echo $USER\necho $USER"),
wrapInInitScript(false).runAsRoot(false));
testMe.init();
sshClient.connect();
expect(sshClient.getUsername()).andReturn("tester");
expect(sshClient.getHostAddress()).andReturn("somewhere.example.com");
expect(sshClient.exec("echo $USER\n" +
"echo $USER\n")).andReturn(new ExecResponse("tester\ntester\n", null, 0));
sshClient.disconnect();
replay(sshClient);
testMe.call();
}
public void simpleRootTest() {
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node, exec("echo $USER\necho $USER"),
wrapInInitScript(false).runAsRoot(true));
testMe.init();
sshClient.connect();
expect(sshClient.getUsername()).andReturn("tester");
expect(sshClient.getHostAddress()).andReturn("somewhere.example.com");
expect(sshClient.exec("sudo sh <<'RUN_SCRIPT_AS_ROOT_SSH'\n" +
"echo $USER\n" +
"echo $USER\n" +
"RUN_SCRIPT_AS_ROOT_SSH\n")).andReturn(new ExecResponse("root\nroot\n", null, 0));
sshClient.disconnect();
replay(sshClient);
testMe.call();
}
public void simpleRootTestWithSudoPassword() {
node = createMock(NodeMetadata.class);
expect(node.getCredentials()).andReturn(new Credentials("tester", "notalot"));
expect(node.getAdminPassword()).andReturn("testpassword!").atLeastOnce();
replay(node);
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node, exec("echo $USER\necho $USER"),
wrapInInitScript(false).runAsRoot(true));
testMe.init();
sshClient.connect();
expect(sshClient.getUsername()).andReturn("tester");
expect(sshClient.getHostAddress()).andReturn("somewhere.example.com");
expect(sshClient.exec("sudo -S sh <<'RUN_SCRIPT_AS_ROOT_SSH'\n" +
"testpassword!\n" +
"echo $USER\n" +
"echo $USER\n" +
"RUN_SCRIPT_AS_ROOT_SSH\n")).andReturn(new ExecResponse("root\nroot\n", null, 0));
sshClient.disconnect();
replay(sshClient);
testMe.call();
}
public void testUserAddAsRoot() {
RunScriptOnNodeUsingSsh testMe = new RunScriptOnNodeUsingSsh(sshFactory, node,
UserAdd.builder().login("testuser").build(),
wrapInInitScript(false).runAsRoot(true).overrideLoginCredentialWith("test"));
testMe.init();
sshClient.connect();
expect(sshClient.getUsername()).andReturn("tester");
expect(sshClient.getHostAddress()).andReturn("somewhere.example.com");
expect(sshClient.exec("sudo sh <<'RUN_SCRIPT_AS_ROOT_SSH'\n" +
"mkdir -p /home/users/testuser\n" +
"useradd -s /bin/bash -d /home/users/testuser testuser\n" +
"chown -R testuser /home/users/testuser\n" +
"RUN_SCRIPT_AS_ROOT_SSH\n")).andReturn(new ExecResponse("done", null, 0));
sshClient.disconnect();
replay(sshClient);
testMe.call();
}
}

View File

@ -0,0 +1,82 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jclouds.compute.predicates;
import static org.easymock.EasyMock.expect;
import static org.easymock.classextension.EasyMock.createMock;
import static org.easymock.classextension.EasyMock.replay;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeState;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
/**
* Tests possible uses of OperatingSystemPredicates
*
* @author Aled Sage
*/
@Test(singleThreaded = true, testName = "NodePredicatesTest")
public class NodePredicatesTest {
private NodeMetadata node;
private ComputeService computeService;
@BeforeMethod
public void setUp() throws Exception {
node = createMock(NodeMetadata.class);
computeService = createMock(ComputeService.class);
expect(node.getId()).andReturn("myid").anyTimes();
expect(computeService.getNodeMetadata("myid")).andReturn(node).anyTimes();
expect(node.getLocation()).andReturn(null).anyTimes();
}
@Test
public void testNodeRunningReturnsTrueWhenRunning() {
expect(node.getState()).andReturn(NodeState.RUNNING).atLeastOnce();
replay(node);
replay(computeService);
NodeRunning nodeRunning = new NodeRunning(computeService);
Assert.assertTrue(nodeRunning.apply(node));
}
@Test(expectedExceptions = IllegalStateException.class)
public void testNodeRunningFailsOnTerminated() {
expect(node.getState()).andReturn(NodeState.TERMINATED).atLeastOnce();
replay(node);
replay(computeService);
NodeRunning nodeRunning = new NodeRunning(computeService);
nodeRunning.apply(node);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testNodeRunningFailsOnError() {
expect(node.getState()).andReturn(NodeState.ERROR).atLeastOnce();
replay(node);
replay(computeService);
NodeRunning nodeRunning = new NodeRunning(computeService);
nodeRunning.apply(node);
}
}

View File

@ -104,7 +104,7 @@
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>1.7.1</version>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>

View File

@ -35,6 +35,8 @@ import com.google.inject.TypeLiteral;
import com.google.inject.name.Names;
/**
* ClientProvider makes the primary interface for the provider context. ex. {@code
* context.getProviderSpecificContext().getApi()} is created by ClientProvider, which is a singleton
*
* @author Adrian Cole
*/
@ -47,8 +49,7 @@ public class ClientProvider<S, A> implements Provider<S> {
private final Map<Class<?>, Class<?>> sync2Async;
@Inject
ClientProvider(Class<S> syncClientType, Class<A> asyncClientType,
Map<Class<?>, Class<?>> sync2Async) {
ClientProvider(Class<S> syncClientType, Class<A> asyncClientType, Map<Class<?>, Class<?>> sync2Async) {
this.asyncClientType = asyncClientType;
this.syncClientType = syncClientType;
this.sync2Async = sync2Async;

View File

@ -36,6 +36,9 @@ import com.google.common.cache.Cache;
import com.google.common.cache.CacheLoader;
/**
* CreateClientForCaller is parameterized, so clients it creates aren't singletons. For example,
* CreateClientForCaller satisfies a call like this:
* {@code context.getProviderSpecificContext().getApi().getOrgClientForName(name)}
*
* @author Adrian Cole
*/
@ -57,8 +60,7 @@ public class CreateClientForCaller extends CacheLoader<ClassMethodArgs, Object>
public Object load(ClassMethodArgs from) throws ExecutionException {
Class<?> syncClass = from.getMethod().getReturnType();
Class<?> asyncClass = sync2Async.get(syncClass);
checkState(asyncClass != null, "configuration error, sync class " + syncClass
+ " not mapped to an async class");
checkState(asyncClass != null, "configuration error, sync class " + syncClass + " not mapped to an async class");
Object asyncClient = asyncMap.get(from);
checkState(asyncClient != null, "configuration error, sync client for " + from + " not found");
try {

View File

@ -46,9 +46,9 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.SortedSet;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import javax.annotation.Resource;
@ -77,7 +77,6 @@ import org.jclouds.http.HttpUtils;
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.http.functions.ParseSax;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.http.functions.ParseURIFromListOrLocationHeaderIf20x;
import org.jclouds.http.functions.ReleasePayloadAndReturn;
import org.jclouds.http.functions.ReturnInputStream;
@ -87,6 +86,7 @@ import org.jclouds.http.functions.UnwrapOnlyJsonValue;
import org.jclouds.http.functions.UnwrapOnlyJsonValueInSet;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue;
import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet;
import org.jclouds.http.functions.ParseSax.HandlerWithResult;
import org.jclouds.http.options.HttpRequestOptions;
import org.jclouds.http.utils.ModifyRequest;
import org.jclouds.internal.ClassMethodArgs;
@ -135,6 +135,7 @@ import org.jclouds.util.Strings2;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Throwables;
@ -144,12 +145,12 @@ import com.google.common.cache.CacheLoader;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.ImmutableSet.Builder;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Inject;
import com.google.inject.Injector;
@ -959,6 +960,27 @@ public class RestAnnotationProcessor<T> {
}
if (shouldBreak)
break OUTER;
} else {
// either arg is null, or request.getArgs().size() < entry.getKey() + 1
// in either case, we require that null be allowed
// (first, however, let's make sure we have enough args on the actual method)
if (entry.getKey() >= request.getJavaMethod().getParameterAnnotations().length) {
// not known whether this happens
throw new IllegalArgumentException("Argument index " + (entry.getKey() + 1)
+ " is out of bounds for method " + request.getJavaMethod());
}
if (request.getJavaMethod().isVarArgs()
&& entry.getKey() + 1 == request.getJavaMethod().getParameterTypes().length)
// allow null/missing for var args
continue OUTER;
Annotation[] annotations = request.getJavaMethod().getParameterAnnotations()[entry.getKey()];
for (Annotation a : annotations) {
if (Nullable.class.isAssignableFrom(a.annotationType()))
continue OUTER;
}
Preconditions.checkNotNull(null, request.getJavaMethod().getName() + " parameter " + (entry.getKey() + 1));
}
}
@ -1093,7 +1115,9 @@ public class RestAnnotationProcessor<T> {
options.contentType(param.contentType());
if (!PartParam.NO_FILENAME.equals(param.filename()))
options.filename(Strings2.replaceTokens(param.filename(), iterable));
Part part = Part.create(param.name(), newPayload(args[entry.getKey()]), options);
Object arg = args[entry.getKey()];
Preconditions.checkNotNull(arg, param.name());
Part part = Part.create(param.name(), newPayload(arg), options);
parts.add(part);
}
}
@ -1200,7 +1224,9 @@ public class RestAnnotationProcessor<T> {
ParamParser extractor = (ParamParser) extractors.iterator().next();
paramValue = injector.getInstance(extractor.value()).apply(args[entry.getKey()]);
} else {
paramValue = args[entry.getKey()].toString();
Object pvo = args[entry.getKey()];
Preconditions.checkNotNull(pvo, paramKey);
paramValue = pvo.toString();
}
formParamValues.put(paramKey, paramValue);
}

View File

@ -143,6 +143,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.binders.BindToStringPayload;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.util.Strings2;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@ -552,6 +553,9 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
@POST
void post(@Nullable @BinderParam(BindToStringPayload.class) String content);
@POST
void postNonnull(@BinderParam(BindToStringPayload.class) String content);
@POST
public void postAsJson(@BinderParam(BindToJsonPayload.class) String content);
@ -587,7 +591,7 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
assertPayloadEquals(request, "data", "application/unknown", false);
}
public void testCreatePostRequestNullOk() throws SecurityException, NoSuchMethodException, IOException {
public void testCreatePostRequestNullOk1() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPost.class.getMethod("post", String.class);
HttpRequest request = factory(TestPost.class).createRequest(method);
@ -596,6 +600,41 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
assertPayloadEquals(request, null, "application/unknown", false);
}
public void testCreatePostRequestNullOk2() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPost.class.getMethod("post", String.class);
HttpRequest request = factory(TestPost.class).createRequest(method, (String) null);
assertRequestLineEquals(request, "POST http://localhost:9999 HTTP/1.1");
assertNonPayloadHeadersEqual(request, "");
assertPayloadEquals(request, null, "application/unknown", false);
}
public void testCreatePostRequestNullNotOk1() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPost.class.getMethod("postNonnull", String.class);
try {
HttpRequest request = factory(TestPost.class).createRequest(method);
Assert
.fail("call should have failed with illegal null parameter, not permitted " + request
+ " to be created");
} catch (NullPointerException e) {
Assert.assertTrue(e.toString().indexOf("postNonnull parameter 1") >= 0,
"Error message should have referred to 'parameter 1': " + e);
}
}
public void testCreatePostRequestNullNotOk2() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPost.class.getMethod("postNonnull", String.class);
try {
HttpRequest request = factory(TestPost.class).createRequest(method, (String) null);
Assert
.fail("call should have failed with illegal null parameter, not permitted " + request
+ " to be created");
} catch (NullPointerException e) {
Assert.assertTrue(e.toString().indexOf("postNonnull parameter 1") >= 0,
"Error message should have referred to parameter 'parameter 1': " + e);
}
}
public void testCreatePostJsonRequest() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestPost.class.getMethod("postAsJson", String.class);
HttpRequest request = factory(TestPost.class).createRequest(method, "data");
@ -684,6 +723,17 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
"----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false);
}
public void testMultipartWithStringPartNullNotOkay() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestMultipartForm.class.getMethod("withStringPart", String.class);
try {
GeneratedHttpRequest<TestMultipartForm> httpRequest = factory(TestMultipartForm.class).createRequest(method,
(String)null);
Assert.fail("call should have failed with illegal null parameter, not permitted "+httpRequest+" to be created");
} catch (NullPointerException e) {
Assert.assertTrue(e.toString().indexOf("fooble")>=0, "Error message should have referred to parameter 'fooble': "+e);
}
}
public void testMultipartWithParamStringPart() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestMultipartForm.class.getMethod("withParamStringPart", String.class, String.class);
GeneratedHttpRequest<TestMultipartForm> httpRequest = factory(TestMultipartForm.class).createRequest(method,
@ -702,6 +752,17 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest {
"----JCLOUDS----\r\n", "multipart/form-data; boundary=--JCLOUDS--", false);
}
public void testMultipartWithParamStringPartNullNotOk() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestMultipartForm.class.getMethod("withParamStringPart", String.class, String.class);
try {
GeneratedHttpRequest<TestMultipartForm> httpRequest = factory(TestMultipartForm.class).createRequest(method,
null, "foobledata");
Assert.fail("call should have failed with illegal null parameter, not permitted "+httpRequest+" to be created");
} catch (NullPointerException e) {
Assert.assertTrue(e.toString().indexOf("name")>=0, "Error message should have referred to parameter 'name': "+e);
}
}
public void testMultipartWithParamFilePart() throws SecurityException, NoSuchMethodException, IOException {
Method method = TestMultipartForm.class.getMethod("withParamFilePart", String.class, File.class);
File file = File.createTempFile("foo", "bar");

View File

@ -27,7 +27,7 @@ import org.testng.annotations.Test;
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest")
@Test(groups = "live", singleThreaded = true, testName = "EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest")
public class EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest extends EucalyptusComputeServiceLiveTest {
public EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest() {
@ -45,8 +45,4 @@ public class EucalyptusPartnerCloudEucalyptusComputeServiceLiveTest extends Euca
return overrides;
}
// test hangs
@Override
public void testExtendedOptionsAndLogin() throws Exception {
}
}

View File

@ -39,6 +39,7 @@ public class SoftLayerPropertiesBuilder extends PropertiesBuilder {
properties.setProperty(PROPERTY_ENDPOINT, "https://api.softlayer.com/rest");
properties.setProperty(PROPERTY_API_VERSION, "3");
properties.setProperty(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME, "Cloud Server");
properties.setProperty(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY, ""+60*60*1000);
properties.setProperty(PROPERTY_ISO3166_CODES, "SG,US-CA,US-TX,US-VA,US-WA,US-TX");
return properties;
}

View File

@ -36,6 +36,7 @@ import org.jclouds.softlayer.compute.functions.ProductItemsToHardware;
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata;
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
import org.jclouds.softlayer.compute.strategy.SoftLayerComputeServiceAdapter;
import org.jclouds.softlayer.config.SoftLayerParserModule;
import org.jclouds.softlayer.domain.Datacenter;
import org.jclouds.softlayer.domain.ProductItem;
import org.jclouds.softlayer.domain.VirtualGuest;
@ -59,6 +60,7 @@ public class SoftLayerComputeServiceContextModule extends
@Override
protected void configure() {
super.configure();
install(new SoftLayerParserModule());
bind(new TypeLiteral<ComputeServiceAdapter<VirtualGuest, Set<ProductItem>, ProductItem, Datacenter>>() {})
.to(SoftLayerComputeServiceAdapter.class);
bind(new TypeLiteral<Function<VirtualGuest, NodeMetadata>>() {})

View File

@ -48,7 +48,7 @@ import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
@Singleton
public class ProductItemsToHardware implements Function<Set<ProductItem>, Hardware> {
private static final double CORE_SPEED = 2.0;
static final double CORE_SPEED = 2.0;
@Override
public Hardware apply(Set<ProductItem> items) {

View File

@ -20,6 +20,7 @@ package org.jclouds.softlayer.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
import static org.jclouds.softlayer.compute.functions.ProductItemsToHardware.CORE_SPEED;
import java.util.Map;
import java.util.Set;
@ -29,13 +30,10 @@ import javax.inject.Singleton;
import org.jclouds.collect.FindResourceInSet;
import org.jclouds.collect.Memoized;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.NodeMetadataBuilder;
import org.jclouds.compute.domain.NodeState;
import org.jclouds.compute.domain.*;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.softlayer.domain.Datacenter;
import org.jclouds.softlayer.domain.VirtualGuest;
import com.google.common.base.Function;
@ -50,25 +48,18 @@ import com.google.common.collect.ImmutableSet;
public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMetadata> {
public static final Map<VirtualGuest.State, NodeState> serverStateToNodeState = ImmutableMap
.<VirtualGuest.State, NodeState> builder()
.put(VirtualGuest.State.HALTED, NodeState.PENDING)
.put(VirtualGuest.State.PAUSED, NodeState.SUSPENDED)
.put(VirtualGuest.State.RUNNING, NodeState.RUNNING)
.put(VirtualGuest.State.UNRECOGNIZED, NodeState.UNRECOGNIZED)
.build();
.<VirtualGuest.State, NodeState> builder().put(VirtualGuest.State.HALTED, NodeState.PENDING).put(
VirtualGuest.State.PAUSED, NodeState.SUSPENDED).put(VirtualGuest.State.RUNNING, NodeState.RUNNING)
.put(VirtualGuest.State.UNRECOGNIZED, NodeState.UNRECOGNIZED).build();
private final FindHardwareForVirtualGuest findHardwareForVirtualGuest;
private final FindLocationForVirtualGuest findLocationForVirtualGuest;
private final FindImageForVirtualGuest findImageForVirtualGuest;
private final Map<String, Credentials> credentialStore;
private final FindLocationForVirtualGuest findLocationForVirtualGuest;
@Inject
VirtualGuestToNodeMetadata(Map<String, Credentials> credentialStore, FindHardwareForVirtualGuest findHardwareForVirtualGuest,
FindLocationForVirtualGuest findLocationForVirtualGuest, FindImageForVirtualGuest findImageForVirtualGuest) {
VirtualGuestToNodeMetadata(Map<String, Credentials> credentialStore,
FindLocationForVirtualGuest findLocationForVirtualGuest) {
this.credentialStore = checkNotNull(credentialStore, "credentialStore");
this.findHardwareForVirtualGuest = checkNotNull(findHardwareForVirtualGuest, "findHardwareForVirtualGuest");
this.findLocationForVirtualGuest = checkNotNull(findLocationForVirtualGuest, "findLocationForVirtualGuest");
this.findImageForVirtualGuest = checkNotNull(findImageForVirtualGuest, "findImageForVirtualGuest");
}
@Override
@ -76,64 +67,57 @@ public class VirtualGuestToNodeMetadata implements Function<VirtualGuest, NodeMe
// convert the result object to a jclouds NodeMetadata
NodeMetadataBuilder builder = new NodeMetadataBuilder();
builder.ids(from.getId() + "");
builder.name(from.getNotes());
builder.name(from.getHostname());
builder.location(findLocationForVirtualGuest.apply(from));
builder.group(parseGroupFromName(from.getNotes()));
builder.group(parseGroupFromName(from.getHostname()));
// TODO determine image id (product price)from virtual guest
// builder.imageId(from.imageId + "");
Image image = findImageForVirtualGuest.apply(from);
if (image != null)
builder.operatingSystem(image.getOperatingSystem());
builder.hardware(findHardwareForVirtualGuest.apply(from));
// TODO get state
// builder.state(serverStateToNodeState.get(from.getState()));
// TODO make operating system from virtual guest
// builder.operatingSystem(OperatingSystem.builder()...);
builder.hardware(getHardware(from));
builder.state(serverStateToNodeState.get(from.getPowerState().getKeyName()));
// These are null for 'bad' guest orders in the HALTED state.
if (from.getPrimaryIpAddress() != null)
builder.publicAddresses(ImmutableSet.<String> of(from.getPrimaryIpAddress()));
if (from.getPrimaryBackendIpAddress() != null)
builder.privateAddresses(ImmutableSet.<String> of(from.getPrimaryBackendIpAddress()));
builder.credentials(credentialStore.get("node#" + from.getId()));
return builder.build();
}
@Singleton
public static class FindHardwareForVirtualGuest extends FindResourceInSet<VirtualGuest, Hardware> {
@Inject
public FindHardwareForVirtualGuest(@Memoized Supplier<Set<? extends Hardware>> hardware) {
super(hardware);
}
@Override
public boolean matches(VirtualGuest from, Hardware input) {
return input.getProviderId().equals(from.getId() + "");
}
}
@Singleton
public static class FindImageForVirtualGuest extends FindResourceInSet<VirtualGuest, Image> {
@Inject
public FindImageForVirtualGuest(@Memoized Supplier<Set<? extends Image>> hardware) {
super(hardware);
}
@Override
public boolean matches(VirtualGuest from, Image input) {
// TODO determine the price list from the virtual guest which would have the image in it.
return false;
}
}
@Singleton
public static class FindLocationForVirtualGuest extends FindResourceInSet<VirtualGuest, Location> {
@Inject
public FindLocationForVirtualGuest(@Memoized Supplier<Set<? extends Location>> hardware) {
super(hardware);
public FindLocationForVirtualGuest(@Memoized Supplier<Set<? extends Location>> location) {
super(location);
}
@Override
public boolean matches(VirtualGuest from, Location input) {
// TODO determine the price list from the virtual guest which would have the image in it.
Datacenter dc = from.getDatacenter();
if (dc == null)
return false;
return input.getId().equals(Integer.toString(dc.getId()));
}
}
private Hardware getHardware(VirtualGuest from) {
HardwareBuilder builder = new HardwareBuilder().id("TODO");
final double cpus = from.getMaxCpu();
if (cpus>0) {
builder.processor(new Processor(cpus, CORE_SPEED));
}
final int maxMemory = from.getMaxMemory();
if (maxMemory>0) {
builder.ram(maxMemory);
}
return builder.build();
}
}

View File

@ -18,46 +18,37 @@
*/
package org.jclouds.softlayer.compute.strategy;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.softlayer.predicates.ProductItemPredicates.categoryCode;
import static org.jclouds.softlayer.predicates.ProductItemPredicates.matches;
import static org.jclouds.softlayer.predicates.ProductItemPredicates.units;
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.softlayer.SoftLayerClient;
import org.jclouds.softlayer.compute.functions.ProductItems;
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
import org.jclouds.softlayer.domain.BillingItemVirtualGuest;
import org.jclouds.softlayer.domain.Datacenter;
import org.jclouds.softlayer.domain.OperatingSystem;
import org.jclouds.softlayer.domain.Password;
import org.jclouds.softlayer.domain.ProductItem;
import org.jclouds.softlayer.domain.ProductItemPrice;
import org.jclouds.softlayer.domain.ProductOrder;
import org.jclouds.softlayer.domain.ProductPackage;
import org.jclouds.softlayer.domain.VirtualGuest;
import org.jclouds.softlayer.features.AccountClient;
import org.jclouds.softlayer.features.ProductPackageClient;
import org.jclouds.softlayer.reference.SoftLayerConstants;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.domain.Template;
import org.jclouds.domain.Credentials;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.softlayer.SoftLayerClient;
import org.jclouds.softlayer.compute.functions.ProductItems;
import org.jclouds.softlayer.compute.options.SoftLayerTemplateOptions;
import org.jclouds.softlayer.domain.*;
import org.jclouds.softlayer.features.AccountClient;
import org.jclouds.softlayer.features.ProductPackageClient;
import org.jclouds.softlayer.reference.SoftLayerConstants;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.softlayer.predicates.ProductItemPredicates.*;
import static org.jclouds.softlayer.predicates.ProductPackagePredicates.named;
/**
* defines the connection between the {@link SoftLayerClient} implementation and the jclouds
@ -73,12 +64,21 @@ public class SoftLayerComputeServiceAdapter implements
private final SoftLayerClient client;
private final String virtualGuestPackageName;
private final RetryablePredicate<VirtualGuest> loginDetailsTester;
private final long guestLoginDelay;
@Inject
public SoftLayerComputeServiceAdapter(SoftLayerClient client,
@Named(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME) String virtualGuestPackageName) {
@Named(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME) String virtualGuestPackageName,
VirtualGuestHasLoginDetailsPresent virtualGuestHasLoginDetailsPresent,
@Named(SoftLayerConstants.PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY) long guestLoginDelay) {
this.client = checkNotNull(client, "client");
this.virtualGuestPackageName = checkNotNull(virtualGuestPackageName, "virtualGuestPackageName");
checkArgument(guestLoginDelay > 500, "guestOrderDelay must be in milliseconds and greater than 500");
this.guestLoginDelay =guestLoginDelay;
this.loginDetailsTester = new RetryablePredicate<VirtualGuest>(virtualGuestHasLoginDetailsPresent,
guestLoginDelay);
}
@Override
@ -90,59 +90,28 @@ public class SoftLayerComputeServiceAdapter implements
"options class %s should have been assignable from SoftLayerTemplateOptions", template.getOptions()
.getClass());
Iterable<VirtualGuest> existing = findVirtualGuests(name,group);
if(!Iterables.isEmpty(existing)) {
throw new IllegalStateException(
"VirtualGuest(s) already exist with hostname:"+name+", group:"+group+". Existing:"+existing);
}
String domainName = template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName();
VirtualGuest newGuest = VirtualGuest.builder()
.domain(template.getOptions().as(SoftLayerTemplateOptions.class).getDomainName())
.hostname(name)
.build();
VirtualGuest newGuest = VirtualGuest.builder().domain(domainName).hostname(name).build();
ProductOrder order = ProductOrder.builder()
.packageId(getProductPackage().getId())
.location(template.getLocation().getId())
.quantity(1)
.useHourlyPricing(true)
.prices(getPrices(template))
.virtualGuest(newGuest)
.build();
ProductOrder order = ProductOrder.builder().packageId(getProductPackage().getId()).location(
template.getLocation().getId()).quantity(1).useHourlyPricing(true).prices(getPrices(template))
.virtualGuest(newGuest).build();
client.getVirtualGuestClient().orderVirtualGuest(order);
ProductOrderReceipt productOrderReceipt = client.getVirtualGuestClient().orderVirtualGuest(order);
VirtualGuest result = Iterables.get(productOrderReceipt.getOrderDetails().getVirtualGuests(), 0);
boolean orderInSystem = loginDetailsTester.apply(result);
VirtualGuest result = Iterables.getOnlyElement(findVirtualGuests(name, group));
Credentials credentials = new Credentials(null,null);
checkState(orderInSystem, "order for guest %s doesn't have login details within %sms", result, Long.toString(guestLoginDelay));
result = client.getVirtualGuestClient().getVirtualGuest(result.getId());
// This information is not always available.
OperatingSystem os = result.getOperatingSystem();
if(os!=null) {
Set<Password> passwords = os.getPasswords();
if(passwords.size()>0) {
Password pw = Iterables.get(passwords,0);
credentials = new Credentials(pw.getUsername(),pw.getPassword());
}
}
Password pw = Iterables.get(result.getOperatingSystem().getPasswords(),0);
Credentials credentials = new Credentials(pw.getUsername(), pw.getPassword());
credentialStore.put("node#" + result.getId(), credentials);
return result;
}
private Iterable<VirtualGuest> findVirtualGuests(String hostname,String domain) {
checkNotNull(hostname,"hostname");
checkNotNull(domain,"domain");
Set<VirtualGuest> result = Sets.newLinkedHashSet();
for( VirtualGuest guest : client.getVirtualGuestClient().listVirtualGuests()) {
if ( guest.getHostname().equals(hostname) && guest.getDomain().equals(domain)) {
result.add(guest);
}
}
return result;
}
private Iterable<ProductItemPrice> getPrices(Template template) {
Set<ProductItemPrice> result = Sets.newLinkedHashSet();
@ -161,8 +130,6 @@ public class SoftLayerComputeServiceAdapter implements
return result;
}
@Override
public Iterable<Set<ProductItem>> listHardwareProfiles() {
ProductPackage productPackage = getProductPackage();
@ -170,7 +137,8 @@ public class SoftLayerComputeServiceAdapter implements
Iterable<ProductItem> cpuItems = Iterables.filter(items, units("PRIVATE_CORE"));
Iterable<ProductItem> ramItems = Iterables.filter(items, categoryCode("ram"));
Iterable<ProductItem> sanItems = Iterables.filter(items, Predicates.and(matches(SAN_DESCRIPTION_REGEX),categoryCode("one_time_charge")));
Iterable<ProductItem> sanItems = Iterables.filter(items, Predicates.and(matches(SAN_DESCRIPTION_REGEX),
categoryCode("one_time_charge")));
Map<Float, ProductItem> cpuMap = Maps.uniqueIndex(cpuItems, ProductItems.capacity());
Map<Float, ProductItem> ramMap = Maps.uniqueIndex(ramItems, ProductItems.capacity());
@ -184,7 +152,8 @@ public class SoftLayerComputeServiceAdapter implements
Float cores = coresEntry.getKey();
ProductItem ramItem = ramMap.get(cores);
// Amount of RAM and number of cores must match.
if(ramItem==null) continue;
if (ramItem == null)
continue;
result.add(ImmutableSet.of(coresEntry.getValue(), ramItem, bootVolume));
}
@ -224,12 +193,13 @@ public class SoftLayerComputeServiceAdapter implements
@Override
public void destroyNode(String id) {
VirtualGuest guest = getNode(id);
if(guest==null) return;
if (guest == null)
return;
BillingItemVirtualGuest billingItem = guest.getBillingItem();
if (billingItem==null) return;
if (guest.getBillingItemId() == -1)
return;
client.getVirtualGuestClient().cancelService(billingItem.getId());
client.getVirtualGuestClient().cancelService(guest.getBillingItemId());
}
@Override
@ -246,4 +216,25 @@ public class SoftLayerComputeServiceAdapter implements
public void suspendNode(String id) {
client.getVirtualGuestClient().pauseVirtualGuest(Long.parseLong(id));
}
public static class VirtualGuestHasLoginDetailsPresent implements Predicate<VirtualGuest> {
private final SoftLayerClient client;
@Inject
public VirtualGuestHasLoginDetailsPresent(SoftLayerClient client) {
this.client = checkNotNull(client, "client was null");
}
@Override
public boolean apply(VirtualGuest guest) {
checkNotNull(guest, "virtual guest was null");
VirtualGuest newGuest = client.getVirtualGuestClient().getVirtualGuest(guest.getId());
boolean hasBackendIp = newGuest.getPrimaryBackendIpAddress() != null;
boolean hasPrimaryIp = newGuest.getPrimaryIpAddress() != null;
boolean hasPasswords = newGuest.getOperatingSystem()!=null && newGuest.getOperatingSystem().getPasswords().size() > 0;
return hasBackendIp && hasPrimaryIp && hasPasswords;
}
}
}

View File

@ -0,0 +1,114 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.config;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Map;
import javax.inject.Singleton;
import org.jclouds.softlayer.domain.Datacenter;
import org.jclouds.softlayer.domain.OperatingSystem;
import org.jclouds.softlayer.domain.PowerState;
import org.jclouds.softlayer.domain.VirtualGuest;
import com.google.common.collect.ImmutableMap;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
public class SoftLayerParserModule extends AbstractModule {
@Singleton
public static class VirtualGuestAdapter implements JsonSerializer<VirtualGuest>, JsonDeserializer<VirtualGuest> {
public JsonElement serialize(VirtualGuest src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src);
}
public VirtualGuest deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return apply(context.<VirtualGuestInternal> deserialize(json, VirtualGuestInternal.class));
}
public VirtualGuest apply(VirtualGuestInternal in) {
return in;
}
/**
* Internal class that flattens billingItem into billingItemId
*/
public static class VirtualGuestInternal extends VirtualGuest {
private BillingItem billingItem;
public VirtualGuestInternal(int accountId, Date createDate, boolean dedicatedAccountHostOnly, String domain,
String fullyQualifiedDomainName, String hostname, int id, Date lastVerifiedDate, int maxCpu,
String maxCpuUnits, int maxMemory, Date metricPollDate, Date modifyDate, String notes,
boolean privateNetworkOnly, int startCpus, int statusId, String uuid, String primaryBackendIpAddress,
String primaryIpAddress, int billingItemId, OperatingSystem operatingSystem, Datacenter datacenter,
PowerState powerState) {
super(accountId, createDate, dedicatedAccountHostOnly, domain, fullyQualifiedDomainName, hostname, id,
lastVerifiedDate, maxCpu, maxCpuUnits, maxMemory, metricPollDate, modifyDate, notes,
privateNetworkOnly, startCpus, statusId, uuid, primaryBackendIpAddress, primaryIpAddress,
billingItemId, operatingSystem, datacenter, powerState);
}
@Override
public int getBillingItemId() {
return billingItem != null ? billingItem.id : -1;
}
}
public static class BillingItem {
private int id = -1;
// for deserializer
BillingItem() {
}
public BillingItem(int id) {
this.id = id;
}
@Override
public String toString() {
return "[id=" + id + "]";
}
}
}
@Override
protected void configure() {
bind(new TypeLiteral<Map<Type, Object>>() {
}).toInstance(ImmutableMap.<Type, Object> of(VirtualGuest.class, new VirtualGuestAdapter()));
}
}

View File

@ -18,8 +18,7 @@
*/
package org.jclouds.softlayer.config;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.jclouds.http.HttpErrorHandler;
import org.jclouds.http.HttpRetryHandler;
import org.jclouds.http.RequiresHttp;
@ -33,17 +32,10 @@ import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule;
import org.jclouds.softlayer.SoftLayerAsyncClient;
import org.jclouds.softlayer.SoftLayerClient;
import org.jclouds.softlayer.features.AccountAsyncClient;
import org.jclouds.softlayer.features.AccountClient;
import org.jclouds.softlayer.features.DatacenterAsyncClient;
import org.jclouds.softlayer.features.DatacenterClient;
import org.jclouds.softlayer.features.ProductPackageAsyncClient;
import org.jclouds.softlayer.features.ProductPackageClient;
import org.jclouds.softlayer.features.VirtualGuestAsyncClient;
import org.jclouds.softlayer.features.VirtualGuestClient;
import org.jclouds.softlayer.features.*;
import org.jclouds.softlayer.handlers.SoftLayerErrorHandler;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
/**
* Configures the SoftLayer connection.

View File

@ -1,101 +0,0 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Strings.emptyToNull;
/**
*
* @author Jason King
* @see <a href= "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Billing_Item_Virtual_Guest"
* />
*/
public class BillingItemVirtualGuest implements Comparable<BillingItemVirtualGuest> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private int id = -1;
public Builder id(int id) {
this.id = id;
return this;
}
public static Builder fromBillingItemVirtualGuest(BillingItemVirtualGuest in) {
return BillingItemVirtualGuest.builder().id(in.getId());
}
}
private int id = -1;
// for deserializer
BillingItemVirtualGuest() {
}
public BillingItemVirtualGuest(int id) {
this.id = id;
}
@Override
public int compareTo(BillingItemVirtualGuest arg0) {
return new Integer(id).compareTo(arg0.getId());
}
/**
* @return The unique identifier for this billing item.
*/
public int getId() {
return id;
}
public Builder toBuilder() {
return Builder.fromBillingItemVirtualGuest(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (id ^ (id >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BillingItemVirtualGuest other = (BillingItemVirtualGuest) obj;
if (id != other.id)
return false;
return true;
}
@Override
public String toString() {
return "[id=" + id + "]";
}
}

View File

@ -132,6 +132,6 @@ public class OperatingSystem implements Comparable<OperatingSystem> {
@Override
public String toString() {
return "OperatingSystem [id=" + id + ", passwords=" + passwords + "]";
return "[id=" + id + ", passwords=" + passwords + "]";
}
}

View File

@ -0,0 +1,102 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.domain;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The power state class provides a common set of values for which a guest's power state will be presented in the SoftLayer API.
* @author Jason King
* @see <a href= "http://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest_Power_State"
* />
*/
public class PowerState implements Comparable<PowerState> {
public static Builder builder() {
return new Builder();
}
public static class Builder {
private VirtualGuest.State keyName;
public Builder keyName(VirtualGuest.State keyName) {
this.keyName = keyName;
return this;
}
public PowerState build() {
return new PowerState(keyName);
}
public static Builder fromAddress(PowerState in) {
return PowerState.builder().keyName(in.getKeyName());
}
}
private VirtualGuest.State keyName;
// for deserializer
PowerState() {
}
public PowerState(VirtualGuest.State keyName) {
this.keyName = checkNotNull(keyName,"keyName cannot be null or empty:"+keyName);
}
@Override
public int compareTo(PowerState arg0) {
return keyName.compareTo(arg0.keyName);
}
/**
* Maps onto {@code VirtualGuest.State}
* @return The key name of a power state.
*
*/
public VirtualGuest.State getKeyName() {
return keyName;
}
public Builder toBuilder() {
return Builder.fromAddress(this);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
PowerState that = (PowerState) o;
if (keyName != null ? !keyName.equals(that.keyName) : that.keyName != null)
return false;
return true;
}
@Override
public int hashCode() {
return keyName != null ? keyName.hashCode() : 0;
}
@Override
public String toString() {
return "[keyName=" + keyName + "]";
}
}

View File

@ -31,30 +31,38 @@ public class ProductOrderReceipt implements Comparable<ProductOrderReceipt> {
public static class Builder {
private int orderId = -1;
private ProductOrder orderDetails;
public Builder orderId(int orderId) {
this.orderId = orderId;
return this;
}
public Builder orderDetails(ProductOrder orderDetails) {
this.orderDetails = orderDetails;
return this;
}
public ProductOrderReceipt build() {
return new ProductOrderReceipt(orderId);
return new ProductOrderReceipt(orderId,orderDetails);
}
public static Builder fromAddress(ProductOrderReceipt in) {
return ProductOrderReceipt.builder().orderId(in.getOrderId());
return ProductOrderReceipt.builder().orderId(in.getOrderId()).orderDetails(in.getOrderDetails());
}
}
private int orderId = -1;
private ProductOrder orderDetails;
// for deserializer
ProductOrderReceipt() {
}
public ProductOrderReceipt(int orderId) {
public ProductOrderReceipt(int orderId,ProductOrder orderDetails) {
this.orderId = orderId;
this.orderDetails = orderDetails;
}
@Override
@ -69,6 +77,16 @@ public class ProductOrderReceipt implements Comparable<ProductOrderReceipt> {
return orderId;
}
/**
* This is a copy of the SoftLayer_Container_Product_Order
* which holds all the data related to an order.
* This will only return when an order is processed successfully.
* It will contain all the items in an order as well as the order totals.
*/
public ProductOrder getOrderDetails() {
return orderDetails;
}
public Builder toBuilder() {
return Builder.fromAddress(this);
}
@ -97,7 +115,7 @@ public class ProductOrderReceipt implements Comparable<ProductOrderReceipt> {
@Override
public String toString() {
return "[orderId=" + orderId + "]";
return "[orderId=" + orderId + ", orderDetails="+orderDetails+"]";
}

View File

@ -18,12 +18,12 @@
*/
package org.jclouds.softlayer.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.CaseFormat;
import com.google.gson.annotations.SerializedName;
import java.util.Date;
import com.google.common.base.CaseFormat;
import com.google.gson.annotations.SerializedName;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The virtual guest data type presents the structure in which all virtual guests will be presented.
@ -74,8 +74,10 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
private String uuid;
private String primaryBackendIpAddress;
private String primaryIpAddress;
private BillingItemVirtualGuest billingItem;
private int billingItemId;
private OperatingSystem operatingSystem;
private Datacenter datacenter;
private PowerState powerState;
public Builder id(int id) {
this.id = id;
@ -177,8 +179,8 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
return this;
}
public Builder billingItem(BillingItemVirtualGuest billingItem) {
this.billingItem = billingItem;
public Builder billingItemId(int billingItemId) {
this.billingItemId = billingItemId;
return this;
}
@ -187,12 +189,22 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
return this;
}
public Builder datacenter(Datacenter datacenter) {
this.datacenter = datacenter;
return this;
}
public Builder powerState(PowerState powerState) {
this.powerState = powerState;
return this;
}
public VirtualGuest build() {
return new VirtualGuest(accountId, createDate, dedicatedAccountHostOnly, domain,
fullyQualifiedDomainName, hostname, id, lastVerifiedDate, maxCpu,
maxCpuUnits, maxMemory, metricPollDate, modifyDate, notes,
privateNetworkOnly, startCpus, statusId, uuid, primaryBackendIpAddress,
primaryIpAddress,billingItem,operatingSystem);
primaryIpAddress, billingItemId,operatingSystem,datacenter,powerState);
}
public static Builder fromVirtualGuest(VirtualGuest in) {
@ -217,9 +229,10 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
.uuid(in.getUuid())
.primaryBackendIpAddress(in.getPrimaryBackendIpAddress())
.primaryIpAddress(in.getPrimaryIpAddress())
.billingItem(in.getBillingItem())
.operatingSystem(in.getOperatingSystem());
.billingItemId(in.getBillingItemId())
.operatingSystem(in.getOperatingSystem())
.datacenter(in.getDatacenter())
.powerState(in.getPowerState());
}
}
@ -270,8 +283,10 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
private String primaryBackendIpAddress;
private String primaryIpAddress;
private BillingItemVirtualGuest billingItem;
private int billingItemId = -1;
private OperatingSystem operatingSystem;
private Datacenter datacenter;
private PowerState powerState;
// for deserializer
VirtualGuest() {
@ -282,7 +297,7 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
String fullyQualifiedDomainName, String hostname, int id, Date lastVerifiedDate, int maxCpu,
String maxCpuUnits, int maxMemory, Date metricPollDate, Date modifyDate, String notes,
boolean privateNetworkOnly, int startCpus, int statusId, String uuid, String primaryBackendIpAddress,
String primaryIpAddress,BillingItemVirtualGuest billingItem, OperatingSystem operatingSystem) {
String primaryIpAddress,int billingItemId, OperatingSystem operatingSystem, Datacenter datacenter, PowerState powerState) {
this.accountId = accountId;
this.createDate = createDate;
this.dedicatedAccountHostOnly = dedicatedAccountHostOnly;
@ -303,8 +318,10 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
this.uuid = uuid;
this.primaryBackendIpAddress = primaryBackendIpAddress;
this.primaryIpAddress = primaryIpAddress;
this.billingItem = billingItem;
this.billingItemId = billingItemId;
this.operatingSystem = operatingSystem;
this.datacenter = datacenter;
this.powerState = powerState;
}
@Override
@ -458,8 +475,8 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
/**
* @return The billing item for a CloudLayer Compute Instance.
*/
public BillingItemVirtualGuest getBillingItem() {
return billingItem;
public int getBillingItemId() {
return billingItemId;
}
/**
@ -469,6 +486,21 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
return operatingSystem;
}
/**
* @return The guest's datacenter
*/
public Datacenter getDatacenter() {
return datacenter;
}
/**
* @return The current power state of a virtual guest.
*/
public PowerState getPowerState() {
return powerState;
}
@Override
public int hashCode() {
final int prime = 31;
@ -493,8 +525,10 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
result = prime * result + startCpus;
result = prime * result + statusId;
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
result = prime * result + ((billingItem == null) ? 0 : billingItem.hashCode());
result = prime * result + (getBillingItemId() ^ (getBillingItemId() >>> 32));
result = prime * result + ((operatingSystem == null) ? 0 : operatingSystem.hashCode());
result = prime * result + ((datacenter == null) ? 0 : datacenter.hashCode());
result = prime * result + ((powerState == null) ? 0 : powerState.hashCode());
return result;
}
@ -583,16 +617,23 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
return false;
} else if (!uuid.equals(other.uuid))
return false;
if (billingItem == null) {
if (other.billingItem != null)
return false;
} else if (!billingItem.equals(other.billingItem))
if (getBillingItemId() != other.getBillingItemId())
return false;
if (operatingSystem == null) {
if (other.operatingSystem != null)
return false;
} else if (!operatingSystem.equals(other.operatingSystem))
return false;
if (datacenter == null) {
if (other.datacenter != null)
return false;
} else if (!datacenter.equals(other.datacenter))
return false;
if (powerState == null) {
if (other.powerState != null)
return false;
} else if (!powerState.equals(other.powerState))
return false;
return true;
}
@ -605,7 +646,8 @@ public class VirtualGuest implements Comparable<VirtualGuest> {
+ ", metricPollDate=" + metricPollDate + ", modifyDate=" + modifyDate + ", notes=" + notes
+ ", primaryBackendIpAddress=" + primaryBackendIpAddress + ", primaryIpAddress=" + primaryIpAddress
+ ", privateNetworkOnly=" + privateNetworkOnly + ", startCpus=" + startCpus + ", statusId=" + statusId
+ ", uuid=" + uuid + ", billingItem="+billingItem+", operatingSystem="+operatingSystem+"]";
+ ", uuid=" + uuid + ", billingItemId="+getBillingItemId()+", operatingSystem="+operatingSystem+", datacenter="+datacenter
+ ", powerState="+powerState+"]";
}
}

View File

@ -34,6 +34,12 @@ public interface SoftLayerConstants {
*/
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_PACKAGE_NAME = "jclouds.softlayer.virtualguest.package-name";
/**
* number of milliseconds to wait for an order to arrive on the api.
*/
public static final String PROPERTY_SOFTLAYER_VIRTUALGUEST_LOGIN_DETAILS_DELAY = "jclouds.softlayer.virtualguest.order-delay";
public static final Set<ProductItemPrice> DEFAULT_VIRTUAL_GUEST_PRICES = ImmutableSet.<ProductItemPrice>builder()
.add(ProductItemPrice.builder().id(1639).build()) // 100 GB (SAN)
.add(ProductItemPrice.builder().id(21).build()) // 1 IP Address

View File

@ -24,6 +24,7 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import org.jclouds.compute.domain.ExecResponse;
@ -55,7 +56,8 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
public void setupClient() {
super.setupClient();
adapter = new SoftLayerComputeServiceAdapter(context.getApi(),
ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME);
ProductPackageClientLiveTest.CLOUD_SERVER_PACKAGE_NAME,
new SoftLayerComputeServiceAdapter.VirtualGuestHasLoginDetailsPresent(context.getApi()),60*60*1000);
}
@Test
@ -66,7 +68,7 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
@Test
public void testCreateNodeWithGroupEncodedIntoNameThenStoreCredentials() {
String group = "foo";
String name = "foo-ef4";
String name = "node"+new Random().nextInt();
Template template = computeContext.getComputeService().templateBuilder()
.locationId("3") // the default (singapore) doesn't work.
.build();
@ -87,7 +89,7 @@ public class SoftLayerComputeServiceAdapterLiveTest extends BaseSoftLayerClientL
protected void doConnectViaSsh(VirtualGuest guest, Credentials creds) {
SshClient ssh = computeContext.utils().sshFactory()
.create(new IPSocket(guest.getPrimaryBackendIpAddress(), 22), creds);
.create(new IPSocket(guest.getPrimaryIpAddress(), 22), creds);
try {
ssh.connect();
ExecResponse hello = ssh.exec("echo hello");

View File

@ -0,0 +1,89 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.compute;
import com.google.inject.Module;
import org.jclouds.compute.BaseComputeServiceLiveTest;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.domain.LocationScope;
import org.jclouds.rest.RestContext;
import org.jclouds.softlayer.SoftLayerAsyncClient;
import org.jclouds.softlayer.SoftLayerClient;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.Test;
import java.io.IOException;
import static org.testng.Assert.assertEquals;
/**
*
* Generally disabled, as it incurs higher fees.
*
* @author Adrian Cole
*/
@Test(groups = "live", enabled = true, sequential = true)
public class SoftLayerComputeServiceLiveTest extends BaseComputeServiceLiveTest {
public SoftLayerComputeServiceLiveTest() {
provider = "softlayer";
}
@Override
protected Module getSshModule() {
return new SshjSshClientModule();
}
public void testAssignability() throws Exception {
@SuppressWarnings("unused")
RestContext<SoftLayerClient, SoftLayerAsyncClient> tmContext = new ComputeServiceContextFactory()
.createContext(provider, identity, credential).getProviderSpecificContext();
}
@Override
protected void checkNodes(Iterable<? extends NodeMetadata> nodes, String tag) throws IOException {
super.checkNodes(nodes, tag);
for (NodeMetadata node : nodes) {
assertEquals(node.getLocation().getScope(), LocationScope.HOST);
}
}
@Test(enabled = true, dependsOnMethods = "testReboot", expectedExceptions = UnsupportedOperationException.class)
public void testSuspendResume() throws Exception {
super.testSuspendResume();
}
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
@Override
public void testGetNodesWithDetails() throws Exception {
super.testGetNodesWithDetails();
}
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
@Override
public void testListNodes() throws Exception {
super.testListNodes();
}
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails" })
@Override
public void testDestroyNodes() {
super.testDestroyNodes();
}
}

View File

@ -20,9 +20,14 @@ package org.jclouds.softlayer.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import com.google.common.collect.Iterables;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.compute.ComputeServiceContextFactory;
import org.jclouds.compute.RunNodesException;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.sshj.config.SshjSshClientModule;
import org.testng.annotations.BeforeClass;
@ -31,6 +36,8 @@ import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
import com.google.inject.Module;
import java.util.Set;
/**
*
* @author Adrian Cole
@ -69,4 +76,29 @@ public class SoftLayerExperimentLiveTest {
}
}
@Test
public void testCreateAndDestoryNode() throws RunNodesException {
ComputeServiceContext context = null;
try {
String identity = checkNotNull(System.getProperty("test.softlayer.identity"), "test.softlayer.identity");
String credential = checkNotNull(System.getProperty("test.softlayer.credential"), "test.softlayer.credential");
context = new ComputeServiceContextFactory().createContext("softlayer", identity, credential, ImmutableSet
.<Module> of(new Log4JLoggingModule(), new SshjSshClientModule()));
Template template = context.getComputeService().templateBuilder()
.locationId("3") // the default (singapore) doesn't work.
.build();
Set<? extends NodeMetadata> nodes = context.getComputeService().createNodesInGroup("computeservice",1,template);
assertTrue(nodes.size() == 1);
NodeMetadata data = Iterables.get(nodes,0);
context.getComputeService().destroyNode(data.getId());
} finally {
if (context != null)
context.close();
}
}
}

View File

@ -28,7 +28,6 @@ import org.jclouds.domain.Location;
import org.jclouds.location.suppliers.JustProvider;
import org.jclouds.softlayer.domain.Address;
import org.jclouds.softlayer.domain.Datacenter;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@ -41,24 +40,14 @@ import com.google.common.collect.ImmutableSet;
@Test(singleThreaded = true, groups = "unit")
public class DatacenterToLocationTest {
private DatacenterToLocation function;
@BeforeMethod
public void setup() {
function = new DatacenterToLocation(new JustProvider(ImmutableSet.<String>of(), "softlayer", URI.create("foo")));
}
static DatacenterToLocation function = new DatacenterToLocation(new JustProvider(ImmutableSet.<String> of(), "softlayer",
URI.create("foo")));;
@Test
public void testDatacenterToLocation() {
Address address = Address.builder().country("US")
.state("TX")
.description("This is Texas!")
.build();
Address address = Address.builder().country("US").state("TX").description("This is Texas!").build();
Datacenter datacenter = Datacenter.builder().id(1)
.longName("Texas Datacenter")
.locationAddress(address)
.build();
Datacenter datacenter = Datacenter.builder().id(1).longName("Texas Datacenter").locationAddress(address).build();
Location location = function.apply(datacenter);
@ -70,9 +59,7 @@ public class DatacenterToLocationTest {
@Test
public void testGetIso3166CodeNoCountryAndState() {
Datacenter datacenter = Datacenter.builder().id(1)
.longName("Nowhere")
.build();
Datacenter datacenter = Datacenter.builder().id(1).longName("Nowhere").build();
Location location = function.apply(datacenter);
@ -83,14 +70,9 @@ public class DatacenterToLocationTest {
@Test
public void testGetIso3166CodeCountryOnly() {
Address address = Address.builder().country("US")
.description("This is North America!")
.build();
Address address = Address.builder().country("US").description("This is North America!").build();
Datacenter datacenter = Datacenter.builder().id(1)
.longName("Nowhere")
.locationAddress(address)
.build();
Datacenter datacenter = Datacenter.builder().id(1).longName("Nowhere").locationAddress(address).build();
Location location = function.apply(datacenter);
@ -102,15 +84,10 @@ public class DatacenterToLocationTest {
@Test
public void testGetIso3166CodeWhitespaceTrimmer() {
Address address = Address.builder().country(" US ")
.state(" TX ")
.description("This is spaced out Texas")
Address address = Address.builder().country(" US ").state(" TX ").description("This is spaced out Texas")
.build();
Datacenter datacenter = Datacenter.builder().id(1)
.longName("Nowhere")
.locationAddress(address)
.build();
Datacenter datacenter = Datacenter.builder().id(1).longName("Nowhere").locationAddress(address).build();
Location location = function.apply(datacenter);

View File

@ -0,0 +1,196 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.compute.functions;
import static org.testng.Assert.assertEquals;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set;
import com.google.common.collect.Iterables;
import org.jclouds.compute.domain.*;
import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.softlayer.compute.functions.VirtualGuestToNodeMetadata.FindLocationForVirtualGuest;
import org.jclouds.softlayer.domain.Password;
import org.jclouds.softlayer.domain.VirtualGuest;
import org.jclouds.softlayer.parse.*;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
/**
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "VirtualGuestToNodeMetadataTest")
public class VirtualGuestToNodeMetadataTest {
@Test
public void testApplyWhereVirtualGuestWithNoPassword() throws UnknownHostException {
// notice if we've already parsed this properly here, we can rely on it.
VirtualGuest guest = new ParseVirtualGuestWithNoPasswordTest().expected();
// note we are testing when no credentials are here. otherwise would be ("node#416696", new
// Credentials("root", "password"))
Map<String, Credentials> credentialStore = ImmutableMap.<String, Credentials> of();
// setup so that we have an expected Location to be parsed from the guest.
Location expectedLocation = DatacenterToLocationTest.function.apply(guest.getDatacenter());
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(expectedLocation));
VirtualGuestToNodeMetadata parser = new VirtualGuestToNodeMetadata(credentialStore,
new FindLocationForVirtualGuest(locationSupplier));
NodeMetadata node = parser.apply(guest);
assertEquals(node, new NodeMetadataBuilder().ids("416788").name("node1000360500").location(
expectedLocation).state(NodeState.PENDING).publicAddresses(ImmutableSet.of("173.192.29.186"))
.privateAddresses(ImmutableSet.of("10.37.102.194"))
.hardware(new HardwareBuilder().id("TODO").processor(new Processor(1,2.0)).ram(1042).build())
.build());
// because it wasn't present in the credential store.
assertEquals(node.getCredentials(), null);
}
@Test
public void testApplyWhereVirtualIsBad() throws UnknownHostException {
// notice if we've already parsed this properly here, we can rely on it.
VirtualGuest guest = new ParseBadVirtualGuest().expected();
// note we are testing when no credentials are here. otherwise would be ("node#416696", new
// Credentials("root", "password"))
Map<String, Credentials> credentialStore = ImmutableMap.<String, Credentials> of();
// no location here
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of());
VirtualGuestToNodeMetadata parser = new VirtualGuestToNodeMetadata(credentialStore,
new FindLocationForVirtualGuest(locationSupplier));
NodeMetadata node = parser.apply(guest);
assertEquals(node, new NodeMetadataBuilder().ids("413348")
.name("foo-ef4").group("foo")
.state(NodeState.PENDING)
.hardware(new HardwareBuilder().id("TODO").ram(256).build())
.build());
// because it wasn't present in the credential store.
assertEquals(node.getCredentials(), null);
}
@Test
public void testApplyWhereVirtualGuestIsHalted() throws UnknownHostException {
// notice if we've already parsed this properly here, we can rely on it.
VirtualGuest guest = new ParseVirtualGuestHaltedTest().expected();
Password password = Iterables.get(guest.getOperatingSystem().getPasswords(), 0);
Credentials credentials = new Credentials(password.getUsername(),password.getPassword());
Map<String, Credentials> credentialStore = ImmutableMap.<String, Credentials> of("node#416700",credentials);
// setup so that we have an expected Location to be parsed from the guest.
Location expectedLocation = DatacenterToLocationTest.function.apply(guest.getDatacenter());
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(expectedLocation));
VirtualGuestToNodeMetadata parser = new VirtualGuestToNodeMetadata(credentialStore,
new FindLocationForVirtualGuest(locationSupplier));
NodeMetadata node = parser.apply(guest);
assertEquals(node, new NodeMetadataBuilder().ids("416700").name("node1703810489").location(
expectedLocation).state(NodeState.PENDING).credentials(credentials)
.publicAddresses(ImmutableSet.of("173.192.29.187")).privateAddresses(ImmutableSet.of("10.37.102.195"))
.hardware(new HardwareBuilder().id("TODO").processor(new Processor(1,2.0)).ram(1042).build())
.build());
// because it wasn't present in the credential store.
assertEquals(node.getCredentials(), credentials);
}
@Test
public void testApplyWhereVirtualGuestIsPaused() throws UnknownHostException {
// notice if we've already parsed this properly here, we can rely on it.
VirtualGuest guest = new ParseVirtualGuestPausedTest().expected();
Password password = Iterables.get(guest.getOperatingSystem().getPasswords(),0);
Credentials credentials = new Credentials(password.getUsername(),password.getPassword());
Map<String, Credentials> credentialStore = ImmutableMap.<String, Credentials> of("node#416700",credentials);
// setup so that we have an expected Location to be parsed from the guest.
Location expectedLocation = DatacenterToLocationTest.function.apply(guest.getDatacenter());
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(expectedLocation));
VirtualGuestToNodeMetadata parser = new VirtualGuestToNodeMetadata(credentialStore,
new FindLocationForVirtualGuest(locationSupplier));
NodeMetadata node = parser.apply(guest);
assertEquals(node, new NodeMetadataBuilder().ids("416700").name("node1703810489").location(
expectedLocation).state(NodeState.SUSPENDED).credentials(credentials)
.publicAddresses(ImmutableSet.of("173.192.29.187")).privateAddresses(ImmutableSet.of("10.37.102.195"))
.hardware(new HardwareBuilder().id("TODO").processor(new Processor(1,2.0)).ram(1042).build())
.build());
// because it wasn't present in the credential store.
assertEquals(node.getCredentials(), credentials);
}
@Test
public void testApplyWhereVirtualGuestIsRunning() throws UnknownHostException {
// notice if we've already parsed this properly here, we can rely on it.
VirtualGuest guest = new ParseVirtualGuestRunningTest().expected();
Password password = Iterables.get(guest.getOperatingSystem().getPasswords(),0);
Credentials credentials = new Credentials(password.getUsername(),password.getPassword());
Map<String, Credentials> credentialStore = ImmutableMap.<String, Credentials> of("node#416700",credentials);
// setup so that we have an expected Location to be parsed from the guest.
Location expectedLocation = DatacenterToLocationTest.function.apply(guest.getDatacenter());
Supplier<Set<? extends Location>> locationSupplier = Suppliers.<Set<? extends Location>> ofInstance(ImmutableSet
.<Location> of(expectedLocation));
VirtualGuestToNodeMetadata parser = new VirtualGuestToNodeMetadata(credentialStore,
new FindLocationForVirtualGuest(locationSupplier));
NodeMetadata node = parser.apply(guest);
assertEquals(node, new NodeMetadataBuilder().ids("416700").name("node1703810489").location(
expectedLocation).state(NodeState.RUNNING).credentials(credentials)
.publicAddresses(ImmutableSet.of("173.192.29.187")).privateAddresses(ImmutableSet.of("10.37.102.195"))
.hardware(new HardwareBuilder().id("TODO").processor(new Processor(1,2.0)).ram(1042).build())
.build());
// because it wasn't present in the credential store.
assertEquals(node.getCredentials(), credentials);
}
}

View File

@ -73,9 +73,8 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
// objectMask: virtualGuests.activeTransaction
for( VirtualGuest guest: client.listVirtualGuests()) {
if (guest.getHostname().startsWith(TEST_HOSTNAME_PREFIX)) {
BillingItemVirtualGuest billingItem = guest.getBillingItem();
if(billingItem!=null) {
client.cancelService(billingItem.getId());
if(guest.getBillingItemId()!=-1) {
client.cancelService(guest.getBillingItemId());
}
}
}
@ -125,8 +124,7 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
private void checkVirtualGuest(VirtualGuest vg) {
if (vg.getBillingItem()==null) return;//Quotes and shutting down guests
checkBillingItem(vg.getBillingItem());
if (vg.getBillingItemId()==-1) return;//Quotes and shutting down guests
assert vg.getAccountId() > 0 : vg;
assert vg.getCreateDate() != null : vg;
@ -146,9 +144,4 @@ public class VirtualGuestClientLiveTest extends BaseSoftLayerClientLiveTest {
assert vg.getPrimaryIpAddress() != null : vg;
}
private void checkBillingItem(BillingItemVirtualGuest billingItem) {
assert null != billingItem;
assert billingItem.getId() > 0 : billingItem;
}
}

View File

@ -0,0 +1,72 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.parse;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.softlayer.config.SoftLayerParserModule;
import org.jclouds.softlayer.domain.PowerState;
import org.jclouds.softlayer.domain.VirtualGuest;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseVirtualGuestWithNoPasswordTest")
public class ParseBadVirtualGuest extends BaseItemParserTest<VirtualGuest> {
@Override
public String resource() {
return "/virtual_guest_bad_halted.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public VirtualGuest expected() {
return VirtualGuest
.builder()
.id(413348).accountId(93750).billingItemId(-1)
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-09-28T01:52:45-08:00"))
.domain("jclouds.org").fullyQualifiedDomainName("foo-ef4.jclouds.org")
.hostname("foo-ef4").maxCpu(0).maxCpuUnits("CORE").maxMemory(256)
.statusId(1001).startCpus(0)
//TODO: maybe powerState can be flattened like billingItemId
.powerState(new PowerState(VirtualGuest.State.HALTED)).build();
}
protected Injector injector() {
return Guice.createInjector(new SoftLayerParserModule(), new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
});
}
}

View File

@ -0,0 +1,78 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.parse;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.softlayer.config.SoftLayerParserModule;
import org.jclouds.softlayer.domain.*;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseVirtualGuestWithNoPasswordTest")
public class ParseVirtualGuestHaltedTest extends BaseItemParserTest<VirtualGuest> {
@Override
public String resource() {
return "/virtual_guest_good_halted.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public VirtualGuest expected() {
return VirtualGuest
.builder()
.id(416700).accountId(93750).billingItemId(7184019)
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-01T11:47:35-08:00"))
.metricPollDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T02:32:00-08:00"))
.dedicatedAccountHostOnly(true).domain("me.org").fullyQualifiedDomainName("node1703810489.me.org")
.hostname("node1703810489").maxCpu(1).maxCpuUnits("CORE").maxMemory(1024)
.modifyDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T03:19:43-08:00"))
.primaryBackendIpAddress("10.37.102.195").primaryIpAddress("173.192.29.187").startCpus(1).statusId(1001)
.uuid("02ddbbba-9225-3d54-6de5-fc603b309dd8")
.operatingSystem(OperatingSystem.builder().id(913824)
.password(Password.builder().id(729122).username("root").password("KnJqhC2l").build())
.build())
.datacenter(Datacenter.builder().id(3).name("dal01").longName("Dallas").build())
//TODO: maybe powerState can be flattened like billingItemId
.powerState(new PowerState(VirtualGuest.State.HALTED)).build();
}
protected Injector injector() {
return Guice.createInjector(new SoftLayerParserModule(), new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
});
}
}

View File

@ -0,0 +1,78 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.parse;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.softlayer.config.SoftLayerParserModule;
import org.jclouds.softlayer.domain.*;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseVirtualGuestWithNoPasswordTest")
public class ParseVirtualGuestPausedTest extends BaseItemParserTest<VirtualGuest> {
@Override
public String resource() {
return "/virtual_guest_paused.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public VirtualGuest expected() {
return VirtualGuest
.builder()
.id(416700).accountId(93750).billingItemId(7184019)
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-01T11:47:35-08:00"))
.metricPollDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T02:32:00-08:00"))
.dedicatedAccountHostOnly(true).domain("me.org").fullyQualifiedDomainName("node1703810489.me.org")
.hostname("node1703810489").maxCpu(1).maxCpuUnits("CORE").maxMemory(1024)
.modifyDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T03:18:12-08:00"))
.primaryBackendIpAddress("10.37.102.195").primaryIpAddress("173.192.29.187").startCpus(1).statusId(1001)
.uuid("02ddbbba-9225-3d54-6de5-fc603b309dd8")
.operatingSystem(OperatingSystem.builder().id(913824)
.password(Password.builder().id(729122).username("root").password("KnJqhC2l").build())
.build())
.datacenter(Datacenter.builder().id(3).name("dal01").longName("Dallas").build())
//TODO: maybe powerState can be flattened like billingItemId
.powerState(new PowerState(VirtualGuest.State.PAUSED)).build();
}
protected Injector injector() {
return Guice.createInjector(new SoftLayerParserModule(), new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
});
}
}

View File

@ -0,0 +1,78 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.parse;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.softlayer.config.SoftLayerParserModule;
import org.jclouds.softlayer.domain.*;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseVirtualGuestWithNoPasswordTest")
public class ParseVirtualGuestRunningTest extends BaseItemParserTest<VirtualGuest> {
@Override
public String resource() {
return "/virtual_guest_running.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public VirtualGuest expected() {
return VirtualGuest
.builder()
.id(416700).accountId(93750).billingItemId(7184019)
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-01T11:47:35-08:00"))
.metricPollDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T02:32:00-08:00"))
.dedicatedAccountHostOnly(true).domain("me.org").fullyQualifiedDomainName("node1703810489.me.org")
.hostname("node1703810489").maxCpu(1).maxCpuUnits("CORE").maxMemory(1024)
.modifyDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T02:32:40-08:00"))
.primaryBackendIpAddress("10.37.102.195").primaryIpAddress("173.192.29.187").startCpus(1).statusId(1001)
.uuid("02ddbbba-9225-3d54-6de5-fc603b309dd8")
.operatingSystem(OperatingSystem.builder().id(913824)
.password(Password.builder().id(729122).username("root").password("KnJqhC2l").build())
.build())
.datacenter(Datacenter.builder().id(3).name("dal01").longName("Dallas").build())
//TODO: maybe powerState can be flattened like billingItemId
.powerState(new PowerState(VirtualGuest.State.RUNNING)).build();
}
protected Injector injector() {
return Guice.createInjector(new SoftLayerParserModule(), new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
});
}
}

View File

@ -0,0 +1,78 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds 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.softlayer.parse;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule;
import org.jclouds.softlayer.config.SoftLayerParserModule;
import org.jclouds.softlayer.domain.Datacenter;
import org.jclouds.softlayer.domain.OperatingSystem;
import org.jclouds.softlayer.domain.PowerState;
import org.jclouds.softlayer.domain.VirtualGuest;
import org.testng.annotations.Test;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "ParseVirtualGuestWithNoPasswordTest")
public class ParseVirtualGuestWithNoPasswordTest extends BaseItemParserTest<VirtualGuest> {
@Override
public String resource() {
return "/virtual_guest_no_password.json";
}
@Override
@Consumes(MediaType.APPLICATION_JSON)
public VirtualGuest expected() {
return VirtualGuest
.builder()
.id(416788).accountId(93750).billingItemId(7185261)
.createDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T03:24:43-08:00"))
.dedicatedAccountHostOnly(true).domain("me.org").fullyQualifiedDomainName("node1000360500.me.org")
.hostname("node1000360500").maxCpu(1).maxCpuUnits("CORE").maxMemory(1024)
.modifyDate(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-10-02T03:25:33-08:00"))
.primaryBackendIpAddress("10.37.102.194").primaryIpAddress("173.192.29.186").startCpus(1).statusId(1001)
.uuid("96fe22ad-8182-924d-ce51-a037e477dd83")
.operatingSystem(OperatingSystem.builder().id(913960).build())
.datacenter(Datacenter.builder().id(3).name("dal01").longName("Dallas").build())
//TODO: maybe powerState can be flattened like billingItemId
.powerState(new PowerState(VirtualGuest.State.HALTED)).build();
}
protected Injector injector() {
return Guice.createInjector(new SoftLayerParserModule(), new GsonModule() {
@Override
protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
super.configure();
}
});
}
}

View File

@ -0,0 +1,4 @@
{"accountId":93750,"createDate":"2011-09-28T01:52:45-08:00","dedicatedAccountHostOnlyFlag":false,"domain":"jclouds.org","fullyQualifiedDomainName":"foo-ef4.jclouds.org","hostname":"foo-ef4","id":413348,"lastVerifiedDate":null,"maxCpu":null,"maxCpuUnits":"CORE","maxMemory":256,"metricPollDate":null,"modifyDate":null,"privateNetworkOnlyFlag":false,"startCpus":null,"statusId":1001,"globalIdentifier":"9a8b20f0-a758-4c1f-b65b-0e63b791009f","managedResourceFlag":false,"networkVlans":[],"powerState":{
"keyName":"HALTED",
"name":"Halted"
}}

View File

@ -0,0 +1,117 @@
{"accountId":93750,"createDate":"2011-10-01T11:47:35-08:00","dedicatedAccountHostOnlyFlag":true,"domain":"me.org","fullyQualifiedDomainName":"node1703810489.me.org","hostname":"node1703810489","id":416700,"lastVerifiedDate":null,"maxCpu":1,"maxCpuUnits":"CORE","maxMemory":1024,"metricPollDate":"2011-10-02T02:32:00-08:00","modifyDate":"2011-10-02T03:19:43-08:00","privateNetworkOnlyFlag":false,"startCpus":1,"statusId":1001,"uuid":"02ddbbba-9225-3d54-6de5-fc603b309dd8","billingItem":{
"cancellationDate":null,
"categoryCode":"guest_core",
"createDate":"2011-10-01T11:48:10-08:00",
"currentHourlyCharge":"0",
"cycleStartDate":"2011-10-01T11:58:26-08:00",
"description":"Private 1 x 2.0 GHz Core",
"domainName":"me.org",
"hostName":"node1703810489",
"hourlyRecurringFee":"0",
"hoursUsed":"16",
"id":7184019,
"laborFee":"0",
"laborFeeTaxRate":"0",
"lastBillDate":"2011-10-01T11:58:26-08:00",
"modifyDate":"2011-10-01T11:58:26-08:00",
"nextBillDate":"2011-10-17T21:00:00-08:00",
"oneTimeFee":"0",
"oneTimeFeeTaxRate":"0",
"orderItemId":8021579,
"parentId":null,
"recurringFee":"0",
"recurringFeeTaxRate":"0",
"recurringMonths":1,
"serviceProviderId":1,
"setupFee":"0",
"setupFeeTaxRate":"0",
"resourceTableId":416700
},"datacenter":{
"id":3,
"longName":"Dallas",
"name":"dal01"
},"globalIdentifier":"0ea2db7f-800d-479a-88e0-8e276e500b80","managedResourceFlag":false,"networkVlans":[
{
"accountId":93750,
"id":144615,
"modifyDate":"2011-09-30T11:35:27-08:00",
"networkVrfId":null,
"primarySubnetId":171267,
"vlanNumber":1673
},
{
"accountId":93750,
"id":144616,
"modifyDate":"2011-09-30T11:35:30-08:00",
"networkVrfId":null,
"primarySubnetId":329652,
"vlanNumber":1622
}
],"operatingSystem":{
"hardwareId":null,
"id":913824,
"manufacturerLicenseInstance":"",
"passwords":[
{
"createDate":"2011-10-01T11:48:52-08:00",
"id":729122,
"modifyDate":"2011-10-01T11:48:52-08:00",
"password":"KnJqhC2l",
"port":null,
"softwareId":913824,
"username":"root",
"software":{
"hardwareId":null,
"id":913824,
"manufacturerLicenseInstance":"",
"passwords":[
{
"createDate":"2011-10-01T11:48:52-08:00",
"id":729122,
"modifyDate":"2011-10-01T11:48:52-08:00",
"password":"KnJqhC2l",
"port":null,
"softwareId":913824,
"username":"root",
"software":null
}
],
"softwareLicense":{
"id":427,
"softwareDescriptionId":408,
"softwareDescription":{
"controlPanel":0,
"id":408,
"manufacturer":"Ubuntu",
"name":"Ubuntu ",
"operatingSystem":1,
"requiredUser":"root",
"upgradeSwDescId":null,
"version":"8.04-64 Minimal for CCI",
"virtualLicense":0,
"virtualizationPlatform":0
}
}
}
}
],
"softwareLicense":{
"id":427,
"softwareDescriptionId":408,
"softwareDescription":{
"controlPanel":0,
"id":408,
"manufacturer":"Ubuntu",
"name":"Ubuntu ",
"operatingSystem":1,
"requiredUser":"root",
"upgradeSwDescId":null,
"version":"8.04-64 Minimal for CCI",
"virtualLicense":0,
"virtualizationPlatform":0
}
}
},"powerState":{
"keyName":"HALTED",
"name":"Halted"
},"primaryBackendIpAddress":"10.37.102.195","primaryIpAddress":"173.192.29.187"}

View File

@ -0,0 +1,74 @@
{"accountId":93750,"createDate":"2011-10-02T03:24:43-08:00","dedicatedAccountHostOnlyFlag":true,"domain":"me.org","fullyQualifiedDomainName":"node1000360500.me.org","hostname":"node1000360500","id":416788,"lastVerifiedDate":null,"maxCpu":1,"maxCpuUnits":"CORE","maxMemory":1024,"metricPollDate":null,"modifyDate":"2011-10-02T03:25:33-08:00","privateNetworkOnlyFlag":false,"startCpus":1,"statusId":1001,"uuid":"96fe22ad-8182-924d-ce51-a037e477dd83","billingItem":{
"cancellationDate":null,
"categoryCode":"guest_core",
"createDate":"2011-10-02T03:25:12-08:00",
"currentHourlyCharge":"0",
"cycleStartDate":"2011-10-02T03:25:12-08:00",
"description":"Private 1 x 2.0 GHz Core",
"domainName":"me.org",
"hostName":"node1000360500",
"hourlyRecurringFee":"0",
"hoursUsed":"1",
"id":7185261,
"laborFee":"0",
"laborFeeTaxRate":"0",
"lastBillDate":"2011-10-02T03:25:12-08:00",
"modifyDate":"2011-10-02T03:25:51-08:00",
"nextBillDate":"2011-10-17T21:00:00-08:00",
"oneTimeFee":"0",
"oneTimeFeeTaxRate":"0",
"orderItemId":8023216,
"parentId":null,
"recurringFee":"0",
"recurringFeeTaxRate":"0",
"recurringMonths":1,
"serviceProviderId":1,
"setupFee":"0",
"setupFeeTaxRate":"0",
"resourceTableId":416788
},"datacenter":{
"id":3,
"longName":"Dallas",
"name":"dal01"
},"globalIdentifier":"0a07b4fc-2b3c-4053-9220-55992de14d21","managedResourceFlag":false,"networkVlans":[
{
"accountId":93750,
"id":144615,
"modifyDate":"2011-09-30T11:35:27-08:00",
"networkVrfId":null,
"primarySubnetId":171267,
"vlanNumber":1673
},
{
"accountId":93750,
"id":144616,
"modifyDate":"2011-09-30T11:35:30-08:00",
"networkVrfId":null,
"primarySubnetId":329652,
"vlanNumber":1622
}
],"operatingSystem":{
"hardwareId":null,
"id":913960,
"manufacturerLicenseInstance":"",
"passwords":[],
"softwareLicense":{
"id":427,
"softwareDescriptionId":408,
"softwareDescription":{
"controlPanel":0,
"id":408,
"manufacturer":"Ubuntu",
"name":"Ubuntu ",
"operatingSystem":1,
"requiredUser":"root",
"upgradeSwDescId":null,
"version":"8.04-64 Minimal for CCI",
"virtualLicense":0,
"virtualizationPlatform":0
}
}
},"powerState":{
"keyName":"HALTED",
"name":"Halted"
},"primaryBackendIpAddress":"10.37.102.194","primaryIpAddress":"173.192.29.186"}

View File

@ -0,0 +1,117 @@
{"accountId":93750,"createDate":"2011-10-01T11:47:35-08:00","dedicatedAccountHostOnlyFlag":true,"domain":"me.org","fullyQualifiedDomainName":"node1703810489.me.org","hostname":"node1703810489","id":416700,"lastVerifiedDate":null,"maxCpu":1,"maxCpuUnits":"CORE","maxMemory":1024,"metricPollDate":"2011-10-02T02:32:00-08:00","modifyDate":"2011-10-02T03:18:12-08:00","privateNetworkOnlyFlag":false,"startCpus":1,"statusId":1001,"uuid":"02ddbbba-9225-3d54-6de5-fc603b309dd8","billingItem":{
"cancellationDate":null,
"categoryCode":"guest_core",
"createDate":"2011-10-01T11:48:10-08:00",
"currentHourlyCharge":"0",
"cycleStartDate":"2011-10-01T11:58:26-08:00",
"description":"Private 1 x 2.0 GHz Core",
"domainName":"me.org",
"hostName":"node1703810489",
"hourlyRecurringFee":"0",
"hoursUsed":"16",
"id":7184019,
"laborFee":"0",
"laborFeeTaxRate":"0",
"lastBillDate":"2011-10-01T11:58:26-08:00",
"modifyDate":"2011-10-01T11:58:26-08:00",
"nextBillDate":"2011-10-17T21:00:00-08:00",
"oneTimeFee":"0",
"oneTimeFeeTaxRate":"0",
"orderItemId":8021579,
"parentId":null,
"recurringFee":"0",
"recurringFeeTaxRate":"0",
"recurringMonths":1,
"serviceProviderId":1,
"setupFee":"0",
"setupFeeTaxRate":"0",
"resourceTableId":416700
},"datacenter":{
"id":3,
"longName":"Dallas",
"name":"dal01"
},"globalIdentifier":"0ea2db7f-800d-479a-88e0-8e276e500b80","managedResourceFlag":false,"networkVlans":[
{
"accountId":93750,
"id":144615,
"modifyDate":"2011-09-30T11:35:27-08:00",
"networkVrfId":null,
"primarySubnetId":171267,
"vlanNumber":1673
},
{
"accountId":93750,
"id":144616,
"modifyDate":"2011-09-30T11:35:30-08:00",
"networkVrfId":null,
"primarySubnetId":329652,
"vlanNumber":1622
}
],"operatingSystem":{
"hardwareId":null,
"id":913824,
"manufacturerLicenseInstance":"",
"passwords":[
{
"createDate":"2011-10-01T11:48:52-08:00",
"id":729122,
"modifyDate":"2011-10-01T11:48:52-08:00",
"password":"KnJqhC2l",
"port":null,
"softwareId":913824,
"username":"root",
"software":{
"hardwareId":null,
"id":913824,
"manufacturerLicenseInstance":"",
"passwords":[
{
"createDate":"2011-10-01T11:48:52-08:00",
"id":729122,
"modifyDate":"2011-10-01T11:48:52-08:00",
"password":"KnJqhC2l",
"port":null,
"softwareId":913824,
"username":"root",
"software":null
}
],
"softwareLicense":{
"id":427,
"softwareDescriptionId":408,
"softwareDescription":{
"controlPanel":0,
"id":408,
"manufacturer":"Ubuntu",
"name":"Ubuntu ",
"operatingSystem":1,
"requiredUser":"root",
"upgradeSwDescId":null,
"version":"8.04-64 Minimal for CCI",
"virtualLicense":0,
"virtualizationPlatform":0
}
}
}
}
],
"softwareLicense":{
"id":427,
"softwareDescriptionId":408,
"softwareDescription":{
"controlPanel":0,
"id":408,
"manufacturer":"Ubuntu",
"name":"Ubuntu ",
"operatingSystem":1,
"requiredUser":"root",
"upgradeSwDescId":null,
"version":"8.04-64 Minimal for CCI",
"virtualLicense":0,
"virtualizationPlatform":0
}
}
},"powerState":{
"keyName":"PAUSED",
"name":"Paused"
},"primaryBackendIpAddress":"10.37.102.195","primaryIpAddress":"173.192.29.187"}

View File

@ -0,0 +1,117 @@
{"accountId":93750,"createDate":"2011-10-01T11:47:35-08:00","dedicatedAccountHostOnlyFlag":true,"domain":"me.org","fullyQualifiedDomainName":"node1703810489.me.org","hostname":"node1703810489","id":416700,"lastVerifiedDate":null,"maxCpu":1,"maxCpuUnits":"CORE","maxMemory":1024,"metricPollDate":"2011-10-02T02:32:00-08:00","modifyDate":"2011-10-02T02:32:40-08:00","privateNetworkOnlyFlag":false,"startCpus":1,"statusId":1001,"uuid":"02ddbbba-9225-3d54-6de5-fc603b309dd8","billingItem":{
"cancellationDate":null,
"categoryCode":"guest_core",
"createDate":"2011-10-01T11:48:10-08:00",
"currentHourlyCharge":"0",
"cycleStartDate":"2011-10-01T11:58:26-08:00",
"description":"Private 1 x 2.0 GHz Core",
"domainName":"me.org",
"hostName":"node1703810489",
"hourlyRecurringFee":"0",
"hoursUsed":"16",
"id":7184019,
"laborFee":"0",
"laborFeeTaxRate":"0",
"lastBillDate":"2011-10-01T11:58:26-08:00",
"modifyDate":"2011-10-01T11:58:26-08:00",
"nextBillDate":"2011-10-17T21:00:00-08:00",
"oneTimeFee":"0",
"oneTimeFeeTaxRate":"0",
"orderItemId":8021579,
"parentId":null,
"recurringFee":"0",
"recurringFeeTaxRate":"0",
"recurringMonths":1,
"serviceProviderId":1,
"setupFee":"0",
"setupFeeTaxRate":"0",
"resourceTableId":416700
},"datacenter":{
"id":3,
"longName":"Dallas",
"name":"dal01"
},"globalIdentifier":"0ea2db7f-800d-479a-88e0-8e276e500b80","managedResourceFlag":false,"networkVlans":[
{
"accountId":93750,
"id":144615,
"modifyDate":"2011-09-30T11:35:27-08:00",
"networkVrfId":null,
"primarySubnetId":171267,
"vlanNumber":1673
},
{
"accountId":93750,
"id":144616,
"modifyDate":"2011-09-30T11:35:30-08:00",
"networkVrfId":null,
"primarySubnetId":329652,
"vlanNumber":1622
}
],"operatingSystem":{
"hardwareId":null,
"id":913824,
"manufacturerLicenseInstance":"",
"passwords":[
{
"createDate":"2011-10-01T11:48:52-08:00",
"id":729122,
"modifyDate":"2011-10-01T11:48:52-08:00",
"password":"KnJqhC2l",
"port":null,
"softwareId":913824,
"username":"root",
"software":{
"hardwareId":null,
"id":913824,
"manufacturerLicenseInstance":"",
"passwords":[
{
"createDate":"2011-10-01T11:48:52-08:00",
"id":729122,
"modifyDate":"2011-10-01T11:48:52-08:00",
"password":"KnJqhC2l",
"port":null,
"softwareId":913824,
"username":"root",
"software":null
}
],
"softwareLicense":{
"id":427,
"softwareDescriptionId":408,
"softwareDescription":{
"controlPanel":0,
"id":408,
"manufacturer":"Ubuntu",
"name":"Ubuntu ",
"operatingSystem":1,
"requiredUser":"root",
"upgradeSwDescId":null,
"version":"8.04-64 Minimal for CCI",
"virtualLicense":0,
"virtualizationPlatform":0
}
}
}
}
],
"softwareLicense":{
"id":427,
"softwareDescriptionId":408,
"softwareDescription":{
"controlPanel":0,
"id":408,
"manufacturer":"Ubuntu",
"name":"Ubuntu ",
"operatingSystem":1,
"requiredUser":"root",
"upgradeSwDescId":null,
"version":"8.04-64 Minimal for CCI",
"virtualLicense":0,
"virtualizationPlatform":0
}
}
},"powerState":{
"keyName":"RUNNING",
"name":"Running"
},"primaryBackendIpAddress":"10.37.102.195","primaryIpAddress":"173.192.29.187"}