From 01918a02ecf01e3c727ddf6e8053faf89262ccfb Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 24 Jul 2012 23:01:08 -0700 Subject: [PATCH] cleaned up joyent and fixed ssh auth related issues --- .../cloudapi/v6_5/JoyentCloudApiMetadata.java | 4 + .../v6_5/binders/BindKeyToJsonPayload.java | 54 --- .../compute/JoyentCloudComputeService.java | 2 +- ...oyentCloudComputeServiceContextModule.java | 14 +- .../functions/DatasetInDatacenterToImage.java | 5 +- .../MachineInDatacenterToNodeMetadata.java | 6 +- .../v6_5/compute/loaders/CreateUniqueKey.java | 18 +- .../options/JoyentCloudTemplateOptions.java | 15 +- ...sWithGroupEncodedIntoNameThenAddToSet.java | 11 +- .../config/JoyentCloudRestClientModule.java | 1 - .../joyent/cloudapi/v6_5/domain/Dataset.java | 326 ++++++++++++++---- .../joyent/cloudapi/v6_5/domain/Key.java | 68 +++- .../joyent/cloudapi/v6_5/domain/Machine.java | 215 +++++++++--- .../joyent/cloudapi/v6_5/domain/Package.java | 90 +++-- .../joyent/cloudapi/v6_5/domain/Type.java | 26 -- .../datacenterscoped/DatasetInDatacenter.java | 2 +- .../cloudapi/v6_5/features/DatacenterApi.java | 2 +- .../v6_5/features/DatacenterAsyncApi.java | 2 +- .../cloudapi/v6_5/features/DatasetApi.java | 2 +- .../v6_5/features/DatasetAsyncApi.java | 2 +- .../joyent/cloudapi/v6_5/features/KeyApi.java | 2 +- .../cloudapi/v6_5/features/KeyAsyncApi.java | 8 +- .../cloudapi/v6_5/features/MachineApi.java | 2 +- .../v6_5/features/MachineAsyncApi.java | 114 +++--- .../cloudapi/v6_5/features/PackageApi.java | 2 +- .../v6_5/features/PackageAsyncApi.java | 2 +- .../internal/JoyentCloudTypeAdapters.java | 59 ---- .../ZoneIdToURIFromDatacentersApi.java | 29 +- .../JoyentCloudComputeServiceExpectTest.java | 141 ++++++++ .../JoyentCloudComputeServiceLiveTest.java | 1 - .../DatasetInDatacenterToImageTest.java | 8 +- ...tCloudComputeServiceContextExpectTest.java | 57 +++ ...eJoyentCloudComputeServiceExpectTest.java} | 28 +- .../compute/loaders/CreateUniqueKeyTest.java | 56 +-- .../JoyentCloudTemplateOptionsTest.java | 6 +- .../v6_5/features/DatasetApiExpectTest.java | 30 +- .../v6_5/features/KeyApiExpectTest.java | 15 +- .../v6_5/features/MachineApiExpectTest.java | 7 +- .../v6_5/features/MachineApiLiveTest.java | 2 +- .../v6_5/features/PackageApiExpectTest.java | 17 +- .../BaseJoyentCloudApiExpectTest.java | 12 +- .../internal/BaseJoyentCloudExpectTest.java | 13 +- .../v6_5/parse/ParseCreatedMachineTest.java | 5 +- .../v6_5/parse/ParseDatasetListTest.java | 49 ++- .../cloudapi/v6_5/parse/ParseDatasetTest.java | 18 +- .../cloudapi/v6_5/parse/ParseKeyListTest.java | 3 +- .../cloudapi/v6_5/parse/ParseKeyTest.java | 3 +- .../v6_5/parse/ParseMachineListTest.java | 26 +- .../cloudapi/v6_5/parse/ParseMachineTest.java | 5 +- .../v6_5/parse/ParsePackageListTest.java | 3 +- .../cloudapi/v6_5/parse/ParsePackageTest.java | 11 +- .../src/test/resources/dataset_list.json | 35 +- 52 files changed, 1059 insertions(+), 575 deletions(-) delete mode 100644 labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/binders/BindKeyToJsonPayload.java delete mode 100644 labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Type.java delete mode 100644 labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/functions/internal/JoyentCloudTypeAdapters.java create mode 100644 labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceExpectTest.java create mode 100644 labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceContextExpectTest.java rename labs/joyent-cloudapi/src/{main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudParserModule.java => test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceExpectTest.java} (52%) diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/JoyentCloudApiMetadata.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/JoyentCloudApiMetadata.java index 539e4b373a..67a05dff80 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/JoyentCloudApiMetadata.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/JoyentCloudApiMetadata.java @@ -63,6 +63,10 @@ public class JoyentCloudApiMetadata extends BaseRestApiMetadata { public static Properties 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"); return properties; } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/binders/BindKeyToJsonPayload.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/binders/BindKeyToJsonPayload.java deleted file mode 100644 index 9a4b3d96f9..0000000000 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/binders/BindKeyToJsonPayload.java +++ /dev/null @@ -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 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 bindToRequest(R request, Map postParams) { - throw new IllegalStateException("This should be assigned only a single arg"); - } - -} diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java index 07d7a47314..d2979dba9f 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeService.java @@ -94,7 +94,7 @@ public class JoyentCloudComputeService extends BaseComputeService { CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy, DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy, SuspendNodeStrategy stopNodeStrategy, Provider templateBuilderProvider, - Provider templateOptionsProvider, + @Named("DEFAULT") Provider templateOptionsProvider, @Named(TIMEOUT_NODE_RUNNING) Predicate> nodeRunning, @Named(TIMEOUT_NODE_TERMINATED) Predicate> nodeTerminated, @Named(TIMEOUT_NODE_SUSPENDED) Predicate> nodeSuspended, diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/config/JoyentCloudComputeServiceContextModule.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/config/JoyentCloudComputeServiceContextModule.java index 62d8963df4..9017a235cd 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/config/JoyentCloudComputeServiceContextModule.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/config/JoyentCloudComputeServiceContextModule.java @@ -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 java.security.SecureRandom; import java.util.Map; import java.util.Set; @@ -119,9 +118,9 @@ public class JoyentCloudComputeServiceContextModule extends @Override protected TemplateOptions provideTemplateOptions(Injector injector, TemplateOptions options) { - return options.as(JoyentCloudTemplateOptions.class) - .generateKey(injector.getInstance( - com.google.inject.Key.get(boolean.class, Names.named(AUTOGENERATE_KEYS)))); + boolean generateKey = injector.getInstance(com.google.inject.Key.get(boolean.class, + Names.named(AUTOGENERATE_KEYS))); + return options.as(JoyentCloudTemplateOptions.class).generateKey(generateKey); } @Provides @@ -130,6 +129,7 @@ public class JoyentCloudComputeServiceContextModule extends CacheLoader in) { return CacheBuilder.newBuilder().build(in); } + @Provides @Singleton protected Supplier> createLocationIndexedById( @@ -150,12 +150,6 @@ public class JoyentCloudComputeServiceContextModule extends }, locations); } - - @Provides - @Singleton - protected SecureRandom provideSecureRandom() { - return new SecureRandom(); - } @VisibleForTesting public static final Map toPortableNodeStatus = ImmutableMap diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImage.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImage.java index 3ffd15585c..0b63d01df8 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImage.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImage.java @@ -59,10 +59,11 @@ public class DatasetInDatacenterToImage implements Function() { @@ -109,7 +109,7 @@ public class MachineInDatacenterToNodeMetadata implements Function secureRandom; + protected final SshKeyPairGenerator sshKeyPairGenerator; @Inject - public CreateUniqueKey(JoyentCloudApi cloudApiApi, GroupNamingConvention.Factory namingConvention, Crypto crypto, Provider secureRandom) { + public CreateUniqueKey(JoyentCloudApi cloudApiApi, GroupNamingConvention.Factory namingConvention, + SshKeyPairGenerator sshKeyPairGenerator) { this.cloudApiApi = checkNotNull(cloudApiApi, "cloudApiApi"); this.namingConvention = checkNotNull(namingConvention, "namingConvention"); - this.crypto = checkNotNull(crypto, "crypto"); - this.secureRandom = checkNotNull(secureRandom, "secureRandom"); + this.sshKeyPairGenerator = checkNotNull(sshKeyPairGenerator, "sshKeyPairGenerator"); } @Override public KeyAndPrivateKey load(DatacenterAndName datacenterAndName) { String datacenterId = checkNotNull(datacenterAndName, "datacenterAndName").getDatacenter(); String prefix = datacenterAndName.getName(); - - Map keyPair = SshKeys.generate(crypto.rsaKeyPairGenerator(), secureRandom.get()); + + Map keyPair = sshKeyPairGenerator.get(); String publicKey = keyPair.get("public"); String privateKey = keyPair.get("private"); diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptions.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptions.java index 68b13500a1..1e296135c6 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptions.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptions.java @@ -28,6 +28,7 @@ import org.jclouds.scriptbuilder.domain.Statement; import com.google.common.base.Objects; import com.google.common.base.Objects.ToStringHelper; +import com.google.common.base.Optional; /** * 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 */ public class JoyentCloudTemplateOptions extends TemplateOptions implements Cloneable { + @Override public JoyentCloudTemplateOptions clone() { JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions(); @@ -60,11 +62,11 @@ public class JoyentCloudTemplateOptions extends TemplateOptions implements Clone super.copyTo(to); if (to instanceof JoyentCloudTemplateOptions) { JoyentCloudTemplateOptions eTo = JoyentCloudTemplateOptions.class.cast(to); - eTo.generateKey(shouldGenerateKey()); + eTo.generateKey = generateKey; } } - protected boolean generateKey = false; + protected Optional generateKey = Optional.absent(); @Override public boolean equals(Object o) { @@ -83,17 +85,14 @@ public class JoyentCloudTemplateOptions extends TemplateOptions implements Clone @Override public ToStringHelper string() { - ToStringHelper toString = super.string(); - if (generateKey) - toString.add("generateKey", generateKey); - return toString; + return super.string().add("generateKey", generateKey.orNull()); } /** * @see #shouldGenerateKey() */ public JoyentCloudTemplateOptions generateKey(boolean enable) { - this.generateKey = enable; + this.generateKey = Optional.of(enable); return this; } @@ -101,7 +100,7 @@ public class JoyentCloudTemplateOptions extends TemplateOptions implements Clone * * @return true if auto generation of keys is enabled */ - public boolean shouldGenerateKey() { + public Optional shouldGenerateKey() { return generateKey; } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java index 28c3e716c7..e154b941e9 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/compute/strategy/ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.java @@ -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.checkNotNull; +import static org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudProperties.AUTOGENERATE_KEYS; import java.util.Map; import java.util.Set; @@ -55,6 +56,7 @@ public class ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameT CreateNodesWithGroupEncodedIntoNameThenAddToSet { private final LoadingCache keyCache; + private final boolean defaultToAutogenerateKeys; @Inject protected ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet( @@ -63,10 +65,12 @@ public class ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameT GroupNamingConvention.Factory namingConvention, CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, - LoadingCache keyCache) { + LoadingCache keyCache, + @Named(AUTOGENERATE_KEYS) boolean defaultToAutogenerateKeys) { super(addNodeWithTagStrategy, listNodesStrategy, namingConvention, executor, customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory); this.keyCache = checkNotNull(keyCache, "keyCache"); + this.defaultToAutogenerateKeys = defaultToAutogenerateKeys; } @Override @@ -80,8 +84,11 @@ public class ApplyJoyentCloudTemplateOptionsCreateNodesWithGroupEncodedIntoNameT assert template.getOptions().equals(templateOptions) : "options didn't clone properly"; 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() .sharedNameForGroup(group))); // in order to delete the key later diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudRestClientModule.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudRestClientModule.java index 7fd1ea84e2..33fbf47a43 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudRestClientModule.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudRestClientModule.java @@ -65,7 +65,6 @@ public class JoyentCloudRestClientModule extends RestClientModule + * @see docs */ public class Dataset implements Comparable { public static Builder builder() { return new Builder(); } + + public Builder toBuilder() { + return new Builder().fromDataset(this); + } public static class Builder { private String id; - private String name; - private Type type; - private String version; private String urn; + private String name; + private String os; + private Type type; + private String description; private boolean isDefault; + private ImmutableMap.Builder requirements = ImmutableMap.builder(); + private String version; private Date created; + /** + * @see Dataset#getId() + */ public Builder id(String id) { this.id = id; return this; } - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder type(Type type) { - this.type = type; - return this; - } - - public Builder version(String version) { - this.version = version; - return this; - } - + /** + * @see Dataset#getUrn() + */ public Builder urn(String urn) { this.urn = urn; 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) { this.isDefault = isDefault; return this; } + + /** + * @see Dataset#getRequirements() + */ + public Builder requirements(Map requirements) { + this.requirements = ImmutableMap. 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) { this.created = created; return this; } - + 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) { - return id(in.getId()).name(in.getName()).type(in.getType()).version(in.getVersion()).urn(in.getUrn()) - .isDefault(in.isDefault()).created(in.getCreated()); + return id(in.getId()).urn(in.getUrn()).name(in.getName()).os(in.getOs()).type(in.getType()).description(in.getDescription()) + .isDefault(in.isDefault()).requirements(in.requirements).version(in.getVersion()).created(in.getCreated()); } } - // The globally unique id for this dataset - protected final String id; - // The "friendly" name for this dataset - protected final String name; - // Whether this is a smartmachine or virtualmachine - protected final Type type; - // The version for this dataset - protected final String version; - // The full URN for this dataset - protected final String urn; - // Whether this is the default dataset in this datacenter - @SerializedName("default") - protected final boolean isDefault; - // Date (ISO8601) When this dataset was created - protected final Date created; - - public Dataset(String id, String name, Type type, String version, String urn, boolean isDefault, Date created) { - super(); - this.id = id; - this.name = name; - this.type = type; - this.version = version; - this.urn = urn; + private final String id; + private final String name; + private final String os; + private final String urn; + private final Type type; + private final String description; + @Named("default") + private final boolean isDefault; + private final Map requirements; + private final String version; + private final Date created; + + @ConstructorProperties({ "id", "urn", "name", "os", "type", "description", "default", "requirements", "version", + "created" }) + public Dataset(String id, String urn, String name, String os, Type type, String description, boolean isDefault, + Map requirements, String version, Date created) { + this.id = checkNotNull(id, "id"); + this.urn = checkNotNull(urn, "urn of dataset(%s)", id); + this.name = checkNotNull(name, "name of dataset(%s)", id); + this.os = checkNotNull(os, "os of dataset(%s)", id); + this.type = checkNotNull(type, "type of dataset(%s)", id); + this.description = checkNotNull(description, "description of dataset(%s)", id); 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() { return id; } + /** + * The full URN for this dataset + */ + public String getUrn() { + return urn; + } + + /** + * The friendly name for this dataset + */ public String getName() { 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() { 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() { 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 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. + * + *

Note

+ * + * requirements can contain arbitrarily complex values. If the value has structure, you should + * use {@link #getRequirementsAsJsonLiterals} + */ + public Map 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() { return created; } - @Override - public int compareTo(Dataset other) { - return id.compareTo(other.getId()); - } + @VisibleForTesting + static final Function unquoteString = new Function() { + + @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 public boolean equals(Object object) { if (this == object) { return true; } - if (object instanceof Machine) { - return Objects.equal(id, ((Machine) object).id); + if (object instanceof Dataset) { + Dataset that = Dataset.class.cast(object); + return Objects.equal(id, that.id); } else { return false; } } - + @Override public int hashCode() { return Objects.hashCode(id); } - + @Override public String toString() { - return String.format("[id=%s, name=%s, type=%s, version=%s, urn=%s, default=%s, created=%s]", id, name, - type.name(), type.name(), version, urn, isDefault, created); + return Objects.toStringHelper("").omitNullValues() + .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(); + } + } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Key.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Key.java index 2b84bbb96d..334b616a2b 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Key.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Key.java @@ -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; import static com.google.common.base.Preconditions.checkNotNull; +import java.beans.ConstructorProperties; import java.util.Date; 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 * CloudAPI supports uploads of public keys in the OpenSSH format. * * @author Adrian Cole - * @see docs + * @see docs */ public class Key implements Comparable { @@ -26,18 +46,27 @@ public class Key implements Comparable { public static class Builder { private String name; private String key; - private Date created; + private Date created = new Date(); + /** + * @see Key#getName() + */ public Builder name(String name) { this.name = name; return this; } + /** + * @see Key#get() + */ public Builder key(String key) { this.key = key; return this; } + /** + * @see Key#getCreated() + */ public Builder created(Date created) { this.created = created; return this; @@ -54,12 +83,14 @@ public class Key implements Comparable { protected final String name; 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) { this.name = checkNotNull(name, "name"); - this.key = checkNotNull(key, "key: OpenSSH formatted public key"); - this.created = created; + this.key = checkNotNull(key, "key: OpenSSH formatted public key of key(%s)", name); + this.created = checkNotNull(created, "created date of key(%s)", name); } /** @@ -75,23 +106,22 @@ public class Key implements Comparable { public String get() { return key; } - + + /** + * Date the key was created + */ public Date getCreated() { return created; } - @Override - public int compareTo(Key other) { - return name.compareTo(other.getName()); - } - @Override public boolean equals(Object object) { if (this == object) { return true; } if (object instanceof Key) { - return Objects.equal(name, ((Key) object).name); + Key that = Key.class.cast(object); + return Objects.equal(name, that.name); } else { return false; } @@ -104,6 +134,16 @@ public class Key implements Comparable { @Override 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(); } } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Machine.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Machine.java index 6a5caad5ea..7ee0f474a8 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Machine.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Machine.java @@ -20,10 +20,13 @@ package org.jclouds.joyent.cloudapi.v6_5.domain; import static com.google.common.base.Preconditions.checkNotNull; +import java.beans.ConstructorProperties; import java.util.Date; import java.util.Map; import java.util.Set; +import javax.inject.Named; + import org.jclouds.domain.JsonBall; import org.jclouds.joyent.cloudapi.v6_5.reference.Metadata; 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.Functions; import com.google.common.base.Objects; +import com.google.common.collect.ComparisonChain; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; 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 - * @see + * @see */ public class Machine implements Comparable { + + 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 { PROVISIONING, RUNNING, STOPPING, STOPPED, OFFLINE, DELETED, UNRECOGNIZED; @@ -83,56 +107,95 @@ public class Machine implements Comparable { private String dataset; private int memorySizeMb; private int diskSizeGb; - private Set ips; + private ImmutableSet.Builder ips = ImmutableSet. builder(); private Date created; private Date updated; - private Map metadata = ImmutableMap.of(); - + private ImmutableMap.Builder metadata = ImmutableMap.builder(); + + /** + * @see Machine#getId() + */ public Builder id(String id) { this.id = id; return this; } - + + /** + * @see Machine#getName() + */ public Builder name(String name) { this.name = name; return this; } - + + /** + * @see Machine#getType() + */ public Builder type(Type type) { this.type = type; return this; } - + + /** + * @see Machine#getState() + */ public Builder state(State state) { this.state = state; return this; } - + + /** + * @see Machine#getDatasetURN() + */ public Builder dataset(String dataset) { this.dataset = dataset; return this; } - + + /** + * @see Machine#getMemorySizeMb() + */ public Builder memorySizeMb(int memorySizeMb) { this.memorySizeMb = memorySizeMb; return this; } - + + /** + * @see Machine#getDiskSizeGb() + */ public Builder diskSizeGb(int diskSizeGb) { this.diskSizeGb = diskSizeGb; return this; } + /** + * @see Machine#getIps() + */ public Builder ips(Set ips) { - this.ips = ips; + this.ips = ImmutableSet. builder(); + this.ips.addAll(checkNotNull(ips, "ips")); 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) { this.created = created; return this; } - + + /** + * @see Machine#getUpdated() + */ public Builder updated(Date updated) { this.updated = updated; return this; @@ -142,110 +205,137 @@ public class Machine implements Comparable { * @see Machine#getMetadata() */ public Builder metadata(Map metadata) { - this.metadata = metadata; + this.metadata = ImmutableMap. 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; } 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) { - 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()) .metadata(in.metadata).created(in.getCreated()).updated(in.getUpdated()); } } - // The globally unique id for this machine protected final String id; - // The "friendly" name for this machine protected final String name; - // Whether this is a smartmachine or virtualmachine protected final Type type; - // The current state of this machine protected final State state; - // The dataset urn this machine was provisioned with protected final String dataset; - // The amount of memory this machine has (Mb) - @SerializedName("memory") + @Named("memory") protected final int memorySizeMb; - // The amount of disk this machine has (Gb) - @SerializedName("disk") + @Named("disk") protected final int diskSizeGb; - // The IP addresses this machine has protected final Set ips; - // Date (ISO8601) When this machine was created protected final Date created; - // Date (ISO8601) When this machine was updated protected final Date updated; // metadata Object[String => String] Any "extra" metadata this machine has private final Map metadata; - @Override - public int compareTo(Machine other) { - return id.compareTo(other.getId()); - } - + @ConstructorProperties({ "id", "name", "type", "state", "dataset", "memory", "disk", "ips", "created", "updated", "metadata" }) public Machine(String id, String name, Type type, State state, String dataset, int memorySizeMb, int diskSizeGb, Set ips, Date created, Date updated, final Map metadata) { - super(); - this.id = id; - this.name = name; - this.type = type; - this.state = state; - this.dataset = dataset; + this.id = checkNotNull(id, "id"); + this.name = checkNotNull(name, "name of machine(%s)", id); + this.type = checkNotNull(type, "type of machine(%s)", id); + this.state = checkNotNull(state, "state of machine(%s)", id); + this.dataset = checkNotNull(dataset, "dataset of machine(%s)", id); this.memorySizeMb = memorySizeMb; this.diskSizeGb = diskSizeGb; - this.ips = ImmutableSet. copyOf(ips); - this.created = created; - this.updated = updated; - this.metadata = metadata; + this.ips = ImmutableSet. copyOf(checkNotNull(ips, "ips of machine(%s)", id)); + this.created = checkNotNull(created, "created date of machine(%s)", id); + this.updated = checkNotNull(created, "updated date of machine(%s)", id); + this.metadata = ImmutableMap. copyOf(checkNotNull(metadata, "metadata of machine(%s)", id)); } + /** + * The globally unique id for this machine + */ public String getId() { return id; } + /** + * The "friendly" name for this machine + */ public String getName() { return name; } + /** + * Whether this is a smartmachine or virtualmachine + */ public Type getType() { return type; } + /** + * The current state of this machine + */ public State getState() { return state; } - public String get() { + /** + * The dataset urn this machine was provisioned with + */ + public String getDatasetURN() { return dataset; } + /** + * The amount of memory this machine has (Mb) + */ public int getMemorySizeMb() { return memorySizeMb; } + /** + * The amount of disk this machine has (Gb) + */ public int getDiskSizeGb() { return diskSizeGb; } + /** + * The IP addresses this machine has + */ public Set getIps() { return ips; } + /** + * When this machine was created + */ public Date getCreated() { return created; } + /** + * When this machine was updated + */ public Date getUpdated() { return updated; } /** - * If the value is a string, it will be quoted, as that's how json strings are represented. + * + *

note

+ * + * 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 Metadata#valueType @@ -256,9 +346,13 @@ public class Machine implements Comparable { } /** - * Note!! metadata can contain arbitrarily complex values. If the value has structure, you should use {@link #getMetadataAsJsonLiterals} + * Any "extra" metadata this machine has + * + *

note

+ * + * metadata can contain arbitrarily complex values. If the value has structure, you should use + * {@link #getMetadataAsJsonLiterals} * - * @return metadata */ public Map getMetadata() { return Maps.transformValues(metadata, Functions.compose(Functions.toStringFunction(), unquoteString)); @@ -276,14 +370,15 @@ public class Machine implements Comparable { } }; - + @Override public boolean equals(Object object) { if (this == object) { return true; } if (object instanceof Machine) { - return Objects.equal(id, ((Machine) object).id); + Machine that = Machine.class.cast(object); + return Objects.equal(id, that.id); } else { return false; } @@ -296,7 +391,23 @@ public class Machine implements Comparable { @Override public String toString() { - return String.format("[id=%s, name=%s, type=%s, state=%s, memory=%s, disk=%s, ips=%s, created=%s, updated=%s]", - id, name, type.name(), state.name(), memorySizeMb, diskSizeGb, ips, created, updated); + return Objects.toStringHelper("").omitNullValues() + .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(); } } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Package.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Package.java index 815abbf7ec..745cc23b04 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Package.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Package.java @@ -18,20 +18,32 @@ */ 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.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 - * @see
+ * @see docs */ public class Package implements Comparable { public static Builder builder() { return new Builder(); } + + public Builder toBuilder() { + return new Builder().fromPackage(this); + } public static class Builder { private String name; @@ -40,26 +52,41 @@ public class Package implements Comparable { private int swapSizeMb; private boolean isDefault; + /** + * @see Package#getName() + */ public Builder name(String name) { this.name = name; return this; } + /** + * @see Package#getMemorySizeMb() + */ public Builder memorySizeMb(int memorySizeMb) { this.memorySizeMb = memorySizeMb; return this; } + /** + * @see Package#getDiskSizeGb() + */ public Builder diskSizeGb(int diskSizeGb) { this.diskSizeGb = diskSizeGb; return this; } + /** + * @see Package#getSwapSizeMb() + */ public Builder swapSizeMb(int swapSizeMb) { this.swapSizeMb = swapSizeMb; return this; } + /** + * @see Package#isDefault() + */ public Builder isDefault(boolean isDefault) { this.isDefault = isDefault; return this; @@ -75,51 +102,56 @@ public class Package implements Comparable { } } - // The "friendly" name for this machine protected final String name; - // The amount of memory this package has (Mb) - @SerializedName("memory") + @Named("memory") protected final int memorySizeMb; - // The amount of disk this package has (Gb) - @SerializedName("disk") + @Named("disk") protected final int diskSizeGb; - // The amount of swap this package has (Gb) - @SerializedName("swap") + @Named("swap") protected final int swapSizeMb; - // Whether this is the default package in this datacenter - @SerializedName("default") + @Named("default") protected final boolean isDefault; - @Override - public int compareTo(Package other) { - return name.compareTo(other.getName()); - } - + @ConstructorProperties({ "name", "memory", "disk", "swap", "default" }) public Package(String name, int memorySizeMb, int diskSizeGb, int swapSizeMb, boolean isDefault) { - super(); - this.name = name; + this.name = checkNotNull(name, "name"); this.memorySizeMb = memorySizeMb; this.diskSizeGb = diskSizeGb; this.swapSizeMb = swapSizeMb; this.isDefault = isDefault; } + /** + * The "friendly name for this package + */ public String getName() { return name; } + /** + * How much memory will by available (in Mb) + */ public int getMemorySizeMb() { return memorySizeMb; } + /** + * How much disk space will be available (in Gb) + */ public int getDiskSizeGb() { return diskSizeGb; } + /** + * How much swap memory will be available (in Mb) + */ public int getSwapSizeMb() { return swapSizeMb; } + /** + * Whether this is the default package in this datacenter + */ public boolean isDefault() { return isDefault; } @@ -130,7 +162,8 @@ public class Package implements Comparable { return true; } if (object instanceof Package) { - return Objects.equal(name, ((Package) object).name); + Package that = Package.class.cast(object); + return Objects.equal(name, that.name); } else { return false; } @@ -143,7 +176,20 @@ public class Package implements Comparable { @Override public String toString() { - return String.format("[name=%s, memory=%s, disk=%s, swap=%s, default=%s]", name, memorySizeMb, diskSizeGb, - swapSizeMb, isDefault); + return Objects.toStringHelper("").omitNullValues() + .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(); } } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Type.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Type.java deleted file mode 100644 index 36e070dae4..0000000000 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/Type.java +++ /dev/null @@ -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(); - } -} diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/datacenterscoped/DatasetInDatacenter.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/datacenterscoped/DatasetInDatacenter.java index cd0f88c9f5..d164787ced 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/datacenterscoped/DatasetInDatacenter.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/domain/datacenterscoped/DatasetInDatacenter.java @@ -29,7 +29,7 @@ public class DatasetInDatacenter extends DatacenterAndId { protected final Dataset dataset; public DatasetInDatacenter(Dataset dataset, String datacenterId) { - super(datacenterId, checkNotNull(dataset, "dataset").getId()); + super(datacenterId, checkNotNull(dataset, "dataset").getUrn()); this.dataset = dataset; } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterApi.java index 9951dfb8f3..2453c21a8a 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterApi.java @@ -29,7 +29,7 @@ import org.jclouds.concurrent.Timeout; * * @see DatacenterAsyncApi * @author Adrian Cole - * @see api doc + * @see api doc */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface DatacenterApi { diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterAsyncApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterAsyncApi.java index 32c123057a..a22d5a0c85 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterAsyncApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatacenterAsyncApi.java @@ -40,7 +40,7 @@ import com.google.common.util.concurrent.ListenableFuture; * * @see DatacenterApi * @author Adrian Cole - * @see api doc + * @see api doc */ @SkipEncoding({ '/', '=' }) @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApi.java index 8626aba9aa..01494bfffc 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApi.java @@ -12,7 +12,7 @@ import org.jclouds.joyent.cloudapi.v6_5.domain.Dataset; * * @author Gerald Pereira * @see DatasetAsyncApi - * @see api doc + * @see api doc */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface DatasetApi { diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetAsyncApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetAsyncApi.java index 0f38852988..d0b4985649 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetAsyncApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetAsyncApi.java @@ -25,7 +25,7 @@ import com.google.common.util.concurrent.ListenableFuture; * * @author Gerald Pereira * @see DatasetApi - * @see api doc + * @see api doc */ @SkipEncoding({ '/', '=' }) @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApi.java index ea145e6397..26e5e93bec 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApi.java @@ -12,7 +12,7 @@ import org.jclouds.joyent.cloudapi.v6_5.domain.Key; * * @author Adrian Cole * @see KeyAsyncApi - * @see api doc + * @see api doc */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface KeyApi { diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyAsyncApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyAsyncApi.java index cda5500ad9..fb7789eab3 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyAsyncApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyAsyncApi.java @@ -11,22 +11,23 @@ import javax.ws.rs.PathParam; import javax.ws.rs.core.MediaType; 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.rest.annotations.BinderParam; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.Headers; import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.SkipEncoding; +import org.jclouds.rest.binders.BindToJsonPayload; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import com.google.common.util.concurrent.ListenableFuture; /** * @author Adrian Cole * @see KeyApi - * @see api doc + * @see api doc */ @SkipEncoding({ '/', '=' }) @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") @@ -56,7 +57,7 @@ public interface KeyAsyncApi { @POST @Path("/my/keys") @Consumes(MediaType.APPLICATION_JSON) - ListenableFuture create(@BinderParam(BindKeyToJsonPayload.class) Key key); + ListenableFuture create(@BinderParam(BindToJsonPayload.class) Key key); /** * @see KeyApi#delete @@ -64,6 +65,7 @@ public interface KeyAsyncApi { @DELETE @Consumes(MediaType.APPLICATION_JSON) @Path("/my/keys/{name}") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) ListenableFuture delete(@PathParam("name") String name); } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApi.java index 7ccb99a417..5a05e7608b 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApi.java @@ -31,7 +31,7 @@ import org.jclouds.joyent.cloudapi.v6_5.options.CreateMachineOptions; * * @author Gerald Pereira * @see MachineAsyncApi - * @see api doc + * @see api doc */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface MachineApi { diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineAsyncApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineAsyncApi.java index 6fc95c8214..1776941c50 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineAsyncApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineAsyncApi.java @@ -41,6 +41,7 @@ import org.jclouds.rest.annotations.RequestFilters; import org.jclouds.rest.annotations.SkipEncoding; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; +import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404; import com.google.common.util.concurrent.ListenableFuture; @@ -50,7 +51,7 @@ import com.google.common.util.concurrent.ListenableFuture; * * @author Gerald Pereira * @see MachineApi - * @see api doc + * @see api doc */ @SkipEncoding({ '/', '=' }) @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") @@ -74,7 +75,7 @@ public interface MachineAsyncApi { @Consumes(MediaType.APPLICATION_JSON) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture get(@PathParam("id") String id); - + /** * @see MachineApi#createWithDataset(String) */ @@ -82,63 +83,62 @@ public interface MachineAsyncApi { @Path("/my/machines") @Consumes(MediaType.APPLICATION_JSON) ListenableFuture createWithDataset(@QueryParam("dataset") String datasetURN); - - /** - * @see MachineApi#createWithDataset(String, CreateMachineOptions) - */ - @POST + + /** + * @see MachineApi#createWithDataset(String, CreateMachineOptions) + */ + @POST @Path("/my/machines") @Consumes(MediaType.APPLICATION_JSON) ListenableFuture createWithDataset(@QueryParam("dataset") String datasetURN, CreateMachineOptions options); - /** - * @see MachineApi#stop - */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_FORM_URLENCODED) - @Path("/my/machines/{id}") - @Payload("action=stop") - ListenableFuture stop(@PathParam("id") String id); - - /** - * @see MachineApi#start - */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_FORM_URLENCODED) - @Path("/my/machines/{id}") - @Payload("action=start") - ListenableFuture start(@PathParam("id") String id); - - /** - * @see MachineApi#reboot - */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_FORM_URLENCODED) - @Path("/my/machines/{id}") - @Payload("action=reboot") - ListenableFuture reboot(@PathParam("id") String id); - - /** - * @see MachineApi#resize - */ - @POST - @Consumes(MediaType.APPLICATION_JSON) - @Produces(MediaType.APPLICATION_FORM_URLENCODED) - @Path("/my/machines/{id}") - @Payload("action=resize&package={package}") - ListenableFuture resize(@PathParam("id") String id,@PayloadParam("package") String packageJoyentCloud); - - /** - * @see MachineApi#delete - */ - @DELETE - @Consumes(MediaType.APPLICATION_JSON) - @Path("/my/machines/{id}") - ListenableFuture delete(@PathParam("id") String id); - - - + /** + * @see MachineApi#stop + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_FORM_URLENCODED) + @Path("/my/machines/{id}") + @Payload("action=stop") + ListenableFuture stop(@PathParam("id") String id); + + /** + * @see MachineApi#start + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_FORM_URLENCODED) + @Path("/my/machines/{id}") + @Payload("action=start") + ListenableFuture start(@PathParam("id") String id); + + /** + * @see MachineApi#reboot + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_FORM_URLENCODED) + @Path("/my/machines/{id}") + @Payload("action=reboot") + ListenableFuture reboot(@PathParam("id") String id); + + /** + * @see MachineApi#resize + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_FORM_URLENCODED) + @Path("/my/machines/{id}") + @Payload("action=resize&package={package}") + ListenableFuture resize(@PathParam("id") String id, @PayloadParam("package") String packageJoyentCloud); + + /** + * @see MachineApi#delete + */ + @DELETE + @Consumes(MediaType.APPLICATION_JSON) + @Path("/my/machines/{id}") + @ExceptionParser(ReturnVoidOnNotFoundOr404.class) + ListenableFuture delete(@PathParam("id") String id); + } diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApi.java index a35875b5d9..098a10d9aa 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApi.java @@ -11,7 +11,7 @@ import org.jclouds.concurrent.Timeout; * * @author Gerald Pereira * @see PackageAsyncApi - * @see api doc + * @see api doc */ @Timeout(duration = 30, timeUnit = TimeUnit.SECONDS) public interface PackageApi { diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageAsyncApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageAsyncApi.java index e2a4d7dd68..45c688a96d 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageAsyncApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageAsyncApi.java @@ -24,7 +24,7 @@ import com.google.common.util.concurrent.ListenableFuture; * * @author Gerald Pereira * @see PackageApi - * @see api doc + * @see api doc */ @SkipEncoding({ '/', '=' }) @Headers(keys = "X-Api-Version", values = "{jclouds.api-version}") diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/functions/internal/JoyentCloudTypeAdapters.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/functions/internal/JoyentCloudTypeAdapters.java deleted file mode 100644 index cb3e67cfa2..0000000000 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/functions/internal/JoyentCloudTypeAdapters.java +++ /dev/null @@ -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 { - @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 { - @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()); - } - } - -} diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/suppliers/ZoneIdToURIFromDatacentersApi.java b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/suppliers/ZoneIdToURIFromDatacentersApi.java index 738a41d70c..f0c215541b 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/suppliers/ZoneIdToURIFromDatacentersApi.java +++ b/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/suppliers/ZoneIdToURIFromDatacentersApi.java @@ -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; +import static com.google.common.collect.Maps.filterKeys; +import static com.google.common.collect.Maps.transformValues; + import java.net.URI; import java.util.Map; @@ -7,25 +28,27 @@ import javax.inject.Inject; import javax.inject.Singleton; 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.util.Suppliers2; import com.google.common.base.Supplier; -import com.google.common.collect.Maps; @Singleton public class ZoneIdToURIFromDatacentersApi implements ZoneIdToURISupplier { private final DatacenterApi api; + private final AnyOrConfiguredZoneId filter; @Inject - public ZoneIdToURIFromDatacentersApi(DatacenterApi api) { + public ZoneIdToURIFromDatacentersApi(DatacenterApi api, AnyOrConfiguredZoneId filter) { this.api = api; + this.filter = filter; } @Override public Map> get() { - return Maps.transformValues(api.getDatacenters(), Suppliers2. ofInstanceFunction()); + return filterKeys(transformValues(api.getDatacenters(), Suppliers2. ofInstanceFunction()), filter); } @Override diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceExpectTest.java new file mode 100644 index 0000000000..65e489f843 --- /dev/null +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceExpectTest.java @@ -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 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 requestResponseMap = ImmutableMap. 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>() { + }).toInstance(new Supplier() { + + @Override + public String get() { + return suffix.getAndIncrement() + ""; + } + + }); + bind(SshKeyPairGenerator.class).toInstance(new SshKeyPairGenerator() { + + @Override + public Map 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")); + } +} diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceLiveTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceLiveTest.java index 7303c6e19c..e866e50d0c 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceLiveTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/JoyentCloudComputeServiceLiveTest.java @@ -21,6 +21,5 @@ public class JoyentCloudComputeServiceLiveTest extends BaseComputeServiceLiveTes protected Module getSshModule() { return new SshjSshClientModule(); } - } diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImageTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImageTest.java index 9c970fa6df..f751b01274 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImageTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/functions/DatasetInDatacenterToImageTest.java @@ -44,7 +44,7 @@ import com.google.common.collect.ImmutableMap; * * @author Adrian Cole */ -@Test(testName = "DatasetInDatacenterToHardwareTest") +@Test(testName = "DatasetInDatacenterToImageTest") public class DatasetInDatacenterToImageTest { 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); - assertEquals(convertedImage.getId(), datasetInZoneToConvert.slashEncode()); - assertEquals(convertedImage.getProviderId(), datasetToConvert.getId()); + assertEquals(convertedImage.getId(), "us-sw-1/" + datasetToConvert.getUrn()); + assertEquals(convertedImage.getProviderId(), datasetToConvert.getUrn()); assertEquals(convertedImage.getLocation(), locationIndex.get().get("us-sw-1")); assertEquals(convertedImage.getName(), datasetToConvert.getName()); assertEquals(convertedImage.getStatus(), org.jclouds.compute.domain.Image.Status.AVAILABLE); assertEquals(convertedImage.getOperatingSystem(), operatingSystem); - assertEquals(convertedImage.getDescription(), datasetToConvert.getUrn()); + assertEquals(convertedImage.getDescription(), datasetToConvert.getDescription()); assertEquals(convertedImage.getVersion(), datasetToConvert.getVersion()); } diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceContextExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceContextExpectTest.java new file mode 100644 index 0000000000..da53581f12 --- /dev/null +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceContextExpectTest.java @@ -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 extends BaseJoyentCloudExpectTest implements + Function { + + + @Override + public T createClient(Function fn, Module module, Properties props) { + return apply(createComputeServiceContext(fn, module, props)); + } + + private ComputeServiceContext createComputeServiceContext(Function fn, Module module, + Properties props) { + return createInjector(fn, module, props).getInstance(ComputeServiceContext.class); + } + + @Override + protected ApiMetadata createApiMetadata() { + return new JoyentCloudApiMetadata(); + } + +} diff --git a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudParserModule.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceExpectTest.java similarity index 52% rename from labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudParserModule.java rename to labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceExpectTest.java index a1d298f8fa..beae2e2077 100644 --- a/labs/joyent-cloudapi/src/main/java/org/jclouds/joyent/cloudapi/v6_5/config/JoyentCloudParserModule.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/internal/BaseJoyentCloudComputeServiceExpectTest.java @@ -16,34 +16,20 @@ * specific language governing permissions and limitations * 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 java.util.Map; - -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; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceContext; /** + * * @author Adrian Cole */ -public class JoyentCloudParserModule extends AbstractModule { - - @Provides - @Singleton - public Map provideCustomAdapterBindings() { - return ImmutableMap. of(Machine.State.class, new JoyentCloudTypeAdapters.MachineStateAdapter(), Type.class, - new JoyentCloudTypeAdapters.JoyentCloudTypeAdapter()); - } +public class BaseJoyentCloudComputeServiceExpectTest extends BaseJoyentCloudComputeServiceContextExpectTest { @Override - protected void configure() { + public ComputeService apply(ComputeServiceContext input) { + return input.getComputeService(); } } diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/loaders/CreateUniqueKeyTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/loaders/CreateUniqueKeyTest.java index 1eb3aa40b6..f110d8116a 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/loaders/CreateUniqueKeyTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/loaders/CreateUniqueKeyTest.java @@ -22,30 +22,18 @@ import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; 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 java.io.IOException; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; 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.util.Map; import org.jclouds.compute.functions.GroupNamingConvention; import org.jclouds.compute.functions.GroupNamingConvention.Factory; -import org.jclouds.crypto.Crypto; -import org.jclouds.crypto.Pems; -import org.jclouds.crypto.SshKeys; -import org.jclouds.io.Payloads; +import org.jclouds.crypto.SshKeyPairGenerator; 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.loaders.CreateUniqueKey; 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.features.KeyApi; @@ -54,21 +42,20 @@ import org.testng.annotations.Test; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; import com.google.inject.AbstractModule; import com.google.inject.Guice; import com.google.inject.TypeLiteral; -import com.google.inject.util.Providers; /** * @author Adrian Cole */ @Test(groups = "unit", testName = "CreateUniqueKeyTest") public class CreateUniqueKeyTest { - private static final String lineSeparator = System.getProperty("line.separator"); + private ImmutableMap keyPair = ImmutableMap.of("public", "ssh-rsa AAAAB3NzaC...", "private", + "-----BEGIN RSA PRIVATE KEY-----\n"); private Factory namingConvention; - private KeyPair keyPair; - private String openSshKey; @BeforeClass public void setup() throws InvalidKeySpecException, NoSuchAlgorithmException, IOException { @@ -80,42 +67,35 @@ public class CreateUniqueKeyTest { }).toInstance(Suppliers.ofInstance("foo")); } }).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 public void testApply() { JoyentCloudApi cloudApiApi = createMock(JoyentCloudApi.class); + SshKeyPairGenerator sshKeyPairGenerator = new SshKeyPairGenerator() { + + @Override + public Map get() { + return keyPair; + } + + }; KeyApi keyApi = createMock(KeyApi.class); - Crypto crypto = createMock(Crypto.class); - 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); + Key key = Key.builder().name("group-foo").key(keyPair.get("public")).build(); expect(cloudApiApi.getKeyApi()).andReturn(keyApi); 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")), - KeyAndPrivateKey.fromKeyAndPrivateKey(key, PRIVATE_KEY.replaceAll("\n", lineSeparator))); + KeyAndPrivateKey.fromKeyAndPrivateKey(key, keyPair.get("private"))); - verify(cloudApiApi, keyApi, crypto, rsaKeyPairGenerator, secureRandom); + verify(cloudApiApi, keyApi); } } diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptionsTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptionsTest.java index b832ae3d89..99522cd71b 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptionsTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/compute/options/JoyentCloudTemplateOptionsTest.java @@ -47,19 +47,19 @@ public class JoyentCloudTemplateOptionsTest { @Test public void testGenerateKeyDefault() { JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions(); - assert !options.shouldGenerateKey(); + assert !options.shouldGenerateKey().isPresent(); } @Test public void testGenerateKey() { JoyentCloudTemplateOptions options = new JoyentCloudTemplateOptions().generateKey(true); - assert options.shouldGenerateKey(); + assert options.shouldGenerateKey().get(); } @Test public void testGenerateKeyStatic() { JoyentCloudTemplateOptions options = generateKey(true); - assert options.shouldGenerateKey(); + assert options.shouldGenerateKey().get(); } // superclass tests diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApiExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApiExpectTest.java index f24ce6e5e9..af5dac9cd7 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApiExpectTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/DatasetApiExpectTest.java @@ -20,8 +20,6 @@ package org.jclouds.joyent.cloudapi.v6_5.features; import static org.testng.Assert.assertEquals; -import java.net.URI; - import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; 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.testng.annotations.Test; -import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; /** @@ -37,14 +34,16 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit", testName = "DatasetApiExpectTest") public class DatasetApiExpectTest extends BaseJoyentCloudApiExpectTest { - HttpRequest list = HttpRequest.builder().method("GET").endpoint( - URI.create("https://us-sw-1.api.joyentcloud.com/my/datasets")).headers( - ImmutableMultimap. builder().put("X-Api-Version", "~6.5").put("Accept", "application/json") - .put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(); - + public HttpRequest list = HttpRequest.builder().method("GET") + .endpoint("https://us-sw-1.api.joyentcloud.com/my/datasets") + .addHeader("X-Api-Version", "~6.5") + .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() { - HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload( - payloadFromResource("/dataset_list.json")).build(); 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()); } - - // [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 } diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApiExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApiExpectTest.java index 034ae716d1..dc37fab7c1 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApiExpectTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/KeyApiExpectTest.java @@ -35,15 +35,16 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit", testName = "KeyApiExpectTest") public class KeyApiExpectTest extends BaseJoyentCloudApiExpectTest { - HttpRequest list = HttpRequest.builder().method("GET") - .endpoint("https://api.joyentcloud.com/my/keys") - .addHeader("X-Api-Version", "~6.5") - .addHeader("Accept", "application/json") - .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); + public HttpRequest list = HttpRequest.builder().method("GET") + .endpoint("https://api.joyentcloud.com/my/keys") + .addHeader("X-Api-Version", "~6.5") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); + + public HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload( + payloadFromResource("/key_list.json")).build(); public void testListKeysWhenResponseIs2xx() { - HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload( - payloadFromResource("/key_list.json")).build(); JoyentCloudApi apiWhenKeysExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse); diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiExpectTest.java index 1a9a7b863d..7032dccf35 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiExpectTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiExpectTest.java @@ -36,15 +36,16 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit", testName = "MachineApiExpectTest") 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") .addHeader("X-Api-Version", "~6.5") .addHeader("Accept", "application/json") .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); + public HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload( + payloadFromResource("/machine_list.json")).build(); + public void testListMachinesWhenResponseIs2xx() { - HttpResponse listResponse = HttpResponse.builder().statusCode(200).payload( - payloadFromResource("/machine_list.json")).build(); JoyentCloudApi apiWhenMachinesExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse); diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiLiveTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiLiveTest.java index 3b9870efbf..ceb441ab28 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiLiveTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/MachineApiLiveTest.java @@ -68,7 +68,7 @@ public class MachineApiLiveTest extends BaseJoyentCloudApiLiveTest { assertEquals(newDetails.getName(), machine.getName()); assertEquals(newDetails.getType(), machine.getType()); assertEquals(newDetails.getState(), machine.getState()); - assertEquals(newDetails.get(), machine.get()); + assertEquals(newDetails.getDatasetURN(), machine.getDatasetURN()); assertEquals(newDetails.getMemorySizeMb(), machine.getMemorySizeMb()); assertEquals(newDetails.getDiskSizeGb(), machine.getDiskSizeGb()); assertEquals(newDetails.getIps(), machine.getIps()); diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApiExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApiExpectTest.java index 5d8fba0b4a..35dc828ab2 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApiExpectTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/features/PackageApiExpectTest.java @@ -34,15 +34,16 @@ import com.google.common.collect.ImmutableSet; */ @Test(groups = "unit", testName = "PackageApiExpectTest") public class PackageApiExpectTest extends BaseJoyentCloudApiExpectTest { - HttpRequest list = HttpRequest.builder().method("GET") - .endpoint("https://us-sw-1.api.joyentcloud.com/my/packages") - .addHeader("X-Api-Version", "~6.5") - .addHeader("Accept", "application/json") - .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); - - public void testListPackagesWhenResponseIs2xx() { - HttpResponse listResponse = HttpResponse.builder().statusCode(200) + public HttpRequest list = HttpRequest.builder().method("GET") + .endpoint("https://us-sw-1.api.joyentcloud.com/my/packages") + .addHeader("X-Api-Version", "~6.5") + .addHeader("Accept", "application/json") + .addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build(); + + public HttpResponse listResponse = HttpResponse.builder().statusCode(200) .payload(payloadFromResource("/package_list.json")).build(); + + public void testListPackagesWhenResponseIs2xx() { JoyentCloudApi apiWhenPackagesExists = requestsSendResponses(getDatacenters, getDatacentersResponse, list, listResponse); diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudApiExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudApiExpectTest.java index fc43a282bc..180560b427 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudApiExpectTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudApiExpectTest.java @@ -18,8 +18,6 @@ */ 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; /** @@ -28,13 +26,5 @@ import org.jclouds.joyent.cloudapi.v6_5.JoyentCloudApi; * @author Adrian Cole */ public class BaseJoyentCloudApiExpectTest extends BaseJoyentCloudExpectTest { - 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(); + } diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudExpectTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudExpectTest.java index 96c90118f9..30aa44153a 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudExpectTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/internal/BaseJoyentCloudExpectTest.java @@ -18,6 +18,8 @@ */ package org.jclouds.joyent.cloudapi.v6_5.internal; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; import org.jclouds.rest.internal.BaseRestApiExpectTest; /** @@ -26,7 +28,16 @@ import org.jclouds.rest.internal.BaseRestApiExpectTest; * @author Adrian Cole */ public class BaseJoyentCloudExpectTest extends BaseRestApiExpectTest { - + 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() { provider = "joyent-cloudapi"; } diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseCreatedMachineTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseCreatedMachineTest.java index d4f9e0d126..b69966f91d 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseCreatedMachineTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseCreatedMachineTest.java @@ -23,9 +23,8 @@ import javax.ws.rs.core.MediaType; import org.jclouds.date.internal.SimpleDateFormatDateService; 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.Type; +import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type; import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.config.GsonModule; import org.testng.annotations.Test; @@ -68,7 +67,7 @@ public class ParseCreatedMachineTest extends BaseItemParserTest { } protected Injector injector() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetListTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetListTest.java index d62373c57f..dc24b6ad6c 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetListTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetListTest.java @@ -24,9 +24,8 @@ import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; 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.Type; +import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type; import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.config.GsonModule; import org.testng.annotations.Test; @@ -50,21 +49,43 @@ public class ParseDatasetListTest extends BaseSetParserTest { @Consumes(MediaType.APPLICATION_JSON) public Set expected() { return ImmutableSet.of( - Dataset.builder().id("e4cd7b9e-4330-11e1-81cf-3bb50a972bda").name("centos-6").urn("sdc:sdc:centos-6:1.0.1") - .type(Type.VIRTUALMACHINE).version("1.0.1").isDefault(false) - .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-13T06:30:33+00:00")) - .build(), - - Dataset.builder().id("e62c30b4-cdda-11e0-9dd4-af4d032032e3").name("nodejs").urn("sdc:sdc:nodejs:1.2.3") - .type(Type.SMARTMACHINE).version("1.2.3").isDefault(false) - .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-09-15T08:15:29+00:00")) - .build() - - ); + Dataset.builder() + .id("71101322-43a5-11e1-8f01-cf2a3031a7f4") + .urn("sdc:sdc:ubuntu-10.04:1.0.1") + .name("ubuntu-10.04") + .os("linux") + .type(Type.VIRTUALMACHINE) + .description("Ubuntu 10.04 VM 1.0.1") + .version("1.0.1") + .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() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetTest.java index 33d7ccdc71..907dc1e4da 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseDatasetTest.java @@ -22,9 +22,8 @@ import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; 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.Type; +import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type; import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.config.GsonModule; import org.testng.annotations.Test; @@ -46,13 +45,20 @@ public class ParseDatasetTest extends BaseItemParserTest { @Override @Consumes(MediaType.APPLICATION_JSON) public Dataset expected() { - return Dataset.builder().id("e4cd7b9e-4330-11e1-81cf-3bb50a972bda").name("centos-6") - .urn("sdc:sdc:centos-6:1.0.1").type(Type.VIRTUALMACHINE).version("1.0.1").isDefault(false) - .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-13T06:30:33+00:00")).build(); + return 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") + .isDefault(false) + .version("1.0.1") + .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-02-13T06:30:33+00:00")).build(); } protected Injector injector() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyListTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyListTest.java index 7f2cbc2dbd..3cb6c8f844 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyListTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyListTest.java @@ -24,7 +24,6 @@ import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; 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.json.BaseSetParserTest; import org.jclouds.json.config.GsonModule; @@ -58,7 +57,7 @@ public class ParseKeyListTest extends BaseSetParserTest { } protected Injector injector() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyTest.java index 99c65d2de0..c464de6066 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseKeyTest.java @@ -22,7 +22,6 @@ import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; 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.json.BaseItemParserTest; import org.jclouds.json.config.GsonModule; @@ -53,7 +52,7 @@ public class ParseKeyTest extends BaseItemParserTest { } protected Injector injector() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineListTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineListTest.java index cc7f86a91d..df92bc0d8f 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineListTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineListTest.java @@ -25,9 +25,8 @@ import javax.ws.rs.core.MediaType; import org.jclouds.date.internal.SimpleDateFormatDateService; 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.Type; +import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type; import org.jclouds.json.BaseSetParserTest; import org.jclouds.json.config.GsonModule; import org.testng.annotations.Test; @@ -52,8 +51,16 @@ public class ParseMachineListTest extends BaseSetParserTest { @Consumes(MediaType.APPLICATION_JSON) public Set expected() { 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. builder().add("37.153.96.56").add("10.224.0.57").build()) + .memorySizeMb(1024).diskSizeGb(61440).metadata(ImmutableMap. 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") .name("sample-e92") .type(Type.VIRTUALMACHINE) @@ -67,21 +74,12 @@ public class ParseMachineListTest extends BaseSetParserTest { .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")) .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. builder().add("37.153.96.56").add("10.224.0.57").build()) - .memorySizeMb(1024).diskSizeGb(61440).metadata(ImmutableMap. of()) - .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:39:43+00:00")) - .updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-05-09T13:43:45+00:00")) .build() - ); } protected Injector injector() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineTest.java index af5c0ad306..38fa37f141 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParseMachineTest.java @@ -23,9 +23,8 @@ import javax.ws.rs.core.MediaType; import org.jclouds.date.internal.SimpleDateFormatDateService; 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.Type; +import org.jclouds.joyent.cloudapi.v6_5.domain.Machine.Type; import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.config.GsonModule; import org.testng.annotations.Test; @@ -67,7 +66,7 @@ public class ParseMachineTest extends BaseItemParserTest { } protected Injector injector() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageListTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageListTest.java index d1b83eddf2..3ac142cbb1 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageListTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageListTest.java @@ -23,7 +23,6 @@ import java.util.Set; import javax.ws.rs.Consumes; 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.json.BaseSetParserTest; import org.jclouds.json.config.GsonModule; @@ -57,7 +56,7 @@ public class ParsePackageListTest extends BaseSetParserTest { } protected Injector injector() { - return Guice.createInjector(new JoyentCloudParserModule(), new GsonModule() { + return Guice.createInjector(new GsonModule() { @Override protected void configure() { diff --git a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageTest.java b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageTest.java index f29ee5d993..8b9da901b0 100644 --- a/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageTest.java +++ b/labs/joyent-cloudapi/src/test/java/org/jclouds/joyent/cloudapi/v6_5/parse/ParsePackageTest.java @@ -21,7 +21,6 @@ package org.jclouds.joyent.cloudapi.v6_5.parse; import javax.ws.rs.Consumes; import javax.ws.rs.core.MediaType; -import org.jclouds.joyent.cloudapi.v6_5.config.JoyentCloudParserModule; import org.jclouds.json.BaseItemParserTest; import org.jclouds.json.config.GsonModule; import org.testng.annotations.Test; @@ -43,12 +42,16 @@ public class ParsePackageTest extends BaseItemParserTest