cleaned up joyent and fixed ssh auth related issues

This commit is contained in:
Adrian Cole 2012-07-24 23:01:08 -07:00
parent 5d6e005e8b
commit 01918a02ec
52 changed files with 1059 additions and 575 deletions

View File

@ -63,6 +63,10 @@ public class JoyentCloudApiMetadata extends BaseRestApiMetadata {
public static Properties defaultProperties() { public static Properties defaultProperties() {
Properties properties = BaseRestApiMetadata.defaultProperties(); Properties properties = BaseRestApiMetadata.defaultProperties();
// auth fail sometimes happens, as the rc.local script that injects the
// authorized key executes after ssh has started.
properties.setProperty("jclouds.ssh.max-retries", "7");
properties.setProperty("jclouds.ssh.retry-auth", "true");
properties.setProperty(JoyentCloudProperties.AUTOGENERATE_KEYS, "true"); properties.setProperty(JoyentCloudProperties.AUTOGENERATE_KEYS, "true");
return properties; return properties;
} }

View File

@ -1,54 +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.joyent.cloudapi.v6_5.binders;
import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.HttpRequest;
import org.jclouds.joyent.cloudapi.v6_5.domain.Key;
import org.jclouds.json.Json;
import org.jclouds.rest.binders.BindToJsonPayload;
/**
*
* @author Adrian Cole
*
*/
@Singleton
public class BindKeyToJsonPayload extends BindToJsonPayload {
@Inject
public BindKeyToJsonPayload(Json jsonBinder) {
super(jsonBinder);
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Object toBind) {
// don't include created in the http request
return super.bindToRequest(request, Key.class.cast(toBind).toBuilder().created(null).build());
}
@Override
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
throw new IllegalStateException("This should be assigned only a single arg");
}
}

View File

@ -94,7 +94,7 @@ public class JoyentCloudComputeService extends BaseComputeService {
CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy,
DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy,
SuspendNodeStrategy stopNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider, SuspendNodeStrategy stopNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider,
Provider<TemplateOptions> templateOptionsProvider, @Named("DEFAULT") Provider<TemplateOptions> templateOptionsProvider,
@Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>> nodeRunning, @Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>> nodeRunning,
@Named(TIMEOUT_NODE_TERMINATED) Predicate<AtomicReference<NodeMetadata>> nodeTerminated, @Named(TIMEOUT_NODE_TERMINATED) Predicate<AtomicReference<NodeMetadata>> nodeTerminated,
@Named(TIMEOUT_NODE_SUSPENDED) Predicate<AtomicReference<NodeMetadata>> nodeSuspended, @Named(TIMEOUT_NODE_SUSPENDED) Predicate<AtomicReference<NodeMetadata>> nodeSuspended,

View File

@ -20,7 +20,6 @@ package org.jclouds.joyent.cloudapi.v6_5.compute.config;
import static org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudProperties.AUTOGENERATE_KEYS; import static org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudProperties.AUTOGENERATE_KEYS;
import java.security.SecureRandom;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -119,9 +118,9 @@ public class JoyentCloudComputeServiceContextModule extends
@Override @Override
protected TemplateOptions provideTemplateOptions(Injector injector, TemplateOptions options) { protected TemplateOptions provideTemplateOptions(Injector injector, TemplateOptions options) {
return options.as(JoyentCloudTemplateOptions.class) boolean generateKey = injector.getInstance(com.google.inject.Key.get(boolean.class,
.generateKey(injector.getInstance( Names.named(AUTOGENERATE_KEYS)));
com.google.inject.Key.get(boolean.class, Names.named(AUTOGENERATE_KEYS)))); return options.as(JoyentCloudTemplateOptions.class).generateKey(generateKey);
} }
@Provides @Provides
@ -130,6 +129,7 @@ public class JoyentCloudComputeServiceContextModule extends
CacheLoader<DatacenterAndName, KeyAndPrivateKey> in) { CacheLoader<DatacenterAndName, KeyAndPrivateKey> in) {
return CacheBuilder.newBuilder().build(in); return CacheBuilder.newBuilder().build(in);
} }
@Provides @Provides
@Singleton @Singleton
protected Supplier<Map<String, Location>> createLocationIndexedById( protected Supplier<Map<String, Location>> createLocationIndexedById(
@ -150,12 +150,6 @@ public class JoyentCloudComputeServiceContextModule extends
}, locations); }, locations);
} }
@Provides
@Singleton
protected SecureRandom provideSecureRandom() {
return new SecureRandom();
}
@VisibleForTesting @VisibleForTesting
public static final Map<Machine.State, NodeMetadata.Status> toPortableNodeStatus = ImmutableMap public static final Map<Machine.State, NodeMetadata.Status> toPortableNodeStatus = ImmutableMap

View File

@ -59,10 +59,11 @@ public class DatasetInDatacenterToImage implements Function<DatasetInDatacenter,
Dataset dataset = datasetInDatacenter.get(); Dataset dataset = datasetInDatacenter.get();
return new ImageBuilder() return new ImageBuilder()
.id(datasetInDatacenter.slashEncode()) .id(datasetInDatacenter.slashEncode())
.providerId(dataset.getId()) // note that it is urn that is the expected value!
.providerId(dataset.getUrn())
.name(dataset.getName()) .name(dataset.getName())
.operatingSystem(imageToOs.apply(dataset)) .operatingSystem(imageToOs.apply(dataset))
.description(dataset.getUrn()) .description(dataset.getDescription())
.version(dataset.getVersion()) .version(dataset.getVersion())
.location(location) .location(location)
.status(Image.Status.AVAILABLE).build(); .status(Image.Status.AVAILABLE).build();

View File

@ -94,7 +94,7 @@ public class MachineInDatacenterToNodeMetadata implements Function<MachineInData
builder.id(machineInDatacenter.slashEncode()); builder.id(machineInDatacenter.slashEncode());
builder.providerId(from.getId()); builder.providerId(from.getId());
builder.name(from.getName()); builder.name(from.getName());
builder.hostname(from.getName()); builder.hostname(from.getId());
builder.location(zone); builder.location(zone);
addMetadataAndParseTagsFromCommaDelimitedValue(builder, filterKeys(from.getMetadata(), new Predicate<String>() { addMetadataAndParseTagsFromCommaDelimitedValue(builder, filterKeys(from.getMetadata(), new Predicate<String>() {
@ -109,7 +109,7 @@ public class MachineInDatacenterToNodeMetadata implements Function<MachineInData
})); }));
builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getName())); builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getName()));
builder.imageId(DatacenterAndName.fromDatacenterAndName(machineInDatacenter.getDatacenter(), from.get()) builder.imageId(DatacenterAndName.fromDatacenterAndName(machineInDatacenter.getDatacenter(), from.getDatasetURN())
.slashEncode()); .slashEncode());
builder.operatingSystem(findOperatingSystemForMachineOrNull(machineInDatacenter)); builder.operatingSystem(findOperatingSystemForMachineOrNull(machineInDatacenter));
builder.hardware(findHardwareForMachineOrNull(machineInDatacenter)); builder.hardware(findHardwareForMachineOrNull(machineInDatacenter));
@ -132,7 +132,7 @@ public class MachineInDatacenterToNodeMetadata implements Function<MachineInData
protected OperatingSystem findOperatingSystemForMachineOrNull(MachineInDatacenter machineInDatacenter) { protected OperatingSystem findOperatingSystemForMachineOrNull(MachineInDatacenter machineInDatacenter) {
Image image = findObjectOfTypeForMachineOrNull(images.get(), "image", machineInDatacenter.get() Image image = findObjectOfTypeForMachineOrNull(images.get(), "image", machineInDatacenter.get()
.get(), machineInDatacenter); .getDatasetURN(), machineInDatacenter);
return (image != null) ? image.getOperatingSystem() : null; return (image != null) ? image.getOperatingSystem() : null;
} }

View File

@ -20,18 +20,15 @@ package org.jclouds.joyent.cloudapi.v6_5.compute.loaders;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.security.SecureRandom;
import java.util.Map; import java.util.Map;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.inject.Named; import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.compute.functions.GroupNamingConvention; import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.crypto.Crypto; import org.jclouds.crypto.SshKeyPairGenerator;
import org.jclouds.crypto.SshKeys;
import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi; import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi;
import org.jclouds.joyent.cloudapi.v6_5.compute.internal.KeyAndPrivateKey; import org.jclouds.joyent.cloudapi.v6_5.compute.internal.KeyAndPrivateKey;
import org.jclouds.joyent.cloudapi.v6_5.domain.Key; import org.jclouds.joyent.cloudapi.v6_5.domain.Key;
@ -51,23 +48,22 @@ public class CreateUniqueKey extends CacheLoader<DatacenterAndName, KeyAndPrivat
protected Logger logger = Logger.NULL; protected Logger logger = Logger.NULL;
protected final JoyentCloudApi cloudApiApi; protected final JoyentCloudApi cloudApiApi;
protected final GroupNamingConvention.Factory namingConvention; protected final GroupNamingConvention.Factory namingConvention;
protected final Crypto crypto; protected final SshKeyPairGenerator sshKeyPairGenerator;
protected final Provider<SecureRandom> secureRandom;
@Inject @Inject
public CreateUniqueKey(JoyentCloudApi cloudApiApi, GroupNamingConvention.Factory namingConvention, Crypto crypto, Provider<SecureRandom> secureRandom) { public CreateUniqueKey(JoyentCloudApi cloudApiApi, GroupNamingConvention.Factory namingConvention,
SshKeyPairGenerator sshKeyPairGenerator) {
this.cloudApiApi = checkNotNull(cloudApiApi, "cloudApiApi"); this.cloudApiApi = checkNotNull(cloudApiApi, "cloudApiApi");
this.namingConvention = checkNotNull(namingConvention, "namingConvention"); this.namingConvention = checkNotNull(namingConvention, "namingConvention");
this.crypto = checkNotNull(crypto, "crypto"); this.sshKeyPairGenerator = checkNotNull(sshKeyPairGenerator, "sshKeyPairGenerator");
this.secureRandom = checkNotNull(secureRandom, "secureRandom");
} }
@Override @Override
public KeyAndPrivateKey load(DatacenterAndName datacenterAndName) { public KeyAndPrivateKey load(DatacenterAndName datacenterAndName) {
String datacenterId = checkNotNull(datacenterAndName, "datacenterAndName").getDatacenter(); String datacenterId = checkNotNull(datacenterAndName, "datacenterAndName").getDatacenter();
String prefix = datacenterAndName.getName(); String prefix = datacenterAndName.getName();
Map<String, String> keyPair = SshKeys.generate(crypto.rsaKeyPairGenerator(), secureRandom.get()); Map<String, String> keyPair = sshKeyPairGenerator.get();
String publicKey = keyPair.get("public"); String publicKey = keyPair.get("public");
String privateKey = keyPair.get("private"); String privateKey = keyPair.get("private");

View File

@ -28,6 +28,7 @@ import org.jclouds.scriptbuilder.domain.Statement;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.base.Objects.ToStringHelper; import com.google.common.base.Objects.ToStringHelper;
import com.google.common.base.Optional;
/** /**
* Contains options supported in the {@code ComputeService#createNodesInGroup} operation on the * Contains options supported in the {@code ComputeService#createNodesInGroup} operation on the
@ -48,6 +49,7 @@ import com.google.common.base.Objects.ToStringHelper;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class JoyentCloudTemplateOptions extends TemplateOptions implements Cloneable { public class JoyentCloudTemplateOptions extends TemplateOptions implements Cloneable {
@Override @Override
public JoyentCloudTemplateOptions clone() { public JoyentCloudTemplateOptions clone() {
JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions(); JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions();
@ -60,11 +62,11 @@ public class JoyentCloudTemplateOptions extends TemplateOptions implements Clone
super.copyTo(to); super.copyTo(to);
if (to instanceof JoyentCloudTemplateOptions) { if (to instanceof JoyentCloudTemplateOptions) {
JoyentCloudTemplateOptions eTo = JoyentCloudTemplateOptions.class.cast(to); JoyentCloudTemplateOptions eTo = JoyentCloudTemplateOptions.class.cast(to);
eTo.generateKey(shouldGenerateKey()); eTo.generateKey = generateKey;
} }
} }
protected boolean generateKey = false; protected Optional<Boolean> generateKey = Optional.absent();
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
@ -83,17 +85,14 @@ public class JoyentCloudTemplateOptions extends TemplateOptions implements Clone
@Override @Override
public ToStringHelper string() { public ToStringHelper string() {
ToStringHelper toString = super.string(); return super.string().add("generateKey", generateKey.orNull());
if (generateKey)
toString.add("generateKey", generateKey);
return toString;
} }
/** /**
* @see #shouldGenerateKey() * @see #shouldGenerateKey()
*/ */
public JoyentCloudTemplateOptions generateKey(boolean enable) { public JoyentCloudTemplateOptions generateKey(boolean enable) {
this.generateKey = enable; this.generateKey = Optional.of(enable);
return this; return this;
} }
@ -101,7 +100,7 @@ public class JoyentCloudTemplateOptions extends TemplateOptions implements Clone
* *
* @return true if auto generation of keys is enabled * @return true if auto generation of keys is enabled
*/ */
public boolean shouldGenerateKey() { public Optional<Boolean> shouldGenerateKey() {
return generateKey; return generateKey;
} }

View File

@ -20,6 +20,7 @@ package org.jclouds.joyent.cloudapi.v6_5.compute.strategy;
import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudProperties.AUTOGENERATE_KEYS;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -55,6 +56,7 @@ public class ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameT
CreateNodesWithGroupEncodedIntoNameThenAddToSet { CreateNodesWithGroupEncodedIntoNameThenAddToSet {
private final LoadingCache<DatacenterAndName, KeyAndPrivateKey> keyCache; private final LoadingCache<DatacenterAndName, KeyAndPrivateKey> keyCache;
private final boolean defaultToAutogenerateKeys;
@Inject @Inject
protected ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet( protected ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet(
@ -63,10 +65,12 @@ public class ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameT
GroupNamingConvention.Factory namingConvention, GroupNamingConvention.Factory namingConvention,
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
LoadingCache<DatacenterAndName, KeyAndPrivateKey> keyCache) { LoadingCache<DatacenterAndName, KeyAndPrivateKey> keyCache,
@Named(AUTOGENERATE_KEYS) boolean defaultToAutogenerateKeys) {
super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, executor, super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, executor,
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory); customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
this.keyCache = checkNotNull(keyCache, "keyCache"); this.keyCache = checkNotNull(keyCache, "keyCache");
this.defaultToAutogenerateKeys = defaultToAutogenerateKeys;
} }
@Override @Override
@ -80,8 +84,11 @@ public class ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameT
assert template.getOptions().equals(templateOptions) : "options didn't clone properly"; assert template.getOptions().equals(templateOptions) : "options didn't clone properly";
String datacenter = mutableTemplate.getLocation().getId(); String datacenter = mutableTemplate.getLocation().getId();
if (!templateOptions.shouldGenerateKey().isPresent())
templateOptions.generateKey(defaultToAutogenerateKeys);
if (templateOptions.shouldGenerateKey()) { if (templateOptions.shouldGenerateKey().get()) {
KeyAndPrivateKey keyPair = keyCache.getUnchecked(DatacenterAndName.fromDatacenterAndName(datacenter, namingConvention.create() KeyAndPrivateKey keyPair = keyCache.getUnchecked(DatacenterAndName.fromDatacenterAndName(datacenter, namingConvention.create()
.sharedNameForGroup(group))); .sharedNameForGroup(group)));
// in order to delete the key later // in order to delete the key later

View File

@ -65,7 +65,6 @@ public class JoyentCloudRestClientModule extends RestClientModule<JoyentCloudApi
@Override @Override
protected void configure() { protected void configure() {
bind(DateAdapter.class).to(Iso8601DateAdapter.class); bind(DateAdapter.class).to(Iso8601DateAdapter.class);
install(new JoyentCloudParserModule());
super.configure(); super.configure();
} }

View File

@ -1,156 +1,346 @@
/**
* 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.joyent.cloudapi.v6_5.domain; package org.jclouds.joyent.cloudapi.v6_5.domain;
import java.util.Date; import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date;
import java.util.Map;
import javax.inject.Named;
import org.jclouds.domain.JsonBall;
import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type;
import org.jclouds.json.Json;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.gson.annotations.SerializedName; import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
/** /**
* Listing of a dataset. * A dataset is the image of the software on your machine. It contains the software packages that
* will be available on newly provisioned machines. In the case of virtual machines, the dataset
* also includes the operating system.
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see <a href= "http://apidocs.joyent.com/cloudApiapidoc/cloudapi/#datasets" /> * @see <a href= "http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#ListDatasets" >docs</a>
*/ */
public class Dataset implements Comparable<Dataset> { public class Dataset implements Comparable<Dataset> {
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
public Builder toBuilder() {
return new Builder().fromDataset(this);
}
public static class Builder { public static class Builder {
private String id; private String id;
private String name;
private Type type;
private String version;
private String urn; private String urn;
private String name;
private String os;
private Type type;
private String description;
private boolean isDefault; private boolean isDefault;
private ImmutableMap.Builder<String, JsonBall> requirements = ImmutableMap.<String, JsonBall>builder();
private String version;
private Date created; private Date created;
/**
* @see Dataset#getId()
*/
public Builder id(String id) { public Builder id(String id) {
this.id = id; this.id = id;
return this; return this;
} }
public Builder name(String name) { /**
this.name = name; * @see Dataset#getUrn()
return this; */
}
public Builder type(Type type) {
this.type = type;
return this;
}
public Builder version(String version) {
this.version = version;
return this;
}
public Builder urn(String urn) { public Builder urn(String urn) {
this.urn = urn; this.urn = urn;
return this; return this;
} }
/**
* @see Dataset#getName()
*/
public Builder name(String name) {
this.name = name;
return this;
}
/**
* @see Dataset#getOs()
*/
public Builder os(String os) {
this.os = os;
return this;
}
/**
* @see Dataset#getType()
*/
public Builder type(Type type) {
this.type = type;
return this;
}
/**
* @see Dataset#getDescription()
*/
public Builder description(String description) {
this.description = description;
return this;
}
/**
* @see Dataset#isDefault()
*/
public Builder isDefault(boolean isDefault) { public Builder isDefault(boolean isDefault) {
this.isDefault = isDefault; this.isDefault = isDefault;
return this; return this;
} }
/**
* @see Dataset#getRequirements()
*/
public Builder requirements(Map<String, JsonBall> requirements) {
this.requirements = ImmutableMap.<String, JsonBall> builder();
this.requirements.putAll(checkNotNull(requirements, "requirements"));
return this;
}
/**
* @see Dataset#getRequirements()
*/
public Builder addRequirement(String name, JsonBall values) {
this.requirements.put(checkNotNull(name, "name"), checkNotNull(values, "value of %s", name));
return this;
}
/**
* @see Dataset#getVersion()
*/
public Builder version(String version) {
this.version = version;
return this;
}
/**
* @see Dataset#getCreated()
*/
public Builder created(Date created) { public Builder created(Date created) {
this.created = created; this.created = created;
return this; return this;
} }
public Dataset build() { public Dataset build() {
return new Dataset(id, name, type, version, urn, isDefault, created); return new Dataset(id, urn, name, os, type, description, isDefault, requirements.build(), version,
created);
} }
public Builder fromDataset(Dataset in) { public Builder fromDataset(Dataset in) {
return id(in.getId()).name(in.getName()).type(in.getType()).version(in.getVersion()).urn(in.getUrn()) return id(in.getId()).urn(in.getUrn()).name(in.getName()).os(in.getOs()).type(in.getType()).description(in.getDescription())
.isDefault(in.isDefault()).created(in.getCreated()); .isDefault(in.isDefault()).requirements(in.requirements).version(in.getVersion()).created(in.getCreated());
} }
} }
// The globally unique id for this dataset private final String id;
protected final String id; private final String name;
// The "friendly" name for this dataset private final String os;
protected final String name; private final String urn;
// Whether this is a smartmachine or virtualmachine private final Type type;
protected final Type type; private final String description;
// The version for this dataset @Named("default")
protected final String version; private final boolean isDefault;
// The full URN for this dataset private final Map<String, JsonBall> requirements;
protected final String urn; private final String version;
// Whether this is the default dataset in this datacenter private final Date created;
@SerializedName("default")
protected final boolean isDefault; @ConstructorProperties({ "id", "urn", "name", "os", "type", "description", "default", "requirements", "version",
// Date (ISO8601) When this dataset was created "created" })
protected final Date created; public Dataset(String id, String urn, String name, String os, Type type, String description, boolean isDefault,
Map<String, JsonBall> requirements, String version, Date created) {
public Dataset(String id, String name, Type type, String version, String urn, boolean isDefault, Date created) { this.id = checkNotNull(id, "id");
super(); this.urn = checkNotNull(urn, "urn of dataset(%s)", id);
this.id = id; this.name = checkNotNull(name, "name of dataset(%s)", id);
this.name = name; this.os = checkNotNull(os, "os of dataset(%s)", id);
this.type = type; this.type = checkNotNull(type, "type of dataset(%s)", id);
this.version = version; this.description = checkNotNull(description, "description of dataset(%s)", id);
this.urn = urn;
this.isDefault = isDefault; this.isDefault = isDefault;
this.created = created; this.requirements = ImmutableMap.copyOf(checkNotNull(requirements, "requirements of dataset(%s)", id));
this.version = checkNotNull(version, "version of dataset(%s)", id);
this.created = checkNotNull(created, "created of dataset(%s)", id);
} }
/**
* The globally unique id for this dataset
*/
public String getId() { public String getId() {
return id; return id;
} }
/**
* The full URN for this dataset
*/
public String getUrn() {
return urn;
}
/**
* The friendly name for this dataset
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* The underlying operating system for this dataset
*/
public String getOs() {
return os;
}
/**
* Whether this is a smartmachine or virtualmachine dataset
*/
public Type getType() { public Type getType() {
return type; return type;
} }
public String getVersion() { /**
return version; * The description of this dataset
*/
public String getDescription() {
return description;
} }
public String getUrn() { /**
return urn; * Whether this is the default dataset in this datacenter
} */
public boolean isDefault() { public boolean isDefault() {
return isDefault; return isDefault;
} }
/**
* If the value is a string, it will be quoted, as that's how json strings are represented.
*
* @return key to a json literal of the value
* @see #getRequirements
* @see Json#fromJson
*/
public Map<String, String> getRequirementsAsJsonLiterals() {
return Maps.transformValues(requirements, Functions.toStringFunction());
}
/**
* Contains a grouping of various minimum requirements for provisioning a machine with this
* dataset. For example 'password' indicates that a password must be provided.
*
* <h4>Note</h4>
*
* requirements can contain arbitrarily complex values. If the value has structure, you should
* use {@link #getRequirementsAsJsonLiterals}
*/
public Map<String, String> getRequirements() {
return Maps.transformValues(requirements, Functions.compose(Functions.toStringFunction(), unquoteString));
}
/**
* The version for this dataset
*/
public String getVersion() {
return version;
}
/**
* When the dataset was created
*/
public Date getCreated() { public Date getCreated() {
return created; return created;
} }
@Override @VisibleForTesting
public int compareTo(Dataset other) { static final Function<JsonBall, String> unquoteString = new Function<JsonBall, String>() {
return id.compareTo(other.getId());
} @Override
public String apply(JsonBall input) {
String value = input.toString();
if (value.length() >= 2 && value.charAt(0) == '"' && value.charAt(input.length() - 1) == '"')
return value.substring(1, input.length() - 1);
return value;
}
};
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
if (this == object) { if (this == object) {
return true; return true;
} }
if (object instanceof Machine) { if (object instanceof Dataset) {
return Objects.equal(id, ((Machine) object).id); Dataset that = Dataset.class.cast(object);
return Objects.equal(id, that.id);
} else { } else {
return false; return false;
} }
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(id); return Objects.hashCode(id);
} }
@Override @Override
public String toString() { public String toString() {
return String.format("[id=%s, name=%s, type=%s, version=%s, urn=%s, default=%s, created=%s]", id, name, return Objects.toStringHelper("").omitNullValues()
type.name(), type.name(), version, urn, isDefault, created); .add("id", id)
.add("urn", urn)
.add("name", name)
.add("os", os)
.add("type", type)
.add("description", description)
.add("default", isDefault)
.add("requirements", requirements)
.add("version", version)
.add("created", created).toString();
} }
@Override
public int compareTo(Dataset that) {
return ComparisonChain.start()
.compare(this.urn, that.urn)
.compare(this.name, that.name)
.compare(this.os, that.os)
.compare(this.type, that.type)
.compare(this.description, that.description)
.compare(this.version, that.version)
.compare(this.created, that.created)
.compare(this.id, that.id).result();
}
} }

View File

@ -1,17 +1,37 @@
/**
* 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.joyent.cloudapi.v6_5.domain; package org.jclouds.joyent.cloudapi.v6_5.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date; import java.util.Date;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
/** /**
* Keys are the means by which you operate on your SSH/signing keys. Currently * Keys are the means by which you operate on your SSH/signing keys. Currently
* CloudAPI supports uploads of public keys in the OpenSSH format. * CloudAPI supports uploads of public keys in the OpenSSH format.
* *
* @author Adrian Cole * @author Adrian Cole
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi/#keys" >docs</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#ListKeys" >docs</a>
*/ */
public class Key implements Comparable<Key> { public class Key implements Comparable<Key> {
@ -26,18 +46,27 @@ public class Key implements Comparable<Key> {
public static class Builder { public static class Builder {
private String name; private String name;
private String key; private String key;
private Date created; private Date created = new Date();
/**
* @see Key#getName()
*/
public Builder name(String name) { public Builder name(String name) {
this.name = name; this.name = name;
return this; return this;
} }
/**
* @see Key#get()
*/
public Builder key(String key) { public Builder key(String key) {
this.key = key; this.key = key;
return this; return this;
} }
/**
* @see Key#getCreated()
*/
public Builder created(Date created) { public Builder created(Date created) {
this.created = created; this.created = created;
return this; return this;
@ -54,12 +83,14 @@ public class Key implements Comparable<Key> {
protected final String name; protected final String name;
protected final String key; protected final String key;
protected final Date created; // don't include created in the http request
transient protected final Date created;
@ConstructorProperties({ "name", "key", "created" })
public Key(String name, String key, Date created) { public Key(String name, String key, Date created) {
this.name = checkNotNull(name, "name"); this.name = checkNotNull(name, "name");
this.key = checkNotNull(key, "key: OpenSSH formatted public key"); this.key = checkNotNull(key, "key: OpenSSH formatted public key of key(%s)", name);
this.created = created; this.created = checkNotNull(created, "created date of key(%s)", name);
} }
/** /**
@ -75,23 +106,22 @@ public class Key implements Comparable<Key> {
public String get() { public String get() {
return key; return key;
} }
/**
* Date the key was created
*/
public Date getCreated() { public Date getCreated() {
return created; return created;
} }
@Override
public int compareTo(Key other) {
return name.compareTo(other.getName());
}
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
if (this == object) { if (this == object) {
return true; return true;
} }
if (object instanceof Key) { if (object instanceof Key) {
return Objects.equal(name, ((Key) object).name); Key that = Key.class.cast(object);
return Objects.equal(name, that.name);
} else { } else {
return false; return false;
} }
@ -104,6 +134,16 @@ public class Key implements Comparable<Key> {
@Override @Override
public String toString() { public String toString() {
return String.format("[name=%s, key=%s, created=%s]", name, key, created); return Objects.toStringHelper("").omitNullValues()
.add("name", name)
.add("key", key)
.add("created", created).toString();
}
@Override
public int compareTo(Key that) {
return ComparisonChain.start()
.compare(this.name, that.name)
.compare(this.created, that.created).result();
} }
} }

View File

@ -20,10 +20,13 @@ package org.jclouds.joyent.cloudapi.v6_5.domain;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.inject.Named;
import org.jclouds.domain.JsonBall; import org.jclouds.domain.JsonBall;
import org.jclouds.joyent.cloudapi.v6_5.reference.Metadata; import org.jclouds.joyent.cloudapi.v6_5.reference.Metadata;
import org.jclouds.json.Json; import org.jclouds.json.Json;
@ -33,19 +36,40 @@ import com.google.common.base.CaseFormat;
import com.google.common.base.Function; import com.google.common.base.Function;
import com.google.common.base.Functions; import com.google.common.base.Functions;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.annotations.SerializedName;
/** /**
* Listing of a machine. * a SmartMachine or traditional Virtual Machine
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see <a href= "http://apidocs.joyent.com/cloudApiapidoc/cloudapi/#machines" /> * @see <a href= "http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#machines" />
*/ */
public class Machine implements Comparable<Machine> { public class Machine implements Comparable<Machine> {
public static enum Type {
VIRTUALMACHINE, SMARTMACHINE, UNRECOGNIZED;
public static Type fromValue(String type) {
try {
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
public String value() {
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()));
}
@Override
public String toString() {
return value();
}
}
public static enum State { public static enum State {
PROVISIONING, RUNNING, STOPPING, STOPPED, OFFLINE, DELETED, UNRECOGNIZED; PROVISIONING, RUNNING, STOPPING, STOPPED, OFFLINE, DELETED, UNRECOGNIZED;
@ -83,56 +107,95 @@ public class Machine implements Comparable<Machine> {
private String dataset; private String dataset;
private int memorySizeMb; private int memorySizeMb;
private int diskSizeGb; private int diskSizeGb;
private Set<String> ips; private ImmutableSet.Builder<String> ips = ImmutableSet.<String> builder();
private Date created; private Date created;
private Date updated; private Date updated;
private Map<String, JsonBall> metadata = ImmutableMap.of(); private ImmutableMap.Builder<String, JsonBall> metadata = ImmutableMap.<String, JsonBall>builder();
/**
* @see Machine#getId()
*/
public Builder id(String id) { public Builder id(String id) {
this.id = id; this.id = id;
return this; return this;
} }
/**
* @see Machine#getName()
*/
public Builder name(String name) { public Builder name(String name) {
this.name = name; this.name = name;
return this; return this;
} }
/**
* @see Machine#getType()
*/
public Builder type(Type type) { public Builder type(Type type) {
this.type = type; this.type = type;
return this; return this;
} }
/**
* @see Machine#getState()
*/
public Builder state(State state) { public Builder state(State state) {
this.state = state; this.state = state;
return this; return this;
} }
/**
* @see Machine#getDatasetURN()
*/
public Builder dataset(String dataset) { public Builder dataset(String dataset) {
this.dataset = dataset; this.dataset = dataset;
return this; return this;
} }
/**
* @see Machine#getMemorySizeMb()
*/
public Builder memorySizeMb(int memorySizeMb) { public Builder memorySizeMb(int memorySizeMb) {
this.memorySizeMb = memorySizeMb; this.memorySizeMb = memorySizeMb;
return this; return this;
} }
/**
* @see Machine#getDiskSizeGb()
*/
public Builder diskSizeGb(int diskSizeGb) { public Builder diskSizeGb(int diskSizeGb) {
this.diskSizeGb = diskSizeGb; this.diskSizeGb = diskSizeGb;
return this; return this;
} }
/**
* @see Machine#getIps()
*/
public Builder ips(Set<String> ips) { public Builder ips(Set<String> ips) {
this.ips = ips; this.ips = ImmutableSet.<String> builder();
this.ips.addAll(checkNotNull(ips, "ips"));
return this; return this;
} }
/**
* @see Machine#getIps()
*/
public Builder addIp(String ip) {
this.ips.add(checkNotNull(ip, "ip"));
return this;
}
/**
* @see Machine#getCreated()
*/
public Builder created(Date created) { public Builder created(Date created) {
this.created = created; this.created = created;
return this; return this;
} }
/**
* @see Machine#getUpdated()
*/
public Builder updated(Date updated) { public Builder updated(Date updated) {
this.updated = updated; this.updated = updated;
return this; return this;
@ -142,110 +205,137 @@ public class Machine implements Comparable<Machine> {
* @see Machine#getMetadata() * @see Machine#getMetadata()
*/ */
public Builder metadata(Map<String, JsonBall> metadata) { public Builder metadata(Map<String, JsonBall> metadata) {
this.metadata = metadata; this.metadata = ImmutableMap.<String, JsonBall> builder();
this.metadata.putAll(checkNotNull(metadata, "metadata"));
return this;
}
/**
* @see Machine#getMetadata()
*/
public Builder addMetadata(String name, JsonBall values) {
this.metadata.put(checkNotNull(name, "name"), checkNotNull(values, "value of %s", name));
return this; return this;
} }
public Machine build() { public Machine build() {
return new Machine(id, name, type, state, dataset, memorySizeMb, diskSizeGb, ips, created, updated, metadata); return new Machine(id, name, type, state, dataset, memorySizeMb, diskSizeGb, ips.build(), created, updated, metadata.build());
} }
public Builder fromMachine(Machine in) { public Builder fromMachine(Machine in) {
return id(in.getId()).name(in.getName()).type(in.getType()).state(in.getState()).dataset(in.get()) return id(in.getId()).name(in.getName()).type(in.getType()).state(in.getState()).dataset(in.getDatasetURN())
.memorySizeMb(in.getMemorySizeMb()).diskSizeGb(in.getDiskSizeGb()).ips(in.getIps()) .memorySizeMb(in.getMemorySizeMb()).diskSizeGb(in.getDiskSizeGb()).ips(in.getIps())
.metadata(in.metadata).created(in.getCreated()).updated(in.getUpdated()); .metadata(in.metadata).created(in.getCreated()).updated(in.getUpdated());
} }
} }
// The globally unique id for this machine
protected final String id; protected final String id;
// The "friendly" name for this machine
protected final String name; protected final String name;
// Whether this is a smartmachine or virtualmachine
protected final Type type; protected final Type type;
// The current state of this machine
protected final State state; protected final State state;
// The dataset urn this machine was provisioned with
protected final String dataset; protected final String dataset;
// The amount of memory this machine has (Mb) @Named("memory")
@SerializedName("memory")
protected final int memorySizeMb; protected final int memorySizeMb;
// The amount of disk this machine has (Gb) @Named("disk")
@SerializedName("disk")
protected final int diskSizeGb; protected final int diskSizeGb;
// The IP addresses this machine has
protected final Set<String> ips; protected final Set<String> ips;
// Date (ISO8601) When this machine was created
protected final Date created; protected final Date created;
// Date (ISO8601) When this machine was updated
protected final Date updated; protected final Date updated;
// metadata Object[String => String] Any "extra" metadata this machine has // metadata Object[String => String] Any "extra" metadata this machine has
private final Map<String, JsonBall> metadata; private final Map<String, JsonBall> metadata;
@Override @ConstructorProperties({ "id", "name", "type", "state", "dataset", "memory", "disk", "ips", "created", "updated", "metadata" })
public int compareTo(Machine other) {
return id.compareTo(other.getId());
}
public Machine(String id, String name, Type type, State state, String dataset, int memorySizeMb, int diskSizeGb, public Machine(String id, String name, Type type, State state, String dataset, int memorySizeMb, int diskSizeGb,
Set<String> ips, Date created, Date updated, final Map<String, JsonBall> metadata) { Set<String> ips, Date created, Date updated, final Map<String, JsonBall> metadata) {
super(); this.id = checkNotNull(id, "id");
this.id = id; this.name = checkNotNull(name, "name of machine(%s)", id);
this.name = name; this.type = checkNotNull(type, "type of machine(%s)", id);
this.type = type; this.state = checkNotNull(state, "state of machine(%s)", id);
this.state = state; this.dataset = checkNotNull(dataset, "dataset of machine(%s)", id);
this.dataset = dataset;
this.memorySizeMb = memorySizeMb; this.memorySizeMb = memorySizeMb;
this.diskSizeGb = diskSizeGb; this.diskSizeGb = diskSizeGb;
this.ips = ImmutableSet.<String> copyOf(ips); this.ips = ImmutableSet.<String> copyOf(checkNotNull(ips, "ips of machine(%s)", id));
this.created = created; this.created = checkNotNull(created, "created date of machine(%s)", id);
this.updated = updated; this.updated = checkNotNull(created, "updated date of machine(%s)", id);
this.metadata = metadata; this.metadata = ImmutableMap.<String, JsonBall> copyOf(checkNotNull(metadata, "metadata of machine(%s)", id));
} }
/**
* The globally unique id for this machine
*/
public String getId() { public String getId() {
return id; return id;
} }
/**
* The "friendly" name for this machine
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* Whether this is a smartmachine or virtualmachine
*/
public Type getType() { public Type getType() {
return type; return type;
} }
/**
* The current state of this machine
*/
public State getState() { public State getState() {
return state; return state;
} }
public String get() { /**
* The dataset urn this machine was provisioned with
*/
public String getDatasetURN() {
return dataset; return dataset;
} }
/**
* The amount of memory this machine has (Mb)
*/
public int getMemorySizeMb() { public int getMemorySizeMb() {
return memorySizeMb; return memorySizeMb;
} }
/**
* The amount of disk this machine has (Gb)
*/
public int getDiskSizeGb() { public int getDiskSizeGb() {
return diskSizeGb; return diskSizeGb;
} }
/**
* The IP addresses this machine has
*/
public Set<String> getIps() { public Set<String> getIps() {
return ips; return ips;
} }
/**
* When this machine was created
*/
public Date getCreated() { public Date getCreated() {
return created; return created;
} }
/**
* When this machine was updated
*/
public Date getUpdated() { public Date getUpdated() {
return updated; return updated;
} }
/** /**
* If the value is a string, it will be quoted, as that's how json strings are represented. *
* <h4>note</h4>
*
* If the value is a string, it will be quoted, as that's how json strings are represented.
* *
* @return key to a json literal of the value * @return key to a json literal of the value
* @see Metadata#valueType * @see Metadata#valueType
@ -256,9 +346,13 @@ public class Machine implements Comparable<Machine> {
} }
/** /**
* Note!! metadata can contain arbitrarily complex values. If the value has structure, you should use {@link #getMetadataAsJsonLiterals} * Any "extra" metadata this machine has
*
* <h4>note</h4>
*
* metadata can contain arbitrarily complex values. If the value has structure, you should use
* {@link #getMetadataAsJsonLiterals}
* *
* @return metadata
*/ */
public Map<String, String> getMetadata() { public Map<String, String> getMetadata() {
return Maps.transformValues(metadata, Functions.compose(Functions.toStringFunction(), unquoteString)); return Maps.transformValues(metadata, Functions.compose(Functions.toStringFunction(), unquoteString));
@ -276,14 +370,15 @@ public class Machine implements Comparable<Machine> {
} }
}; };
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
if (this == object) { if (this == object) {
return true; return true;
} }
if (object instanceof Machine) { if (object instanceof Machine) {
return Objects.equal(id, ((Machine) object).id); Machine that = Machine.class.cast(object);
return Objects.equal(id, that.id);
} else { } else {
return false; return false;
} }
@ -296,7 +391,23 @@ public class Machine implements Comparable<Machine> {
@Override @Override
public String toString() { public String toString() {
return String.format("[id=%s, name=%s, type=%s, state=%s, memory=%s, disk=%s, ips=%s, created=%s, updated=%s]", return Objects.toStringHelper("").omitNullValues()
id, name, type.name(), state.name(), memorySizeMb, diskSizeGb, ips, created, updated); .add("id", id)
.add("name", name)
.add("type", type)
.add("state", state)
.add("memorySizeMb", memorySizeMb)
.add("diskSizeGb", diskSizeGb)
.add("ips", ips)
.add("created", created)
.add("updated", updated).toString();
}
@Override
public int compareTo(Machine that) {
return ComparisonChain.start()
.compare(this.name, that.name)
.compare(this.created, that.created)
.compare(this.id, that.id).result();
} }
} }

View File

@ -18,20 +18,32 @@
*/ */
package org.jclouds.joyent.cloudapi.v6_5.domain; package org.jclouds.joyent.cloudapi.v6_5.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import java.beans.ConstructorProperties;
import javax.inject.Named;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.gson.annotations.SerializedName; import com.google.common.collect.ComparisonChain;
/** /**
* Listing of a package. * Packages are named collections of resources that are used to describe the sizes of either a
* smart machine or a virtual machine. These resources include (but are not limited to) RAM, CPUs,
* CPU Caps, Lightweight Threads, Disk Space, Swap size, and Logical Networks.
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see <a href= "http://apidocs.joyent.com/cloudApiapidoc/cloudapi/#machines" /> * @see <a href= "http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#packages" >docs</a>
*/ */
public class Package implements Comparable<Package> { public class Package implements Comparable<Package> {
public static Builder builder() { public static Builder builder() {
return new Builder(); return new Builder();
} }
public Builder toBuilder() {
return new Builder().fromPackage(this);
}
public static class Builder { public static class Builder {
private String name; private String name;
@ -40,26 +52,41 @@ public class Package implements Comparable<Package> {
private int swapSizeMb; private int swapSizeMb;
private boolean isDefault; private boolean isDefault;
/**
* @see Package#getName()
*/
public Builder name(String name) { public Builder name(String name) {
this.name = name; this.name = name;
return this; return this;
} }
/**
* @see Package#getMemorySizeMb()
*/
public Builder memorySizeMb(int memorySizeMb) { public Builder memorySizeMb(int memorySizeMb) {
this.memorySizeMb = memorySizeMb; this.memorySizeMb = memorySizeMb;
return this; return this;
} }
/**
* @see Package#getDiskSizeGb()
*/
public Builder diskSizeGb(int diskSizeGb) { public Builder diskSizeGb(int diskSizeGb) {
this.diskSizeGb = diskSizeGb; this.diskSizeGb = diskSizeGb;
return this; return this;
} }
/**
* @see Package#getSwapSizeMb()
*/
public Builder swapSizeMb(int swapSizeMb) { public Builder swapSizeMb(int swapSizeMb) {
this.swapSizeMb = swapSizeMb; this.swapSizeMb = swapSizeMb;
return this; return this;
} }
/**
* @see Package#isDefault()
*/
public Builder isDefault(boolean isDefault) { public Builder isDefault(boolean isDefault) {
this.isDefault = isDefault; this.isDefault = isDefault;
return this; return this;
@ -75,51 +102,56 @@ public class Package implements Comparable<Package> {
} }
} }
// The "friendly" name for this machine
protected final String name; protected final String name;
// The amount of memory this package has (Mb) @Named("memory")
@SerializedName("memory")
protected final int memorySizeMb; protected final int memorySizeMb;
// The amount of disk this package has (Gb) @Named("disk")
@SerializedName("disk")
protected final int diskSizeGb; protected final int diskSizeGb;
// The amount of swap this package has (Gb) @Named("swap")
@SerializedName("swap")
protected final int swapSizeMb; protected final int swapSizeMb;
// Whether this is the default package in this datacenter @Named("default")
@SerializedName("default")
protected final boolean isDefault; protected final boolean isDefault;
@Override @ConstructorProperties({ "name", "memory", "disk", "swap", "default" })
public int compareTo(Package other) {
return name.compareTo(other.getName());
}
public Package(String name, int memorySizeMb, int diskSizeGb, int swapSizeMb, boolean isDefault) { public Package(String name, int memorySizeMb, int diskSizeGb, int swapSizeMb, boolean isDefault) {
super(); this.name = checkNotNull(name, "name");
this.name = name;
this.memorySizeMb = memorySizeMb; this.memorySizeMb = memorySizeMb;
this.diskSizeGb = diskSizeGb; this.diskSizeGb = diskSizeGb;
this.swapSizeMb = swapSizeMb; this.swapSizeMb = swapSizeMb;
this.isDefault = isDefault; this.isDefault = isDefault;
} }
/**
* The "friendly name for this package
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* How much memory will by available (in Mb)
*/
public int getMemorySizeMb() { public int getMemorySizeMb() {
return memorySizeMb; return memorySizeMb;
} }
/**
* How much disk space will be available (in Gb)
*/
public int getDiskSizeGb() { public int getDiskSizeGb() {
return diskSizeGb; return diskSizeGb;
} }
/**
* How much swap memory will be available (in Mb)
*/
public int getSwapSizeMb() { public int getSwapSizeMb() {
return swapSizeMb; return swapSizeMb;
} }
/**
* Whether this is the default package in this datacenter
*/
public boolean isDefault() { public boolean isDefault() {
return isDefault; return isDefault;
} }
@ -130,7 +162,8 @@ public class Package implements Comparable<Package> {
return true; return true;
} }
if (object instanceof Package) { if (object instanceof Package) {
return Objects.equal(name, ((Package) object).name); Package that = Package.class.cast(object);
return Objects.equal(name, that.name);
} else { } else {
return false; return false;
} }
@ -143,7 +176,20 @@ public class Package implements Comparable<Package> {
@Override @Override
public String toString() { public String toString() {
return String.format("[name=%s, memory=%s, disk=%s, swap=%s, default=%s]", name, memorySizeMb, diskSizeGb, return Objects.toStringHelper("").omitNullValues()
swapSizeMb, isDefault); .add("name", name)
.add("memorySizeMb", memorySizeMb)
.add("diskSizeGb", diskSizeGb)
.add("swapSizeMb", swapSizeMb)
.add("isDefault", isDefault).toString();
}
@Override
public int compareTo(Package that) {
return ComparisonChain.start()
.compare(this.name, that.name)
.compare(this.memorySizeMb, that.memorySizeMb)
.compare(this.diskSizeGb, that.diskSizeGb)
.compare(this.swapSizeMb, that.swapSizeMb).result();
} }
} }

View File

@ -1,26 +0,0 @@
package org.jclouds.joyent.cloudapi.v6_5.domain;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.CaseFormat;
public enum Type {
VIRTUALMACHINE, SMARTMACHINE, UNRECOGNIZED;
public static Type fromValue(String type) {
try {
return valueOf(CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, checkNotNull(type, "type")));
} catch (IllegalArgumentException e) {
return UNRECOGNIZED;
}
}
public String value() {
return (CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name()));
}
@Override
public String toString() {
return value();
}
}

View File

@ -29,7 +29,7 @@ public class DatasetInDatacenter extends DatacenterAndId {
protected final Dataset dataset; protected final Dataset dataset;
public DatasetInDatacenter(Dataset dataset, String datacenterId) { public DatasetInDatacenter(Dataset dataset, String datacenterId) {
super(datacenterId, checkNotNull(dataset, "dataset").getId()); super(datacenterId, checkNotNull(dataset, "dataset").getUrn());
this.dataset = dataset; this.dataset = dataset;
} }

View File

@ -29,7 +29,7 @@ import org.jclouds.concurrent.Timeout;
* *
* @see DatacenterAsyncApi * @see DatacenterAsyncApi
* @author Adrian Cole * @author Adrian Cole
* @see <a href="http://cloudApi.joyent.org/cloudApiapi.html">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#datacenters">api doc</a>
*/ */
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface DatacenterApi { public interface DatacenterApi {

View File

@ -40,7 +40,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* *
* @see DatacenterApi * @see DatacenterApi
* @author Adrian Cole * @author Adrian Cole
* @see <a href="http://cloudApi.joyent.org/cloudApiapi.html">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#datacenters">api doc</a>
*/ */
@SkipEncoding({ '/', '=' }) @SkipEncoding({ '/', '=' })
@Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}")

View File

@ -12,7 +12,7 @@ import org.jclouds.joyent.cloudapi.v6_5.domain.Dataset;
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see DatasetAsyncApi * @see DatasetAsyncApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#datasets">api doc</a>
*/ */
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface DatasetApi { public interface DatasetApi {

View File

@ -25,7 +25,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see DatasetApi * @see DatasetApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#datasets">api doc</a>
*/ */
@SkipEncoding({ '/', '=' }) @SkipEncoding({ '/', '=' })
@Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}")

View File

@ -12,7 +12,7 @@ import org.jclouds.joyent.cloudapi.v6_5.domain.Key;
* *
* @author Adrian Cole * @author Adrian Cole
* @see KeyAsyncApi * @see KeyAsyncApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi/#keys">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#keys">api doc</a>
*/ */
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface KeyApi { public interface KeyApi {

View File

@ -11,22 +11,23 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.http.filters.BasicAuthentication; import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.joyent.cloudapi.v6_5.binders.BindKeyToJsonPayload;
import org.jclouds.joyent.cloudapi.v6_5.domain.Key; import org.jclouds.joyent.cloudapi.v6_5.domain.Key;
import org.jclouds.rest.annotations.BinderParam; import org.jclouds.rest.annotations.BinderParam;
import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.Headers; import org.jclouds.rest.annotations.Headers;
import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.binders.BindToJsonPayload;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
/** /**
* @author Adrian Cole * @author Adrian Cole
* @see KeyApi * @see KeyApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi/#keys">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#keys">api doc</a>
*/ */
@SkipEncoding({ '/', '=' }) @SkipEncoding({ '/', '=' })
@Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}")
@ -56,7 +57,7 @@ public interface KeyAsyncApi {
@POST @POST
@Path("/my/keys") @Path("/my/keys")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Key> create(@BinderParam(BindKeyToJsonPayload.class) Key key); ListenableFuture<Key> create(@BinderParam(BindToJsonPayload.class) Key key);
/** /**
* @see KeyApi#delete * @see KeyApi#delete
@ -64,6 +65,7 @@ public interface KeyAsyncApi {
@DELETE @DELETE
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/my/keys/{name}") @Path("/my/keys/{name}")
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> delete(@PathParam("name") String name); ListenableFuture<Void> delete(@PathParam("name") String name);
} }

View File

@ -31,7 +31,7 @@ import org.jclouds.joyent.cloudapi.v6_5.options.CreateMachineOptions;
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see MachineAsyncApi * @see MachineAsyncApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#machines">api doc</a>
*/ */
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface MachineApi { public interface MachineApi {

View File

@ -41,6 +41,7 @@ import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.annotations.SkipEncoding;
import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
@ -50,7 +51,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see MachineApi * @see MachineApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#machines">api doc</a>
*/ */
@SkipEncoding({ '/', '=' }) @SkipEncoding({ '/', '=' })
@Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}")
@ -74,7 +75,7 @@ public interface MachineAsyncApi {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Machine> get(@PathParam("id") String id); ListenableFuture<Machine> get(@PathParam("id") String id);
/** /**
* @see MachineApi#createWithDataset(String) * @see MachineApi#createWithDataset(String)
*/ */
@ -82,63 +83,62 @@ public interface MachineAsyncApi {
@Path("/my/machines") @Path("/my/machines")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Machine> createWithDataset(@QueryParam("dataset") String datasetURN); ListenableFuture<Machine> createWithDataset(@QueryParam("dataset") String datasetURN);
/** /**
* @see MachineApi#createWithDataset(String, CreateMachineOptions) * @see MachineApi#createWithDataset(String, CreateMachineOptions)
*/ */
@POST @POST
@Path("/my/machines") @Path("/my/machines")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<Machine> createWithDataset(@QueryParam("dataset") String datasetURN, CreateMachineOptions options); ListenableFuture<Machine> createWithDataset(@QueryParam("dataset") String datasetURN, CreateMachineOptions options);
/** /**
* @see MachineApi#stop * @see MachineApi#stop
*/ */
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/my/machines/{id}") @Path("/my/machines/{id}")
@Payload("action=stop") @Payload("action=stop")
ListenableFuture<Void> stop(@PathParam("id") String id); ListenableFuture<Void> stop(@PathParam("id") String id);
/** /**
* @see MachineApi#start * @see MachineApi#start
*/ */
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/my/machines/{id}") @Path("/my/machines/{id}")
@Payload("action=start") @Payload("action=start")
ListenableFuture<Void> start(@PathParam("id") String id); ListenableFuture<Void> start(@PathParam("id") String id);
/** /**
* @see MachineApi#reboot * @see MachineApi#reboot
*/ */
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/my/machines/{id}") @Path("/my/machines/{id}")
@Payload("action=reboot") @Payload("action=reboot")
ListenableFuture<Void> reboot(@PathParam("id") String id); ListenableFuture<Void> reboot(@PathParam("id") String id);
/** /**
* @see MachineApi#resize * @see MachineApi#resize
*/ */
@POST @POST
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_FORM_URLENCODED) @Produces(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/my/machines/{id}") @Path("/my/machines/{id}")
@Payload("action=resize&package={package}") @Payload("action=resize&package={package}")
ListenableFuture<Void> resize(@PathParam("id") String id,@PayloadParam("package") String packageJoyentCloud); ListenableFuture<Void> resize(@PathParam("id") String id, @PayloadParam("package") String packageJoyentCloud);
/** /**
* @see MachineApi#delete * @see MachineApi#delete
*/ */
@DELETE @DELETE
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@Path("/my/machines/{id}") @Path("/my/machines/{id}")
ListenableFuture<Void> delete(@PathParam("id") String id); @ExceptionParser(ReturnVoidOnNotFoundOr404.class)
ListenableFuture<Void> delete(@PathParam("id") String id);
} }

View File

@ -11,7 +11,7 @@ import org.jclouds.concurrent.Timeout;
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see PackageAsyncApi * @see PackageAsyncApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#packages">api doc</a>
*/ */
@Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS)
public interface PackageApi { public interface PackageApi {

View File

@ -24,7 +24,7 @@ import com.google.common.util.concurrent.ListenableFuture;
* *
* @author Gerald Pereira * @author Gerald Pereira
* @see PackageApi * @see PackageApi
* @see <a href="http://apidocs.joyent.com/cloudApiapidoc/cloudapi">api doc</a> * @see <a href="http://apidocs.joyent.com/sdcapidoc/cloudapi/index.html#packages">api doc</a>
*/ */
@SkipEncoding({ '/', '=' }) @SkipEncoding({ '/', '=' })
@Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}")

View File

@ -1,59 +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.joyent.cloudapi.v6_5.functions.internal;
import java.io.IOException;
import org.jclouds.joyent.cloudapi.v6_5.domain.Machine;
import org.jclouds.joyent.cloudapi.v6_5.domain.Type;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
/**
* @author Adrian Cole
*/
public class JoyentCloudTypeAdapters {
public static class MachineStateAdapter extends TypeAdapter<Machine.State> {
@Override
public void write(JsonWriter writer, Machine.State value) throws IOException {
writer.value(value.value());
}
@Override
public Machine.State read(JsonReader reader) throws IOException {
return Machine.State.fromValue(reader.nextString());
}
}
public static class JoyentCloudTypeAdapter extends TypeAdapter<Type> {
@Override
public void write(JsonWriter writer, Type value) throws IOException {
writer.value(value.value());
}
@Override
public Type read(JsonReader reader) throws IOException {
return Type.fromValue(reader.nextString());
}
}
}

View File

@ -1,5 +1,26 @@
/**
* 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
*
* Unles 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 expres or implied. See the License for the
* specific language governing permisions and limitations
* under the License.
*/
package org.jclouds.joyent.cloudapi.v6_5.suppliers; package org.jclouds.joyent.cloudapi.v6_5.suppliers;
import static com.google.common.collect.Maps.filterKeys;
import static com.google.common.collect.Maps.transformValues;
import java.net.URI; import java.net.URI;
import java.util.Map; import java.util.Map;
@ -7,25 +28,27 @@ import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import org.jclouds.joyent.cloudapi.v6_5.features.DatacenterApi; import org.jclouds.joyent.cloudapi.v6_5.features.DatacenterApi;
import org.jclouds.location.predicates.fromconfig.AnyOrConfiguredZoneId;
import org.jclouds.location.suppliers.ZoneIdToURISupplier; import org.jclouds.location.suppliers.ZoneIdToURISupplier;
import org.jclouds.util.Suppliers2; import org.jclouds.util.Suppliers2;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.collect.Maps;
@Singleton @Singleton
public class ZoneIdToURIFromDatacentersApi implements ZoneIdToURISupplier { public class ZoneIdToURIFromDatacentersApi implements ZoneIdToURISupplier {
private final DatacenterApi api; private final DatacenterApi api;
private final AnyOrConfiguredZoneId filter;
@Inject @Inject
public ZoneIdToURIFromDatacentersApi(DatacenterApi api) { public ZoneIdToURIFromDatacentersApi(DatacenterApi api, AnyOrConfiguredZoneId filter) {
this.api = api; this.api = api;
this.filter = filter;
} }
@Override @Override
public Map<String, Supplier<URI>> get() { public Map<String, Supplier<URI>> get() {
return Maps.transformValues(api.getDatacenters(), Suppliers2.<URI> ofInstanceFunction()); return filterKeys(transformValues(api.getDatacenters(), Suppliers2.<URI> ofInstanceFunction()), filter);
} }
@Override @Override

View File

@ -0,0 +1,141 @@
/**
* 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.joyent.cloudapi.v6_5.compute;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;
import org.jclouds.compute.ComputeService;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.crypto.SshKeyPairGenerator;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.joyent.cloudapi.v6_5.compute.internal.BaseJoyentCloudComputeServiceExpectTest;
import org.jclouds.joyent.cloudapi.v6_5.compute.options.JoyentCloudTemplateOptions;
import org.jclouds.joyent.cloudapi.v6_5.features.DatasetApiExpectTest;
import org.jclouds.joyent.cloudapi.v6_5.features.MachineApiExpectTest;
import org.jclouds.joyent.cloudapi.v6_5.features.PackageApiExpectTest;
import org.jclouds.location.reference.LocationConstants;
import org.testng.annotations.Test;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule;
import com.google.inject.TypeLiteral;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "JoyentCloudComputeServiceExpectTest")
public class JoyentCloudComputeServiceExpectTest extends BaseJoyentCloudComputeServiceExpectTest {
Properties onlySW = new Properties();
public JoyentCloudComputeServiceExpectTest(){
onlySW.setProperty(LocationConstants.PROPERTY_ZONES, "us-sw-1");
}
private ImmutableMap<String, String> keyPair = ImmutableMap.of("public", "ssh-rsa AAAAB3NzaC...", "private",
"-----BEGIN RSA PRIVATE KEY-----\n");
DatasetApiExpectTest datasets = new DatasetApiExpectTest();
PackageApiExpectTest packages = new PackageApiExpectTest();
MachineApiExpectTest machines = new MachineApiExpectTest();
@Test
public void testCreateNodeWithGeneratedKeyPairInWestRegion() throws Exception {
Builder<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.<HttpRequest, HttpResponse> builder();
requestResponseMap.put(getDatacenters, getDatacentersResponse);
requestResponseMap.put(datasets.list, datasets.listResponse);
requestResponseMap.put(packages.list, packages.listResponse);
HttpRequest createKey = HttpRequest.builder().method("POST")
.endpoint("https://api.joyentcloud.com/my/keys")
.addHeader("X-Api-Version", "~6.5")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==")
.payload(
payloadFromStringWithContentType(
"{\"name\":\"jclouds-test-0\",\"key\":\"" + keyPair.get("public") + "\"}",
"application/json")).build();
HttpResponse createKeyResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
.payload(payloadFromResourceWithContentType("/key.json", "application/json; charset=UTF-8"))
.build();
requestResponseMap.put(createKey, createKeyResponse);
// look for number to start count at
requestResponseMap.put(machines.list, machines.listResponse);
HttpRequest createMachine = HttpRequest.builder().method("POST")
.endpoint("https://us-sw-1.api.joyentcloud.com/my/machines?dataset=sdc%3Asdc%3Aubuntu-10.04%3A1.0.1&name=test-1&package=Small%201GB")
.addHeader("X-Api-Version", "~6.5")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build();
HttpResponse createMachineResponse = HttpResponse.builder().statusCode(202).message("HTTP/1.1 202 Accepted")
.payload(payloadFromResourceWithContentType("/new_machine.json", "application/json; charset=UTF-8"))
.build();
requestResponseMap.put(createMachine, createMachineResponse);
ComputeService apiThatCreatesNode = requestsSendResponses(requestResponseMap.build(), new AbstractModule() {
@Override
protected void configure() {
// predicatable node names
final AtomicInteger suffix = new AtomicInteger();
bind(new TypeLiteral<Supplier<String>>() {
}).toInstance(new Supplier<String>() {
@Override
public String get() {
return suffix.getAndIncrement() + "";
}
});
bind(SshKeyPairGenerator.class).toInstance(new SshKeyPairGenerator() {
@Override
public Map<String, String> get() {
return keyPair;
}
});
}
}, onlySW);
TemplateOptions options = apiThatCreatesNode.templateOptions().blockUntilRunning(false);
assertTrue(options.as(JoyentCloudTemplateOptions.class).shouldGenerateKey().get());
NodeMetadata node = Iterables.getOnlyElement(apiThatCreatesNode.createNodesInGroup("test", 1, options));
assertEquals(node.getCredentials().getPrivateKey(), keyPair.get("private"));
}
}

View File

@ -21,6 +21,5 @@ public class JoyentCloudComputeServiceLiveTest extends BaseComputeServiceLiveTes
protected Module getSshModule() { protected Module getSshModule() {
return new SshjSshClientModule(); return new SshjSshClientModule();
} }
} }

View File

@ -44,7 +44,7 @@ import com.google.common.collect.ImmutableMap;
* *
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(testName = "DatasetInDatacenterToHardwareTest") @Test(testName = "DatasetInDatacenterToImageTest")
public class DatasetInDatacenterToImageTest { public class DatasetInDatacenterToImageTest {
Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("joyent-cloudapi") Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("joyent-cloudapi")
@ -66,14 +66,14 @@ public class DatasetInDatacenterToImageTest {
org.jclouds.compute.domain.Image convertedImage = converter.apply(datasetInZoneToConvert); org.jclouds.compute.domain.Image convertedImage = converter.apply(datasetInZoneToConvert);
assertEquals(convertedImage.getId(), datasetInZoneToConvert.slashEncode()); assertEquals(convertedImage.getId(), "us-sw-1/" + datasetToConvert.getUrn());
assertEquals(convertedImage.getProviderId(), datasetToConvert.getId()); assertEquals(convertedImage.getProviderId(), datasetToConvert.getUrn());
assertEquals(convertedImage.getLocation(), locationIndex.get().get("us-sw-1")); assertEquals(convertedImage.getLocation(), locationIndex.get().get("us-sw-1"));
assertEquals(convertedImage.getName(), datasetToConvert.getName()); assertEquals(convertedImage.getName(), datasetToConvert.getName());
assertEquals(convertedImage.getStatus(), org.jclouds.compute.domain.Image.Status.AVAILABLE); assertEquals(convertedImage.getStatus(), org.jclouds.compute.domain.Image.Status.AVAILABLE);
assertEquals(convertedImage.getOperatingSystem(), operatingSystem); assertEquals(convertedImage.getOperatingSystem(), operatingSystem);
assertEquals(convertedImage.getDescription(), datasetToConvert.getUrn()); assertEquals(convertedImage.getDescription(), datasetToConvert.getDescription());
assertEquals(convertedImage.getVersion(), datasetToConvert.getVersion()); assertEquals(convertedImage.getVersion(), datasetToConvert.getVersion());
} }

View File

@ -0,0 +1,57 @@
/**
* 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.joyent.cloudapi.v6_5.compute.internal;
import java.util.Properties;
import org.jclouds.apis.ApiMetadata;
import org.jclouds.compute.ComputeServiceContext;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApiMetadata;
import org.jclouds.joyent.cloudapi.v6_5.internal.BaseJoyentCloudExpectTest;
import com.google.common.base.Function;
import com.google.inject.Module;
/**
* Base class for writing Expect tests with the ComputeService abstraction
*
* @author Adrian Cole
*/
public abstract class BaseJoyentCloudComputeServiceContextExpectTest<T> extends BaseJoyentCloudExpectTest<T> implements
Function<ComputeServiceContext, T> {
@Override
public T createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
return apply(createComputeServiceContext(fn, module, props));
}
private ComputeServiceContext createComputeServiceContext(Function<HttpRequest, HttpResponse> fn, Module module,
Properties props) {
return createInjector(fn, module, props).getInstance(ComputeServiceContext.class);
}
@Override
protected ApiMetadata createApiMetadata() {
return new JoyentCloudApiMetadata();
}
}

View File

@ -16,34 +16,20 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.jclouds.joyent.cloudapi.v6_5.config; package org.jclouds.joyent.cloudapi.v6_5.compute.internal;
import java.lang.reflect.Type; import org.jclouds.compute.ComputeService;
import java.util.Map; import org.jclouds.compute.ComputeServiceContext;
import javax.inject.Singleton;
import org.jclouds.joyent.cloudapi.v6_5.domain.Machine;
import org.jclouds.joyent.cloudapi.v6_5.functions.internal.JoyentCloudTypeAdapters;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
/** /**
*
* @author Adrian Cole * @author Adrian Cole
*/ */
public class JoyentCloudParserModule extends AbstractModule { public class BaseJoyentCloudComputeServiceExpectTest extends BaseJoyentCloudComputeServiceContextExpectTest<ComputeService> {
@Provides
@Singleton
public Map<Type, Object> provideCustomAdapterBindings() {
return ImmutableMap.<Type, Object> of(Machine.State.class, new JoyentCloudTypeAdapters.MachineStateAdapter(), Type.class,
new JoyentCloudTypeAdapters.JoyentCloudTypeAdapter());
}
@Override @Override
protected void configure() { public ComputeService apply(ComputeServiceContext input) {
return input.getComputeService();
} }
} }

View File

@ -22,30 +22,18 @@ import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify; import static org.easymock.EasyMock.verify;
import static org.jclouds.crypto.PemsTest.PRIVATE_KEY;
import static org.jclouds.crypto.PemsTest.PUBLIC_KEY;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.io.IOException; import java.io.IOException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException; import java.security.spec.InvalidKeySpecException;
import java.util.Map;
import org.jclouds.compute.functions.GroupNamingConvention; import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.functions.GroupNamingConvention.Factory; import org.jclouds.compute.functions.GroupNamingConvention.Factory;
import org.jclouds.crypto.Crypto; import org.jclouds.crypto.SshKeyPairGenerator;
import org.jclouds.crypto.Pems;
import org.jclouds.crypto.SshKeys;
import org.jclouds.io.Payloads;
import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi; import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi;
import org.jclouds.joyent.cloudapi.v6_5.compute.internal.KeyAndPrivateKey; import org.jclouds.joyent.cloudapi.v6_5.compute.internal.KeyAndPrivateKey;
import org.jclouds.joyent.cloudapi.v6_5.compute.loaders.CreateUniqueKey;
import org.jclouds.joyent.cloudapi.v6_5.domain.Key; import org.jclouds.joyent.cloudapi.v6_5.domain.Key;
import org.jclouds.joyent.cloudapi.v6_5.domain.datacenterscoped.DatacenterAndName; import org.jclouds.joyent.cloudapi.v6_5.domain.datacenterscoped.DatacenterAndName;
import org.jclouds.joyent.cloudapi.v6_5.features.KeyApi; import org.jclouds.joyent.cloudapi.v6_5.features.KeyApi;
@ -54,21 +42,20 @@ import org.testng.annotations.Test;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
import com.google.common.base.Suppliers; import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Guice; import com.google.inject.Guice;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
import com.google.inject.util.Providers;
/** /**
* @author Adrian Cole * @author Adrian Cole
*/ */
@Test(groups = "unit", testName = "CreateUniqueKeyTest") @Test(groups = "unit", testName = "CreateUniqueKeyTest")
public class CreateUniqueKeyTest { public class CreateUniqueKeyTest {
private static final String lineSeparator = System.getProperty("line.separator"); private ImmutableMap<String, String> keyPair = ImmutableMap.of("public", "ssh-rsa AAAAB3NzaC...", "private",
"-----BEGIN RSA PRIVATE KEY-----\n");
private Factory namingConvention; private Factory namingConvention;
private KeyPair keyPair;
private String openSshKey;
@BeforeClass @BeforeClass
public void setup() throws InvalidKeySpecException, NoSuchAlgorithmException, IOException { public void setup() throws InvalidKeySpecException, NoSuchAlgorithmException, IOException {
@ -80,42 +67,35 @@ public class CreateUniqueKeyTest {
}).toInstance(Suppliers.ofInstance("foo")); }).toInstance(Suppliers.ofInstance("foo"));
} }
}).getInstance(GroupNamingConvention.Factory.class); }).getInstance(GroupNamingConvention.Factory.class);
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyfactory.generatePrivate(Pems.privateKeySpec(Payloads.newStringPayload(PRIVATE_KEY)));
PublicKey publicKey = keyfactory
.generatePublic(Pems.publicKeySpec(Payloads.newStringPayload(PUBLIC_KEY)));
keyPair = new KeyPair(publicKey, privateKey);
openSshKey = SshKeys.encodeAsOpenSSH(RSAPublicKey.class.cast(publicKey));
} }
@Test @Test
public void testApply() { public void testApply() {
JoyentCloudApi cloudApiApi = createMock(JoyentCloudApi.class); JoyentCloudApi cloudApiApi = createMock(JoyentCloudApi.class);
SshKeyPairGenerator sshKeyPairGenerator = new SshKeyPairGenerator() {
@Override
public Map<String, String> get() {
return keyPair;
}
};
KeyApi keyApi = createMock(KeyApi.class); KeyApi keyApi = createMock(KeyApi.class);
Crypto crypto = createMock(Crypto.class); Key key = Key.builder().name("group-foo").key(keyPair.get("public")).build();
KeyPairGenerator rsaKeyPairGenerator = createMock(KeyPairGenerator.class);
SecureRandom secureRandom = createMock(SecureRandom.class);
Key key = Key.builder().name("group-foo").key(openSshKey).build();
expect(crypto.rsaKeyPairGenerator()).andReturn(rsaKeyPairGenerator);
rsaKeyPairGenerator.initialize(2048, secureRandom);
expect(rsaKeyPairGenerator.genKeyPair()).andReturn(keyPair);
expect(cloudApiApi.getKeyApi()).andReturn(keyApi); expect(cloudApiApi.getKeyApi()).andReturn(keyApi);
expect(keyApi.create(key)).andReturn(key); expect(keyApi.create(key)).andReturn(key);
replay(cloudApiApi, keyApi, crypto, rsaKeyPairGenerator, secureRandom); replay(cloudApiApi, keyApi);
CreateUniqueKey parser = new CreateUniqueKey(cloudApiApi, namingConvention, crypto, Providers.of(secureRandom)); CreateUniqueKey parser = new CreateUniqueKey(cloudApiApi, namingConvention, sshKeyPairGenerator);
assertEquals(parser.load(DatacenterAndName.fromDatacenterAndName("datacenter", "group")), assertEquals(parser.load(DatacenterAndName.fromDatacenterAndName("datacenter", "group")),
KeyAndPrivateKey.fromKeyAndPrivateKey(key, PRIVATE_KEY.replaceAll("\n", lineSeparator))); KeyAndPrivateKey.fromKeyAndPrivateKey(key, keyPair.get("private")));
verify(cloudApiApi, keyApi, crypto, rsaKeyPairGenerator, secureRandom); verify(cloudApiApi, keyApi);
} }
} }

View File

@ -47,19 +47,19 @@ public class JoyentCloudTemplateOptionsTest {
@Test @Test
public void testGenerateKeyDefault() { public void testGenerateKeyDefault() {
JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions(); JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions();
assert !options.shouldGenerateKey(); assert !options.shouldGenerateKey().isPresent();
} }
@Test @Test
public void testGenerateKey() { public void testGenerateKey() {
JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions().generateKey(true); JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions().generateKey(true);
assert options.shouldGenerateKey(); assert options.shouldGenerateKey().get();
} }
@Test @Test
public void testGenerateKeyStatic() { public void testGenerateKeyStatic() {
JoyentCloudTemplateOptions options = generateKey(true); JoyentCloudTemplateOptions options = generateKey(true);
assert options.shouldGenerateKey(); assert options.shouldGenerateKey().get();
} }
// superclass tests // superclass tests

View File

@ -20,8 +20,6 @@ package org.jclouds.joyent.cloudapi.v6_5.features;
import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertEquals;
import java.net.URI;
import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse; import org.jclouds.http.HttpResponse;
import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi; import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi;
@ -29,7 +27,6 @@ import org.jclouds.joyent.cloudapi.v6_5.internal.BaseJoyentCloudApiExpectTest;
import org.jclouds.joyent.cloudapi.v6_5.parse.ParseDatasetListTest; import org.jclouds.joyent.cloudapi.v6_5.parse.ParseDatasetListTest;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
/** /**
@ -37,14 +34,16 @@ import com.google.common.collect.ImmutableSet;
*/ */
@Test(groups = "unit", testName = "DatasetApiExpectTest") @Test(groups = "unit", testName = "DatasetApiExpectTest")
public class DatasetApiExpectTest extends BaseJoyentCloudApiExpectTest { public class DatasetApiExpectTest extends BaseJoyentCloudApiExpectTest {
HttpRequest list = HttpRequest.builder().method("GET").endpoint( public HttpRequest list = HttpRequest.builder().method("GET")
URI.create("https://us-sw-1.api.joyentcloud.com/my/datasets")).headers( .endpoint("https://us-sw-1.api.joyentcloud.com/my/datasets")
ImmutableMultimap.<String, String> builder().put("X-Api-Version", "~6.5").put("Accept", "application/json") .addHeader("X-Api-Version", "~6.5")
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(); .addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build();
public HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/dataset_list.json")).build();
public void testListDatasetsWhenResponseIs2xx() { public void testListDatasetsWhenResponseIs2xx() {
HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResource("/dataset_list.json")).build();
JoyentCloudApi apiWhenDatasetsExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse); JoyentCloudApi apiWhenDatasetsExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse);
@ -59,15 +58,4 @@ public class DatasetApiExpectTest extends BaseJoyentCloudApiExpectTest {
assertEquals(listWhenNone.getDatasetApiForDatacenter("us-sw-1").list(), ImmutableSet.of()); assertEquals(listWhenNone.getDatasetApiForDatacenter("us-sw-1").list(), ImmutableSet.of());
} }
// [id=e4cd7b9e-4330-11e1-81cf-3bb50a972bda, name=centos-6, type=VIRTUALMACHINE, version=1.0.1,
// urn=sdc:sdc:centos-6:1.0.1, default=false, created=Mon Feb 13 07:30:33 CET 2012],
// [id=e4cd7b9e-4330-11e1-81cf-3bb50a972bda, name=centos-6, type=VIRTUALMACHINE, version=1.0.1,
// urn=sdc:sdc:centos-6:1.0.1, default=false, created=Mon Feb 13 07:30:33 CET 2012],
//
// [id=e62c30b4-cdda-11e0-9dd4-af4d032032e3, name=nodejs, type=SMARTMACHINE, version=1.2.3,
// urn=sdc:sdc:nodejs:1.2.3, default=false, created=Thu Sep 15 10:15:29 CEST 2011]]
//
// [id=e62c30b4-cdda-11e0-9dd4-af4d032032e3, name=nodejs, type=SMARTMACHINE, version=1.2.3,
// urn=sdc:sdc:nodejs:1.2.3, default=false, created=Thu Sep 15 10:15:29 CEST 2011]] but got
} }

View File

@ -35,15 +35,16 @@ import com.google.common.collect.ImmutableSet;
*/ */
@Test(groups = "unit", testName = "KeyApiExpectTest") @Test(groups = "unit", testName = "KeyApiExpectTest")
public class KeyApiExpectTest extends BaseJoyentCloudApiExpectTest { public class KeyApiExpectTest extends BaseJoyentCloudApiExpectTest {
HttpRequest list = HttpRequest.builder().method("GET") public HttpRequest list = HttpRequest.builder().method("GET")
.endpoint("https://api.joyentcloud.com/my/keys") .endpoint("https://api.joyentcloud.com/my/keys")
.addHeader("X-Api-Version", "~6.5") .addHeader("X-Api-Version", "~6.5")
.addHeader("Accept", "application/json") .addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build();
public HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResource("/key_list.json")).build();
public void testListKeysWhenResponseIs2xx() { public void testListKeysWhenResponseIs2xx() {
HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResource("/key_list.json")).build();
JoyentCloudApi apiWhenKeysExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse); JoyentCloudApi apiWhenKeysExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse);

View File

@ -36,15 +36,16 @@ import com.google.common.collect.ImmutableSet;
*/ */
@Test(groups = "unit", testName = "MachineApiExpectTest") @Test(groups = "unit", testName = "MachineApiExpectTest")
public class MachineApiExpectTest extends BaseJoyentCloudApiExpectTest { public class MachineApiExpectTest extends BaseJoyentCloudApiExpectTest {
HttpRequest list = HttpRequest.builder().method("GET") public HttpRequest list = HttpRequest.builder().method("GET")
.endpoint("https://us-sw-1.api.joyentcloud.com/my/machines") .endpoint("https://us-sw-1.api.joyentcloud.com/my/machines")
.addHeader("X-Api-Version", "~6.5") .addHeader("X-Api-Version", "~6.5")
.addHeader("Accept", "application/json") .addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build();
public HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResource("/machine_list.json")).build();
public void testListMachinesWhenResponseIs2xx() { public void testListMachinesWhenResponseIs2xx() {
HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload(
payloadFromResource("/machine_list.json")).build();
JoyentCloudApi apiWhenMachinesExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse); JoyentCloudApi apiWhenMachinesExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse);

View File

@ -68,7 +68,7 @@ public class MachineApiLiveTest extends BaseJoyentCloudApiLiveTest {
assertEquals(newDetails.getName(), machine.getName()); assertEquals(newDetails.getName(), machine.getName());
assertEquals(newDetails.getType(), machine.getType()); assertEquals(newDetails.getType(), machine.getType());
assertEquals(newDetails.getState(), machine.getState()); assertEquals(newDetails.getState(), machine.getState());
assertEquals(newDetails.get(), machine.get()); assertEquals(newDetails.getDatasetURN(), machine.getDatasetURN());
assertEquals(newDetails.getMemorySizeMb(), machine.getMemorySizeMb()); assertEquals(newDetails.getMemorySizeMb(), machine.getMemorySizeMb());
assertEquals(newDetails.getDiskSizeGb(), machine.getDiskSizeGb()); assertEquals(newDetails.getDiskSizeGb(), machine.getDiskSizeGb());
assertEquals(newDetails.getIps(), machine.getIps()); assertEquals(newDetails.getIps(), machine.getIps());

View File

@ -34,15 +34,16 @@ import com.google.common.collect.ImmutableSet;
*/ */
@Test(groups = "unit", testName = "PackageApiExpectTest") @Test(groups = "unit", testName = "PackageApiExpectTest")
public class PackageApiExpectTest extends BaseJoyentCloudApiExpectTest { public class PackageApiExpectTest extends BaseJoyentCloudApiExpectTest {
HttpRequest list = HttpRequest.builder().method("GET") public HttpRequest list = HttpRequest.builder().method("GET")
.endpoint("https://us-sw-1.api.joyentcloud.com/my/packages") .endpoint("https://us-sw-1.api.joyentcloud.com/my/packages")
.addHeader("X-Api-Version", "~6.5") .addHeader("X-Api-Version", "~6.5")
.addHeader("Accept", "application/json") .addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build();
public void testListPackagesWhenResponseIs2xx() { public HttpResponse listResponse = HttpResponse.builder().statusCode(200)
HttpResponse listResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/package_list.json")).build(); .payload(payloadFromResource("/package_list.json")).build();
public void testListPackagesWhenResponseIs2xx() {
JoyentCloudApi apiWhenPackagesExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse); JoyentCloudApi apiWhenPackagesExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse);

View File

@ -18,8 +18,6 @@
*/ */
package org.jclouds.joyent.cloudapi.v6_5.internal; package org.jclouds.joyent.cloudapi.v6_5.internal;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi; import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi;
/** /**
@ -28,13 +26,5 @@ import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BaseJoyentCloudApiExpectTest extends BaseJoyentCloudExpectTest<JoyentCloudApi> { public class BaseJoyentCloudApiExpectTest extends BaseJoyentCloudExpectTest<JoyentCloudApi> {
protected HttpRequest getDatacenters = HttpRequest.builder()
.method("GET")
.endpoint("https://api.joyentcloud.com/my/datacenters")
.addHeader("X-Api-Version", "~6.5")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build();
protected HttpResponse getDatacentersResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/datacenters.json")).build();
} }

View File

@ -18,6 +18,8 @@
*/ */
package org.jclouds.joyent.cloudapi.v6_5.internal; package org.jclouds.joyent.cloudapi.v6_5.internal;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.rest.internal.BaseRestApiExpectTest; import org.jclouds.rest.internal.BaseRestApiExpectTest;
/** /**
@ -26,7 +28,16 @@ import org.jclouds.rest.internal.BaseRestApiExpectTest;
* @author Adrian Cole * @author Adrian Cole
*/ */
public class BaseJoyentCloudExpectTest<T> extends BaseRestApiExpectTest<T> { public class BaseJoyentCloudExpectTest<T> extends BaseRestApiExpectTest<T> {
protected HttpRequest getDatacenters = HttpRequest.builder()
.method("GET")
.endpoint("https://api.joyentcloud.com/my/datacenters")
.addHeader("X-Api-Version", "~6.5")
.addHeader("Accept", "application/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build();
protected HttpResponse getDatacentersResponse = HttpResponse.builder().statusCode(200)
.payload(payloadFromResource("/datacenters.json")).build();
public BaseJoyentCloudExpectTest() { public BaseJoyentCloudExpectTest() {
provider = "joyent-cloudapi"; provider = "joyent-cloudapi";
} }

View File

@ -23,9 +23,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.domain.JsonBall; import org.jclouds.domain.JsonBall;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Machine; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine;
import org.jclouds.joyent.cloudapi.v6_5.domain.Type; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type;
import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -68,7 +67,7 @@ public class ParseCreatedMachineTest extends BaseItemParserTest<Machine> {
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -24,9 +24,8 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Dataset; import org.jclouds.joyent.cloudapi.v6_5.domain.Dataset;
import org.jclouds.joyent.cloudapi.v6_5.domain.Type; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type;
import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -50,21 +49,43 @@ public class ParseDatasetListTest extends BaseSetParserTest<Dataset> {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Set<Dataset> expected() { public Set<Dataset> expected() {
return ImmutableSet.of( return ImmutableSet.of(
Dataset.builder().id("e4cd7b9e-4330-11e1-81cf-3bb50a972bda").name("centos-6").urn("sdc:sdc:centos-6:1.0.1") Dataset.builder()
.type(Type.VIRTUALMACHINE).version("1.0.1").isDefault(false) .id("71101322-43a5-11e1-8f01-cf2a3031a7f4")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-13T06:30:33+00:00")) .urn("sdc:sdc:ubuntu-10.04:1.0.1")
.build(), .name("ubuntu-10.04")
.os("linux")
Dataset.builder().id("e62c30b4-cdda-11e0-9dd4-af4d032032e3").name("nodejs").urn("sdc:sdc:nodejs:1.2.3") .type(Type.VIRTUALMACHINE)
.type(Type.SMARTMACHINE).version("1.2.3").isDefault(false) .description("Ubuntu 10.04 VM 1.0.1")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-09-15T08:15:29+00:00")) .version("1.0.1")
.build() .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-22T18:27:32+00:00"))
.build(),
);
Dataset.builder()
.id("e4cd7b9e-4330-11e1-81cf-3bb50a972bda")
.urn("sdc:sdc:centos-6:1.0.1")
.name("centos-6")
.os("linux")
.type(Type.VIRTUALMACHINE)
.description("Centos 6 VM 1.0.1")
.version("1.0.1")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-15T20:04:18+00:00"))
.build(),
Dataset.builder()
.id("9551fdbc-cc9a-11e1-a9e7-eb1e788a8690")
.urn("sdc:sdc:standard64:1.0.1")
.name("standard64")
.os("smartos")
.type(Type.SMARTMACHINE)
.description("64-bit machine image optimized for web development")
.version("1.0.1")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-07-13T03:30:22+00:00"))
.build()
);
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -22,9 +22,8 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Dataset; import org.jclouds.joyent.cloudapi.v6_5.domain.Dataset;
import org.jclouds.joyent.cloudapi.v6_5.domain.Type; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type;
import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -46,13 +45,20 @@ public class ParseDatasetTest extends BaseItemParserTest<Dataset> {
@Override @Override
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Dataset expected() { public Dataset expected() {
return Dataset.builder().id("e4cd7b9e-4330-11e1-81cf-3bb50a972bda").name("centos-6") return Dataset.builder()
.urn("sdc:sdc:centos-6:1.0.1").type(Type.VIRTUALMACHINE).version("1.0.1").isDefault(false) .id("e4cd7b9e-4330-11e1-81cf-3bb50a972bda")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-13T06:30:33+00:00")).build(); .urn("sdc:sdc:centos-6:1.0.1")
.name("centos-6")
.os("linux")
.type(Type.VIRTUALMACHINE)
.description("Centos 6 VM 1.0.1")
.isDefault(false)
.version("1.0.1")
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-13T06:30:33+00:00")).build();
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -24,7 +24,6 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Key; import org.jclouds.joyent.cloudapi.v6_5.domain.Key;
import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
@ -58,7 +57,7 @@ public class ParseKeyListTest extends BaseSetParserTest<Key> {
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -22,7 +22,6 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Key; import org.jclouds.joyent.cloudapi.v6_5.domain.Key;
import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
@ -53,7 +52,7 @@ public class ParseKeyTest extends BaseItemParserTest<Key> {
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -25,9 +25,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.domain.JsonBall; import org.jclouds.domain.JsonBall;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Machine; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine;
import org.jclouds.joyent.cloudapi.v6_5.domain.Type; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type;
import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -52,8 +51,16 @@ public class ParseMachineListTest extends BaseSetParserTest<Machine> {
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public Set<Machine> expected() { public Set<Machine> expected() {
return ImmutableSet.of( return ImmutableSet.of(
Machine
.builder() Machine.builder().id("d73cb0b0-7d1f-44ef-8c40-e040eef0f726").name("sample-e922").type(Type.SMARTMACHINE)
.state(Machine.State.RUNNING).dataset("sdc:sdc:smartosplus:3.1.0")
.ips(ImmutableSet.<String> builder().add("37.153.96.56").add("10.224.0.57").build())
.memorySizeMb(1024).diskSizeGb(61440).metadata(ImmutableMap.<String, JsonBall> of())
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:39:43+00:00"))
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:43:45+00:00"))
.build(),
Machine.builder()
.id("94eba336-ecb7-49f5-8a27-52f5e4dd57a1") .id("94eba336-ecb7-49f5-8a27-52f5e4dd57a1")
.name("sample-e92") .name("sample-e92")
.type(Type.VIRTUALMACHINE) .type(Type.VIRTUALMACHINE)
@ -67,21 +74,12 @@ public class ParseMachineListTest extends BaseSetParserTest<Machine> {
.put("root_authorized_keys", new JsonBall("ssh-rsa XXXXXX== test@xxxx.ovh.net\n")).build()) .put("root_authorized_keys", new JsonBall("ssh-rsa XXXXXX== test@xxxx.ovh.net\n")).build())
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:32:46+00:00")) .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:32:46+00:00"))
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-11T09:00:33+00:00")) .updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-11T09:00:33+00:00"))
.build(),
Machine.builder().id("d73cb0b0-7d1f-44ef-8c40-e040eef0f726").name("sample-e922").type(Type.SMARTMACHINE)
.state(Machine.State.RUNNING).dataset("sdc:sdc:smartosplus:3.1.0")
.ips(ImmutableSet.<String> builder().add("37.153.96.56").add("10.224.0.57").build())
.memorySizeMb(1024).diskSizeGb(61440).metadata(ImmutableMap.<String, JsonBall> of())
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:39:43+00:00"))
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:43:45+00:00"))
.build() .build()
); );
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -23,9 +23,8 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.domain.JsonBall; import org.jclouds.domain.JsonBall;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Machine; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine;
import org.jclouds.joyent.cloudapi.v6_5.domain.Type; import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type;
import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -67,7 +66,7 @@ public class ParseMachineTest extends BaseItemParserTest<Machine> {
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -23,7 +23,6 @@ import java.util.Set;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.joyent.cloudapi.v6_5.domain.Package; import org.jclouds.joyent.cloudapi.v6_5.domain.Package;
import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.BaseSetParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
@ -57,7 +56,7 @@ public class ParsePackageListTest extends BaseSetParserTest<Package> {
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -21,7 +21,6 @@ package org.jclouds.joyent.cloudapi.v6_5.parse;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule;
import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.BaseItemParserTest;
import org.jclouds.json.config.GsonModule; import org.jclouds.json.config.GsonModule;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -43,12 +42,16 @@ public class ParsePackageTest extends BaseItemParserTest<org.jclouds.joyent.clou
@Override @Override
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
public org.jclouds.joyent.cloudapi.v6_5.domain.Package expected() { public org.jclouds.joyent.cloudapi.v6_5.domain.Package expected() {
return org.jclouds.joyent.cloudapi.v6_5.domain.Package.builder().name("Small 1GB").memorySizeMb(1024) return org.jclouds.joyent.cloudapi.v6_5.domain.Package.builder()
.diskSizeGb(30720).swapSizeMb(2048).isDefault(true).build(); .name("Small 1GB")
.memorySizeMb(1024)
.diskSizeGb(30720)
.swapSizeMb(2048)
.isDefault(true).build();
} }
protected Injector injector() { protected Injector injector() {
return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { return Guice.createInjector(new GsonModule() {
@Override @Override
protected void configure() { protected void configure() {

View File

@ -1 +1,34 @@
[{"id":"e4cd7b9e-4330-11e1-81cf-3bb50a972bda","urn":"sdc:sdc:centos-6:1.0.1","name":"centos-6","os":"linux","type":"virtualmachine","description":"Centos 6 VM 1.0.1","default":false,"requirements":{},"version":"1.0.1","created":"2012-02-13T06:30:33+00:00"},{"id":"e62c30b4-cdda-11e0-9dd4-af4d032032e3","urn":"sdc:sdc:nodejs:1.2.3","name":"nodejs","os":"smartos","type":"smartmachine","description":"Node.js git-deploy PaaS dataset","default":false,"requirements":{},"version":"1.2.3","created":"2011-09-15T08:15:29+00:00"}] [{
"id": "71101322-43a5-11e1-8f01-cf2a3031a7f4",
"urn": "sdc:sdc:ubuntu-10.04:1.0.1",
"name": "ubuntu-10.04",
"os": "linux",
"type": "virtualmachine",
"description": "Ubuntu 10.04 VM 1.0.1",
"default": false,
"requirements": {},
"version": "1.0.1",
"created": "2012-02-22T18:27:32+00:00"
}, {
"id": "e4cd7b9e-4330-11e1-81cf-3bb50a972bda",
"urn": "sdc:sdc:centos-6:1.0.1",
"name": "centos-6",
"os": "linux",
"type": "virtualmachine",
"description": "Centos 6 VM 1.0.1",
"default": false,
"requirements": {},
"version": "1.0.1",
"created": "2012-02-15T20:04:18+00:00"
}, {
"id": "9551fdbc-cc9a-11e1-a9e7-eb1e788a8690",
"urn": "sdc:sdc:standard64:1.0.1",
"name": "standard64",
"os": "smartos",
"type": "smartmachine",
"description": "64-bit machine image optimized for web development",
"default": false,
"requirements": {},
"version": "1.0.1",
"created": "2012-07-13T03:30:22+00:00"
}]