Merged files

This commit is contained in:
Alex Yarmula 2010-04-14 16:43:04 -07:00
commit 66538e4676
33 changed files with 1489 additions and 1167 deletions

View File

@ -4,7 +4,7 @@ jclouds is an open source framework that helps you get started in the cloud
and reuse your java development skills. Our api allows you to freedom to use and reuse your java development skills. Our api allows you to freedom to use
portable abstractions or cloud-specific features. portable abstractions or cloud-specific features.
our current version is 1.0-beta-3 our current version is 1.0-beta-4
our dev version is 1.0-SNAPSHOT our dev version is 1.0-SNAPSHOT
our compute api supports: ec2, rackspace, rimuhosting, vcloud, terremark, our compute api supports: ec2, rackspace, rimuhosting, vcloud, terremark,
@ -45,11 +45,13 @@ Compute Example:
nodes = client.runNodesWithTag("mycluster", 2, template); nodes = client.runNodesWithTag("mycluster", 2, template);
Downloads: Downloads:
* distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-3-package.zip * distribution zip: http://jclouds.googlecode.com/files/jclouds-1.0-beta-4.zip
* maven repo: http://jclouds.googlecode.com/svn/repo * maven repo: http://jclouds.googlecode.com/svn/repo
* snapshot repo: http://jclouds.rimuhosting.com/maven2/snapshots * snapshot repo: http://jclouds.rimuhosting.com/maven2/snapshots
Links: Links:
* project page: http://code.google.com/p/jclouds/ * project page: http://code.google.com/p/jclouds/
* javadocs: http://jclouds.rimuhosting.com/apidocs/
* user group: http://groups.google.com/group/jclouds
* dev group: http://groups.google.com/group/jclouds-dev * dev group: http://groups.google.com/group/jclouds-dev
* twitter: http://twitter.com/jclouds * twitter: http://twitter.com/jclouds

View File

@ -0,0 +1,210 @@
;;
;; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
;;
;; ====================================================================
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; ====================================================================
;;
(ns
#^{:author "Chas Emerick, cemerick@snowtide.com"
:doc "A clojure binding to the jclouds EBS service interface."}
org.jclouds.aws.ebs
(:require (org.jclouds [compute :as compute]))
(:use (clojure.contrib def core))
(:import org.jclouds.aws.domain.Region
org.jclouds.aws.ec2.domain.AvailabilityZone
(org.jclouds.aws.ec2.options DescribeSnapshotsOptions DetachVolumeOptions CreateSnapshotOptions)))
(defn #^org.jclouds.aws.ec2.services.ElasticBlockStoreClient
ebs-services
"Returns the synchronous ElasticBlockStoreClient associated with
the specified compute service, or compute/*compute* as bound by with-compute-service."
[& [compute]]
(-> (or compute compute/*compute*)
.getContext .getProviderSpecificContext .getApi .getElasticBlockStoreServices))
(defn as-region
"Returns the first argument as the corresponding Region if it is a
keyword or already a Region instance. An optional second argument
is returned if the first cannot be coerced into a Region.
Returns nil otherwise."
[v & [default-region]]
(cond
(keyword? v) (Region/fromValue (name v))
(instance? Region v) v
:else default-region))
(defn describe-volumes
"Returns a set of org.jclouds.aws.ec2.domain.Volume instances corresponding to the
volumes in the specified region (defaulting to your account's default region).
e.g. (with-compute-service [compute] (describe-volumes))
(with-compute-service [compute] (describe-volumes :us-east-1 \"vol-6b218805\" ...))"
[& [region & volume-ids]]
(set
(.describeVolumesInRegion (ebs-services)
(as-region region Region/DEFAULT)
(into-array String (if (as-region region)
volume-ids
(cons region volume-ids))))))
(defvar- snapshot-options-ops
{:ids #(.snapshotIds % (into-array %2))
:owners #(.ownedBy % (into-array %2))
:restorable-by #(.restorableBy % (into-array %2))})
(defn- snapshot-options
[options-seq]
(let [optmap (apply hash-map options-seq)
string-array #(let [v (% optmap)]
(into-array String (if (string? v) [v] v)))]
(-> (DescribeSnapshotsOptions.)
(.ownedBy (string-array :owner))
(.snapshotIds (string-array :ids))
(.restorableBy (string-array :restorable-by)))))
(defn describe-snapshots
"Returns a set of org.jclouds.aws.ec2.domain.Snapshot instances corresponding to the
snapshots in the specified region (defaulting to your account's default region)
limited according to the further options provided.
This returns all of the snapshots you own (you can also provide \"amazon\" or an AWS
account ID here):
(with-compute-service [compute]
(describe-snapshots [:owner \"self\"]))
This returns metadata on the two specified snapshots in us-west-1 (assuming you have access to them):
(with-compute-service [compute]
(describe-snapshots :us-west-1 [:ids [\"snap-44b3ab2d\" \"snap-9e8821f7\"]]))
There is also a :restorable-by option. Option values can be provided as strings, or
collections of strings."
[& [region & option-keyvals]]
(let [options (apply snapshot-options
(if (as-region region)
option-keyvals
(cons region option-keyvals)))]
(set
(.describeSnapshotsInRegion (ebs-services)
(as-region region Region/DEFAULT)
(into-array DescribeSnapshotsOptions [options])))))
(defn- as-string
[v]
(cond
(string? v) v
(keyword? v) (name v)
:else v))
(defn- get-string
[map key]
(as-string (get map key)))
(defn- as-int
[v]
(cond
(number? v) (int v)
(string? v) (Integer/parseInt v)
:else (throw (IllegalArgumentException.
(str "Don't know how to convert object of type " (class v) " to a string")))))
(defn create-snapshot
"Creates a snapshot of a volume in the specified region with an optional description.
If provided, the description must be < 255 characters in length. Returns the
org.jclouds.aws.ec2.domain.Snapshot object representing the created snapshot.
e.g. (with-compute-service [compute]
(create-snapshot :us-east-1 \"vol-1dbe6785\")
(create-snapshot :us-east-1 \"vol-1dbe6785\" \"super-important data\"))"
[region volume-id & [description]]
(.createSnapshotInRegion (ebs-services)
(as-region region)
(as-string volume-id)
(into-array CreateSnapshotOptions (when description
[(.withDescription (CreateSnapshotOptions.) description)]))))
(defn delete-snapshot
"Deletes a snapshot in the specified region.
e.g. (with-compute-service [compute]
(delete-snapshot :us-east-1 :snap-252310af)
(delete-snapshot :us-east-1 \"snap-242adf03\"))"
[region snapshot-id]
(.deleteSnapshotInRegion (ebs-services)
(as-region region)
(as-string snapshot-id)))
(defn create-volume
"Creates a new volume given a set of options. :zone is required, one
or both of :size and :snapshot may also be provided; all values can be strings or keywords,
:size may be a number, and :zone may be a org.jclouds.aws.ec2.domain.AvailabilityZone.
Returns the created org.jclouds.aws.ec2.domain.Volume.
e.g. (with-compute-service [compute]
(create-volume :zone :us-east-1a :size 250)
(create-volume :zone :eu-west-1b :snapshot \"snap-252310af\")
(create-volume :zone :eu-west-1b :snapshot \"snap-252310af\" :size :1024))"
[& options]
(when (-> options count odd?)
(throw (IllegalArgumentException. "Must provide key-value pairs, e.g. :zone :us-east-1d :size 200")))
(let [options (apply hash-map options)
snapshot (get-string options :snapshot)
size (-?> (get-string options :size) as-int)
zone (get-string options :zone)
zone (if zone
(if (instance? AvailabilityZone zone)
zone
(AvailabilityZone/fromValue zone))
(throw (IllegalArgumentException. "Must supply a :zone option.")))
ebs (ebs-services)]
(cond
(and snapshot size) (.createVolumeFromSnapshotInAvailabilityZone ebs zone size snapshot)
snapshot (.createVolumeFromSnapshotInAvailabilityZone ebs zone snapshot)
size (.createVolumeInAvailabilityZone ebs zone size)
:else (throw (IllegalArgumentException. "Must supply :size and/or :snapshot options.")))))
(defn delete-volume
"Deletes a volume in the specified region.
e.g. (with-compute-service [compute]
(delete-volume :us-east-1 :vol-45228a6d)
(delete-volume :us-east-1 \"vol-052b846c\"))"
[region volume-id]
(.deleteVolumeInRegion (ebs-services)
(as-region region)
(as-string volume-id)))
(defn attach-volume
"Attaches a volume to an instance, returning the resulting org.jclouds.aws.ec2.domain.Attachment.
The region must be a keyword or Region instance; the remaining parameters may be
strings or keywords.
e.g. (with-compute-service [compute]
(attach-volume :us-east-1 :vol-45228a6d \"i-a92358c1\" \"/dev/sdh\"))"
[region & [volume-id instance-id device :as options]]
(apply #(.attachVolumeInRegion (ebs-services)
(as-region region) % %2 %3)
(map as-string options)))
(defn detach-volume
"Detatches a volume from the instance to which it is currently attached.
The optional force? parameter, if logically true, will cause the volume to be forcibly
detached, regardless of whether it is in-use (mounted) or not.
(It appears that issuing a detatch-volume command while the volume in question is mounted
will cause the volume to be detatched immediately upon the volume beign unmounted."
[region volume-id & [force?]]
(.detachVolumeInRegion (ebs-services)
(as-region region)
(as-string volume-id)
(boolean force?)
(into-array DetachVolumeOptions [])))

View File

@ -107,11 +107,8 @@ public class EC2ComputeServiceContextModule extends EC2ContextModule {
} }
@Provides @Provides
TemplateBuilder provideTemplate(Map<String, ? extends Location> locations, TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes, return template.architecture(Architecture.X86_32).osFamily(UBUNTU);
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).architecture(
Architecture.X86_32).osFamily(UBUNTU);
} }
@Singleton @Singleton

View File

@ -68,10 +68,9 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
Template simpleTemplate = client.templateBuilder().smallest().build(); Template simpleTemplate = client.templateBuilder().smallest().build();
client.runNodesWithTag("ec2", 1, simpleTemplate); client.runNodesWithTag("ec2", 1, simpleTemplate);
Map<String, ? extends NodeMetadata> map = client.getNodesWithTag("ec2"); Map<String, ? extends NodeMetadata> map = client.getNodesWithTag("ec2");
NodeMetadata node = map.values().iterator().next(); map.values().iterator().next();
Credentials creds = new Credentials("ubuntu", keyPair.get("public")); Credentials creds = new Credentials("ubuntu", keyPair.get("public"));
client.runScriptOnNodesWithTag("ec2", creds, client.runScriptOnNodesWithTag("ec2", creds, "mkdir ~/ahha; sleep 3".getBytes());
"mkdir ~/ahha; sleep 3".getBytes());
client.destroyNodesWithTag("ec2"); client.destroyNodesWithTag("ec2");
} }

View File

@ -119,7 +119,8 @@ public class EC2ComputeServiceTest {
return new TemplateBuilderImpl(ImmutableMap.of("us-east-1", location), ImmutableMap.of( return new TemplateBuilderImpl(ImmutableMap.of("us-east-1", location), ImmutableMap.of(
"ami-image", image), Maps.uniqueIndex(ImmutableSet.of(EC2Size.C1_MEDIUM, "ami-image", image), Maps.uniqueIndex(ImmutableSet.of(EC2Size.C1_MEDIUM,
EC2Size.C1_XLARGE, EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE, EC2Size.C1_XLARGE, EC2Size.M1_LARGE, EC2Size.M1_SMALL, EC2Size.M1_XLARGE,
EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE), indexer()), location); EC2Size.M2_XLARGE, EC2Size.M2_2XLARGE, EC2Size.M2_4XLARGE), indexer()), location) {
};
} }
Function<ComputeMetadata, String> indexer() { Function<ComputeMetadata, String> indexer() {

View File

@ -1,3 +1,21 @@
;;
;; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
;;
;; ====================================================================
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; ====================================================================
;;
(ns org.jclouds.blobstore (ns org.jclouds.blobstore
"A clojure binding for the jclouds BlobStore. "A clojure binding for the jclouds BlobStore.

View File

@ -1,3 +1,21 @@
;;
;; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
;;
;; ====================================================================
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; ====================================================================
;;
(ns org.jclouds.blobstore-test (ns org.jclouds.blobstore-test
(:use [org.jclouds.blobstore] :reload-all) (:use [org.jclouds.blobstore] :reload-all)
(:use [clojure.test]) (:use [clojure.test])

View File

@ -1,3 +1,21 @@
;;
;; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
;;
;; ====================================================================
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; ====================================================================
;;
(ns org.jclouds.compute (ns org.jclouds.compute
"A clojure binding to the jclouds ComputeService. "A clojure binding to the jclouds ComputeService.
@ -174,13 +192,13 @@ See http://code.google.com/p/jclouds for details."
" "
([tag] ([tag]
(run-nodes tag 1 (default-template *compute*) *compute*)) (first (run-nodes tag 1 (default-template *compute*) *compute*)))
([tag compute-or-template] ([tag compute-or-template]
(if (compute-service? compute-or-template) (if (compute-service? compute-or-template)
(run-nodes tag 1 (default-template compute-or-template) compute-or-template) (first (run-nodes tag 1 (default-template compute-or-template) compute-or-template))
(run-nodes tag 1 compute-or-template *compute*))) (first (run-nodes tag 1 compute-or-template *compute*))))
([tag template compute] ([tag template compute]
(run-nodes tag 1 template compute))) (first (run-nodes tag 1 template compute))))
(defn #^NodeMetadata node-details (defn #^NodeMetadata node-details
"Retrieve the node metadata." "Retrieve the node metadata."
@ -266,6 +284,11 @@ See http://code.google.com/p/jclouds for details."
[#^ComputeMetadata node] [#^ComputeMetadata node]
(.getName node)) (.getName node))
(defn location
"Returns the compute node's location id"
[#^ComputeMetadata node]
(.getLocationId node))
(define-accessors Template image size location options) (define-accessors Template image size location options)
(define-accessors Image version os-family os-description architecture) (define-accessors Image version os-family os-description architecture)
(define-accessors Size cores ram disk) (define-accessors Size cores ram disk)

View File

@ -18,16 +18,15 @@
*/ */
package org.jclouds.compute; package org.jclouds.compute;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import org.jclouds.compute.config.ResolvesImages; import org.jclouds.compute.config.ResolvesImages;
import org.jclouds.compute.internal.ComputeServiceContextImpl; import org.jclouds.compute.internal.ComputeServiceContextImpl;
import org.jclouds.rest.RestContextBuilder; import org.jclouds.rest.RestContextBuilder;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.inject.Injector;
import com.google.inject.Key; import com.google.inject.Key;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.TypeLiteral; import com.google.inject.TypeLiteral;
@ -80,7 +79,6 @@ public abstract class ComputeServiceContextBuilder<A, S> extends RestContextBuil
} }
} }
@SuppressWarnings({"UnusedDeclaration"})
protected void addImageResolutionModule() { protected void addImageResolutionModule() {
// do nothing; // do nothing;
// this is to be overridden when needed // this is to be overridden when needed

View File

@ -97,7 +97,7 @@ public class TemplateBuilderImpl implements TemplateBuilder {
private TemplateOptions options = TemplateOptions.NONE; private TemplateOptions options = TemplateOptions.NONE;
@Inject @Inject
public TemplateBuilderImpl(Map<String, ? extends Location> locations, protected TemplateBuilderImpl(Map<String, ? extends Location> locations,
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes, Map<String, ? extends Image> images, Map<String, ? extends Size> sizes,
Location defaultLocation) { Location defaultLocation) {
this.locations = locations; this.locations = locations;

View File

@ -1,3 +1,21 @@
;;
;; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
;;
;; ====================================================================
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; ====================================================================
;;
(ns org.jclouds.compute-test (ns org.jclouds.compute-test
(:use [org.jclouds.compute] :reload-all) (:use [org.jclouds.compute] :reload-all)
(:use clojure.test)) (:use clojure.test))

View File

@ -1,3 +1,21 @@
;;
;; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
;;
;; ====================================================================
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; ====================================================================
;;
(ns org.jclouds.core (ns org.jclouds.core
"Core functionality used across blobstore and compute." "Core functionality used across blobstore and compute."
(:use clojure.contrib.logging (:use clojure.contrib.logging
@ -8,6 +26,7 @@
(def module-lookup (def module-lookup
{:log4j 'org.jclouds.logging.log4j.config.Log4JLoggingModule {:log4j 'org.jclouds.logging.log4j.config.Log4JLoggingModule
:lognull 'org.jclouds.logging.config.NullLoggingModule
:ssh 'org.jclouds.ssh.jsch.config.JschSshClientModule :ssh 'org.jclouds.ssh.jsch.config.JschSshClientModule
:enterprise 'org.jclouds.enterprise.config.EnterpriseConfigurationModule :enterprise 'org.jclouds.enterprise.config.EnterpriseConfigurationModule
:httpnio 'org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule :httpnio 'org.jclouds.http.httpnio.config.NioTransformingHttpCommandExecutorServiceModule

View File

@ -125,7 +125,6 @@ public class ParserModule extends AbstractModule {
SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(false); factory.setNamespaceAware(false);
factory.setValidating(false); factory.setValidating(false);
factory.setXIncludeAware(false);
return factory; return factory;
} }

View File

@ -1,3 +1,21 @@
;;
;; Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
;;
;; ====================================================================
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; You may obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;; ====================================================================
;;
(ns org.jclouds.core-test (ns org.jclouds.core-test
(:use [org.jclouds.core] :reload-all) (:use [org.jclouds.core] :reload-all)
(:use clojure.test)) (:use clojure.test))

View File

@ -106,11 +106,8 @@ public class GoGridComputeServiceContextModule extends GoGridContextModule {
} }
@Provides @Provides
TemplateBuilder provideTemplate(Map<String, ? extends Location> locations, TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes, return template.osFamily(CENTOS).imageNameMatches(".*w/ None.*");
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).osFamily(CENTOS)
.imageNameMatches(".*w/ None.*");
} }
@Provides @Provides

View File

@ -23,32 +23,53 @@
*/ */
package org.jclouds.gogrid.options; package org.jclouds.gogrid.options;
import org.jclouds.http.options.BaseHttpRequestOptions; import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Preconditions.checkState;
import static org.jclouds.gogrid.reference.GoGridQueryParams.*; import static org.jclouds.gogrid.reference.GoGridQueryParams.DESCRIPTION_KEY;
import static org.jclouds.gogrid.reference.GoGridQueryParams.IS_SANDBOX_KEY;
import org.jclouds.http.options.BaseHttpRequestOptions;
/** /**
* @author Oleksiy Yarmula * @author Oleksiy Yarmula
*/ */
public class AddServerOptions extends BaseHttpRequestOptions { public class AddServerOptions extends BaseHttpRequestOptions {
public AddServerOptions setDescription(String description) { public AddServerOptions withDescription(String description) {
checkState(!queryParameters.containsKey(DESCRIPTION_KEY), "Can't have duplicate server description"); checkArgument(description.length() <= 500, "Description cannot be longer than 500 characters");
checkState(!queryParameters.containsKey(DESCRIPTION_KEY),
"Can't have duplicate server description");
queryParameters.put(DESCRIPTION_KEY, description); queryParameters.put(DESCRIPTION_KEY, description);
return this; return this;
} }
/** /**
* Make server a sandbox instance. * Make server a sandbox instance. By default, it's not.
* By default, it's not.
* *
* @return itself for convenience * @return itself for convenience
*/ */
public AddServerOptions makeSandboxType() { public AddServerOptions asSandboxType() {
checkState(!queryParameters.containsKey(IS_SANDBOX_KEY), "Can only have one sandbox option per server"); checkState(!queryParameters.containsKey(IS_SANDBOX_KEY),
"Can only have one sandbox option per server");
queryParameters.put(IS_SANDBOX_KEY, "true"); queryParameters.put(IS_SANDBOX_KEY, "true");
return this; return this;
} }
public static class Builder {
/**
* @see AddServerOptions#withDescription(String)
*/
public static AddServerOptions withDescription(String description) {
AddServerOptions options = new AddServerOptions();
return options.withDescription(description);
}
/**
* @see AddServerOptions#asSandboxType()
*/
public static AddServerOptions asSandboxType() {
AddServerOptions options = new AddServerOptions();
return options.asSandboxType();
}
}
} }

View File

@ -39,7 +39,7 @@ public interface GoGridQueryParams {
public static final String SERVER_RAM_KEY = "server.ram"; public static final String SERVER_RAM_KEY = "server.ram";
public static final String DESCRIPTION_KEY = "server.ram"; public static final String DESCRIPTION_KEY = "description";
public static final String POWER_KEY = "power"; public static final String POWER_KEY = "power";
public static final String MAX_NUMBER_KEY = "num_items"; public static final String MAX_NUMBER_KEY = "num_items";

View File

@ -18,13 +18,40 @@
*/ */
package org.jclouds.gogrid; package org.jclouds.gogrid;
import com.google.common.base.Predicate; import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Iterables; import static java.lang.String.format;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.gogrid.domain.*; import org.jclouds.gogrid.domain.Ip;
import org.jclouds.gogrid.domain.IpPortPair;
import org.jclouds.gogrid.domain.Job;
import org.jclouds.gogrid.domain.LoadBalancer;
import org.jclouds.gogrid.domain.LoadBalancerPersistenceType;
import org.jclouds.gogrid.domain.LoadBalancerType;
import org.jclouds.gogrid.domain.PowerCommand;
import org.jclouds.gogrid.domain.Server;
import org.jclouds.gogrid.domain.ServerImage;
import org.jclouds.gogrid.domain.ServerImageType;
import org.jclouds.gogrid.options.AddLoadBalancerOptions; import org.jclouds.gogrid.options.AddLoadBalancerOptions;
import org.jclouds.gogrid.options.AddServerOptions;
import org.jclouds.gogrid.options.GetImageListOptions; import org.jclouds.gogrid.options.GetImageListOptions;
import org.jclouds.gogrid.options.GetIpListOptions;
import org.jclouds.gogrid.predicates.LoadBalancerLatestJobCompleted; import org.jclouds.gogrid.predicates.LoadBalancerLatestJobCompleted;
import org.jclouds.gogrid.predicates.ServerLatestJobCompleted; import org.jclouds.gogrid.predicates.ServerLatestJobCompleted;
import org.jclouds.logging.log4j.config.Log4JLoggingModule; import org.jclouds.logging.log4j.config.Log4JLoggingModule;
@ -38,16 +65,8 @@ import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups; import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import javax.annotation.Nullable; import com.google.common.base.Predicate;
import java.io.IOException; import com.google.common.collect.Iterables;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.concurrent.TimeUnit;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.*;
import static java.lang.String.format;
/** /**
* End to end live test for GoGrid * End to end live test for GoGrid
@ -55,7 +74,6 @@ import static java.lang.String.format;
* @author Oleksiy Yarmula * @author Oleksiy Yarmula
*/ */
@Test(groups = "live", testName = "gogrid.GoGridLiveTest") @Test(groups = "live", testName = "gogrid.GoGridLiveTest")
public class GoGridLiveTest { public class GoGridLiveTest {
private GoGridClient client; private GoGridClient client;
@ -63,8 +81,7 @@ public class GoGridLiveTest {
private RetryablePredicate<Server> serverLatestJobCompleted; private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<LoadBalancer> loadBalancerLatestJobCompleted; private RetryablePredicate<LoadBalancer> loadBalancerLatestJobCompleted;
/** /**
* Keeps track of the servers, created during the tests, * Keeps track of the servers, created during the tests, to remove them after all tests complete
* to remove them after all tests complete
*/ */
private List<String> serversToDeleteAfterTheTests = new ArrayList<String>(); private List<String> serversToDeleteAfterTheTests = new ArrayList<String>();
private List<String> loadBalancersToDeleteAfterTest = new ArrayList<String>(); private List<String> loadBalancersToDeleteAfterTest = new ArrayList<String>();
@ -77,19 +94,44 @@ public class GoGridLiveTest {
client = GoGridContextFactory.createContext(user, password, new Log4JLoggingModule()) client = GoGridContextFactory.createContext(user, password, new Log4JLoggingModule())
.getApi(); .getApi();
serverLatestJobCompleted = new RetryablePredicate<Server>( serverLatestJobCompleted = new RetryablePredicate<Server>(new ServerLatestJobCompleted(client
new ServerLatestJobCompleted(client.getJobServices()), .getJobServices()), 800, 20, TimeUnit.SECONDS);
800, 20, TimeUnit.SECONDS);
loadBalancerLatestJobCompleted = new RetryablePredicate<LoadBalancer>( loadBalancerLatestJobCompleted = new RetryablePredicate<LoadBalancer>(
new LoadBalancerLatestJobCompleted(client.getJobServices()), new LoadBalancerLatestJobCompleted(client.getJobServices()), 800, 20,
800, 20, TimeUnit.SECONDS); TimeUnit.SECONDS);
}
@Test(enabled = false)
public void testDescriptionIs500Characters() {
final String nameOfServer = "Description" + String.valueOf(new Date().getTime()).substring(6);
serversToDeleteAfterTheTests.add(nameOfServer);
Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList();
Ip availableIp = Iterables.getLast(availableIps);
String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1 * 500; i++)
builder.append('a');
String description = builder.toString();
Server createdServer = client.getServerServices().addServer(nameOfServer,
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c", ram, availableIp.getIp(),
new AddServerOptions().withDescription(description));
assertNotNull(createdServer);
assert serverLatestJobCompleted.apply(createdServer);
assertEquals(Iterables.getLast(client.getServerServices().getServersByName(nameOfServer))
.getDescription(), description);
} }
/** /**
* Tests server start, reboot and deletion. * Tests server start, reboot and deletion. Also verifies IP services and job services.
* Also verifies IP services and job services.
*/ */
@Test(enabled=true) @Test(enabled = false)
public void testServerLifecycle() { public void testServerLifecycle() {
int serverCountBeforeTest = client.getServerServices().getServerList().size(); int serverCountBeforeTest = client.getServerServices().getServerList().size();
@ -102,9 +144,7 @@ public class GoGridLiveTest {
String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName(); String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName();
Server createdServer = client.getServerServices().addServer(nameOfServer, Server createdServer = client.getServerServices().addServer(nameOfServer,
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c", "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", ram, availableIp.getIp());
ram,
availableIp.getIp());
assertNotNull(createdServer); assertNotNull(createdServer);
assert serverLatestJobCompleted.apply(createdServer); assert serverLatestJobCompleted.apply(createdServer);
@ -121,8 +161,7 @@ public class GoGridLiveTest {
assert serverLatestJobCompleted.apply(createdServer); assert serverLatestJobCompleted.apply(createdServer);
int serverCountAfterAddingOneServer = client.getServerServices().getServerList().size(); int serverCountAfterAddingOneServer = client.getServerServices().getServerList().size();
assert serverCountAfterAddingOneServer == serverCountBeforeTest + 1 : assert serverCountAfterAddingOneServer == serverCountBeforeTest + 1 : "There should be +1 increase in the number of servers since the test started";
"There should be +1 increase in the number of servers since the test started";
// delete the server // delete the server
client.getServerServices().deleteByName(nameOfServer); client.getServerServices().deleteByName(nameOfServer);
@ -133,18 +172,17 @@ public class GoGridLiveTest {
assert serverLatestJobCompleted.apply(createdServer); assert serverLatestJobCompleted.apply(createdServer);
int serverCountAfterDeletingTheServer = client.getServerServices().getServerList().size(); int serverCountAfterDeletingTheServer = client.getServerServices().getServerList().size();
assert serverCountAfterDeletingTheServer == serverCountBeforeTest : assert serverCountAfterDeletingTheServer == serverCountBeforeTest : "There should be the same # of servers as since the test started";
"There should be the same # of servers as since the test started";
// make sure that IP is put back to "unassigned" // make sure that IP is put back to "unassigned"
assert client.getIpServices().getUnassignedIpList().contains(availableIp); assert client.getIpServices().getUnassignedIpList().contains(availableIp);
} }
/** /**
* Starts a servers, verifies that jobs are created correctly and * Starts a servers, verifies that jobs are created correctly and an be retrieved from the job
* an be retrieved from the job services * services
*/ */
@Test(dependsOnMethods = "testServerLifecycle", enabled=true) @Test(dependsOnMethods = "testServerLifecycle", enabled = false)
public void testJobs() { public void testJobs() {
final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6); final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6);
serversToDeleteAfterTheTests.add(nameOfServer); serversToDeleteAfterTheTests.add(nameOfServer);
@ -154,8 +192,7 @@ public class GoGridLiveTest {
String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName(); String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName();
Server createdServer = client.getServerServices().addServer(nameOfServer, Server createdServer = client.getServerServices().addServer(nameOfServer,
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c", "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", ram,
ram,
Iterables.getLast(availableIps).getIp()); Iterables.getLast(availableIps).getIp());
assert serverLatestJobCompleted.apply(createdServer); assert serverLatestJobCompleted.apply(createdServer);
@ -168,7 +205,8 @@ public class GoGridLiveTest {
Job latestJob = Iterables.getLast(jobs); Job latestJob = Iterables.getLast(jobs);
Long latestJobId = latestJob.getId(); Long latestJobId = latestJob.getId();
Job latestJobFetched = Iterables.getOnlyElement(client.getJobServices().getJobsById(latestJobId)); Job latestJobFetched = Iterables.getOnlyElement(client.getJobServices().getJobsById(
latestJobId));
assert latestJob.equals(latestJobFetched) : "Job and its reprentation found by ID don't match"; assert latestJob.equals(latestJobFetched) : "Job and its reprentation found by ID don't match";
@ -177,47 +215,49 @@ public class GoGridLiveTest {
idsOfAllJobs.add(job.getId()); idsOfAllJobs.add(job.getId());
} }
Set<Job> jobsFetched = client.getJobServices().getJobsById(idsOfAllJobs.toArray(new Long[jobs.size()])); Set<Job> jobsFetched = client.getJobServices().getJobsById(
assert jobsFetched.size() == jobs.size() : format("Number of jobs fetched by ids doesn't match the number of jobs " + idsOfAllJobs.toArray(new Long[jobs.size()]));
"requested. Requested/expected: %d. Found: %d.", assert jobsFetched.size() == jobs.size() : format(
jobs.size(), jobsFetched.size()); "Number of jobs fetched by ids doesn't match the number of jobs "
+ "requested. Requested/expected: %d. Found: %d.", jobs.size(), jobsFetched
.size());
// delete the server // delete the server
client.getServerServices().deleteByName(nameOfServer); client.getServerServices().deleteByName(nameOfServer);
} }
/** /**
* Tests common load balancer operations. * Tests common load balancer operations. Also verifies IP services and job services.
* Also verifies IP services and job services.
*/ */
@Test(enabled=true) @Test(enabled = false)
public void testLoadBalancerLifecycle() { public void testLoadBalancerLifecycle() {
int lbCountBeforeTest = client.getLoadBalancerServices().getLoadBalancerList().size(); int lbCountBeforeTest = client.getLoadBalancerServices().getLoadBalancerList().size();
final String nameOfLoadBalancer = "LoadBalancer" + String.valueOf(new Date().getTime()).substring(6); final String nameOfLoadBalancer = "LoadBalancer"
+ String.valueOf(new Date().getTime()).substring(6);
loadBalancersToDeleteAfterTest.add(nameOfLoadBalancer); loadBalancersToDeleteAfterTest.add(nameOfLoadBalancer);
Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList(); Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList();
if(availableIps.size() < 4) throw new SkipException("Not enough available IPs (4 needed) to run the test"); if (availableIps.size() < 4)
throw new SkipException("Not enough available IPs (4 needed) to run the test");
Iterator<Ip> ipIterator = availableIps.iterator(); Iterator<Ip> ipIterator = availableIps.iterator();
Ip vip = ipIterator.next(); Ip vip = ipIterator.next();
Ip realIp1 = ipIterator.next(); Ip realIp1 = ipIterator.next();
Ip realIp2 = ipIterator.next(); Ip realIp2 = ipIterator.next();
Ip realIp3 = ipIterator.next(); Ip realIp3 = ipIterator.next();
AddLoadBalancerOptions options = new AddLoadBalancerOptions.Builder(). AddLoadBalancerOptions options = new AddLoadBalancerOptions.Builder().create(
create(LoadBalancerType.LEAST_CONNECTED, LoadBalancerPersistenceType.SOURCE_ADDRESS); LoadBalancerType.LEAST_CONNECTED, LoadBalancerPersistenceType.SOURCE_ADDRESS);
LoadBalancer createdLoadBalancer = client.getLoadBalancerServices(). LoadBalancer createdLoadBalancer = client.getLoadBalancerServices().addLoadBalancer(
addLoadBalancer(nameOfLoadBalancer, new IpPortPair(vip, 80), nameOfLoadBalancer, new IpPortPair(vip, 80),
Arrays.asList(new IpPortPair(realIp1, 80), Arrays.asList(new IpPortPair(realIp1, 80), new IpPortPair(realIp2, 80)), options);
new IpPortPair(realIp2, 80)), options);
assertNotNull(createdLoadBalancer); assertNotNull(createdLoadBalancer);
assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer); assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer);
// get load balancer by name // get load balancer by name
Set<LoadBalancer> response = client.getLoadBalancerServices().getLoadBalancersByName(nameOfLoadBalancer); Set<LoadBalancer> response = client.getLoadBalancerServices().getLoadBalancersByName(
nameOfLoadBalancer);
assert (response.size() == 1); assert (response.size() == 1);
createdLoadBalancer = Iterables.getOnlyElement(response); createdLoadBalancer = Iterables.getOnlyElement(response);
assertNotNull(createdLoadBalancer.getRealIpList()); assertNotNull(createdLoadBalancer.getRealIpList());
@ -225,16 +265,17 @@ public class GoGridLiveTest {
assertNotNull(createdLoadBalancer.getVirtualIp()); assertNotNull(createdLoadBalancer.getVirtualIp());
assertEquals(createdLoadBalancer.getVirtualIp().getIp().getIp(), vip.getIp()); assertEquals(createdLoadBalancer.getVirtualIp().getIp().getIp(), vip.getIp());
LoadBalancer editedLoadBalancer = client.getLoadBalancerServices(). LoadBalancer editedLoadBalancer = client.getLoadBalancerServices().editLoadBalancer(
editLoadBalancer(nameOfLoadBalancer, Arrays.asList(new IpPortPair(realIp3, 8181))); nameOfLoadBalancer, Arrays.asList(new IpPortPair(realIp3, 8181)));
assert loadBalancerLatestJobCompleted.apply(editedLoadBalancer); assert loadBalancerLatestJobCompleted.apply(editedLoadBalancer);
assertNotNull(editedLoadBalancer.getRealIpList()); assertNotNull(editedLoadBalancer.getRealIpList());
assertEquals(editedLoadBalancer.getRealIpList().size(), 1); assertEquals(editedLoadBalancer.getRealIpList().size(), 1);
assertEquals(Iterables.getOnlyElement(editedLoadBalancer.getRealIpList()).getIp().getIp(), realIp3.getIp()); assertEquals(Iterables.getOnlyElement(editedLoadBalancer.getRealIpList()).getIp().getIp(),
realIp3.getIp());
int lbCountAfterAddingOneServer = client.getLoadBalancerServices().getLoadBalancerList().size(); int lbCountAfterAddingOneServer = client.getLoadBalancerServices().getLoadBalancerList()
assert lbCountAfterAddingOneServer == lbCountBeforeTest + 1 : .size();
"There should be +1 increase in the number of load balancers since the test started"; assert lbCountAfterAddingOneServer == lbCountBeforeTest + 1 : "There should be +1 increase in the number of load balancers since the test started";
// delete the load balancer // delete the load balancer
client.getLoadBalancerServices().deleteByName(nameOfLoadBalancer); client.getLoadBalancerServices().deleteByName(nameOfLoadBalancer);
@ -244,15 +285,15 @@ public class GoGridLiveTest {
assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer); assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer);
int lbCountAfterDeletingTheServer = client.getLoadBalancerServices().getLoadBalancerList().size(); int lbCountAfterDeletingTheServer = client.getLoadBalancerServices().getLoadBalancerList()
assert lbCountAfterDeletingTheServer == lbCountBeforeTest : .size();
"There should be the same # of load balancers as since the test started"; assert lbCountAfterDeletingTheServer == lbCountBeforeTest : "There should be the same # of load balancers as since the test started";
} }
/** /**
* Tests common server image operations. * Tests common server image operations.
*/ */
@Test(enabled=true) @Test(enabled = false)
public void testImageLifecycle() { public void testImageLifecycle() {
GetImageListOptions options = new GetImageListOptions.Builder().publicDatabaseServers(); GetImageListOptions options = new GetImageListOptions.Builder().publicDatabaseServers();
Set<ServerImage> images = client.getImageServices().getImageList(options); Set<ServerImage> images = client.getImageServices().getImageList(options);
@ -267,13 +308,14 @@ public class GoGridLiveTest {
assert Iterables.all(images, isDatabaseServer) : "All of the images should've been of database type"; assert Iterables.all(images, isDatabaseServer) : "All of the images should've been of database type";
ServerImage image = Iterables.getLast(images); ServerImage image = Iterables.getLast(images);
ServerImage imageFromServer = Iterables.getOnlyElement( ServerImage imageFromServer = Iterables.getOnlyElement(client.getImageServices()
client.getImageServices().getImagesByName(image.getName())); .getImagesByName(image.getName()));
assertEquals(image, imageFromServer); assertEquals(image, imageFromServer);
try { try {
client.getImageServices().editImageDescription(image.getName(), "newDescription"); client.getImageServices().editImageDescription(image.getName(), "newDescription");
throw new TestException("An exception hasn't been thrown where expected; expected GoGridResponseException"); throw new TestException(
"An exception hasn't been thrown where expected; expected GoGridResponseException");
} catch (GoGridResponseException e) { } catch (GoGridResponseException e) {
// expected situation - check and proceed // expected situation - check and proceed
assertTrue(e.getMessage().contains("GoGridIllegalArgumentException")); assertTrue(e.getMessage().contains("GoGridIllegalArgumentException"));
@ -281,7 +323,7 @@ public class GoGridLiveTest {
} }
@Test(enabled=true) @Test(enabled = false)
public void testShellAccess() throws IOException { public void testShellAccess() throws IOException {
final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6); final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6);
serversToDeleteAfterTheTests.add(nameOfServer); serversToDeleteAfterTheTests.add(nameOfServer);
@ -290,9 +332,7 @@ public class GoGridLiveTest {
Ip availableIp = Iterables.getLast(availableIps); Ip availableIp = Iterables.getLast(availableIps);
Server createdServer = client.getServerServices().addServer(nameOfServer, Server createdServer = client.getServerServices().addServer(nameOfServer,
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c", "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", "1", availableIp.getIp());
"1",
availableIp.getIp());
assertNotNull(createdServer); assertNotNull(createdServer);
assert serverLatestJobCompleted.apply(createdServer); assert serverLatestJobCompleted.apply(createdServer);
@ -305,20 +345,21 @@ public class GoGridLiveTest {
Credentials instanceCredentials = credsMap.get(createdServer.getName()); Credentials instanceCredentials = credsMap.get(createdServer.getName());
assertNotNull(instanceCredentials); assertNotNull(instanceCredentials);
InetSocketAddress socket = new InetSocketAddress(InetAddress.getByName(createdServer.getIp().getIp()), 22); InetSocketAddress socket = new InetSocketAddress(InetAddress.getByName(createdServer.getIp()
.getIp()), 22);
Predicate<InetSocketAddress> socketOpen = Predicate<InetSocketAddress> socketOpen = new RetryablePredicate<InetSocketAddress>(
new RetryablePredicate<InetSocketAddress>(new SocketOpen(), 180, 5, TimeUnit.SECONDS); new SocketOpen(), 180, 5, TimeUnit.SECONDS);
socketOpen.apply(socket); socketOpen.apply(socket);
SshClient sshClient = SshClient sshClient = new JschSshClient(socket, 60000, instanceCredentials.account,
new JschSshClient(socket, 60000, instanceCredentials.key);
instanceCredentials.account, instanceCredentials.key);
sshClient.connect(); sshClient.connect();
String output = sshClient.exec("df").getOutput(); String output = sshClient.exec("df").getOutput();
assertTrue(output.contains("Filesystem"), assertTrue(output.contains("Filesystem"),
"The output should've contained filesystem information, but it didn't. Output: " + output); "The output should've contained filesystem information, but it didn't. Output: "
+ output);
sshClient.disconnect(); sshClient.disconnect();
// delete the server // delete the server
@ -326,8 +367,7 @@ public class GoGridLiveTest {
} }
/** /**
* In case anything went wrong during the tests, removes the objects * In case anything went wrong during the tests, removes the objects created in the tests.
* created in the tests.
*/ */
@AfterTest @AfterTest
public void cleanup() { public void cleanup() {

View File

@ -0,0 +1,113 @@
/**
*
* Copyright (C) 2010 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.gogrid.options;
import static org.jclouds.gogrid.options.AddServerOptions.Builder.asSandboxType;
import static org.jclouds.gogrid.options.AddServerOptions.Builder.withDescription;
import static org.testng.Assert.assertEquals;
import java.util.Collections;
import org.jclouds.http.options.HttpRequestOptions;
import org.testng.annotations.Test;
/**
* Tests possible uses of AddServerOptions and AddServerOptions.Builder.*
*
* @author Adrian Cole
*/
public class AddServerOptionsTest {
@Test
public void testAssignability() {
assert HttpRequestOptions.class.isAssignableFrom(AddServerOptions.class);
assert !String.class.isAssignableFrom(AddServerOptions.class);
}
@Test
public void testWithDescription() {
AddServerOptions options = new AddServerOptions();
options.withDescription("test");
assertEquals(options.buildQueryParameters().get("description"), Collections
.singletonList("test"));
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testWith501LengthDescription() {
AddServerOptions options = new AddServerOptions();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1 * 501; i++)
builder.append('a');
String description = builder.toString();
options.withDescription(description);
}
@Test
public void testWith500LengthDescription() {
AddServerOptions options = new AddServerOptions();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1 * 500; i++)
builder.append('a');
String description = builder.toString();
options.withDescription(description);
assertEquals(options.buildQueryParameters().get("description"), Collections
.singletonList(description));
}
@Test
public void testNullWithDescription() {
AddServerOptions options = new AddServerOptions();
assertEquals(options.buildQueryParameters().get("description"), Collections.EMPTY_LIST);
}
@Test
public void testWithDescriptionStatic() {
AddServerOptions options = withDescription("test");
assertEquals(options.buildQueryParameters().get("description"), Collections
.singletonList("test"));
}
@Test(expectedExceptions = NullPointerException.class)
public void testWithDescriptionNPE() {
withDescription(null);
}
@Test
public void testAsSandboxType() {
AddServerOptions options = new AddServerOptions();
options.asSandboxType();
assertEquals(options.buildQueryParameters().get("isSandbox"), Collections
.singletonList("true"));
}
@Test
public void testAsSandboxTypeStatic() {
AddServerOptions options = asSandboxType();
assertEquals(options.buildQueryParameters().get("isSandbox"), Collections
.singletonList("true"));
}
}

View File

@ -50,24 +50,23 @@ import java.net.URI;
import javax.inject.Singleton; import javax.inject.Singleton;
import com.google.common.collect.Iterables; import org.jclouds.encryption.EncryptionService;
import org.jclouds.gogrid.GoGrid; import org.jclouds.gogrid.GoGrid;
import org.jclouds.gogrid.domain.PowerCommand; import org.jclouds.gogrid.domain.PowerCommand;
import org.jclouds.gogrid.filters.SharedKeyLiteAuthentication; import org.jclouds.gogrid.filters.SharedKeyLiteAuthentication;
import org.jclouds.gogrid.functions.ParseOptionsFromJsonResponse; import org.jclouds.gogrid.functions.ParseOptionsFromJsonResponse;
import org.jclouds.gogrid.functions.ParseServerFromJsonResponse; import org.jclouds.gogrid.functions.ParseServerFromJsonResponse;
import org.jclouds.gogrid.functions.ParseServerListFromJsonResponse;
import org.jclouds.gogrid.options.AddServerOptions; import org.jclouds.gogrid.options.AddServerOptions;
import org.jclouds.gogrid.options.GetServerListOptions; import org.jclouds.gogrid.options.GetServerListOptions;
import org.jclouds.gogrid.services.GridServerAsyncClient;
import org.jclouds.logging.Logger; import org.jclouds.logging.Logger;
import org.jclouds.logging.Logger.LoggerFactory; import org.jclouds.logging.Logger.LoggerFactory;
import org.jclouds.rest.RestClientTest; import org.jclouds.rest.RestClientTest;
import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.rest.internal.GeneratedHttpRequest;
import org.jclouds.rest.internal.RestAnnotationProcessor; import org.jclouds.rest.internal.RestAnnotationProcessor;
import org.jclouds.gogrid.functions.ParseServerListFromJsonResponse;
import org.jclouds.encryption.EncryptionService;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.collect.Iterables;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Module; import com.google.inject.Module;
import com.google.inject.Provides; import com.google.inject.Provides;
@ -84,10 +83,12 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
@Test @Test
public void testGetServerListNoOptions() throws NoSuchMethodException, IOException { public void testGetServerListNoOptions() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("getServerList", GetServerListOptions[].class); Method method = GridServerAsyncClient.class.getMethod("getServerList",
GetServerListOptions[].class);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method); GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method);
assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/list?v=1.3 HTTP/1.1"); assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/list?v=1.3 HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
@ -98,17 +99,16 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
checkFilters(httpRequest); checkFilters(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/list?"
"GET https://api.gogrid.com/api/grid/server/list?" + + "v=1.3&sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
"v=1.3&sig=3f446f171455fbb5574aecff4997b273&api_key=foo " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Test @Test
public void testGetServerListWithOptions() throws NoSuchMethodException, IOException { public void testGetServerListWithOptions() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("getServerList", GetServerListOptions[].class); Method method = GridServerAsyncClient.class.getMethod("getServerList",
GetServerListOptions[].class);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method, GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
new GetServerListOptions.Builder().onlySandboxServers()); new GetServerListOptions.Builder().onlySandboxServers());
@ -124,19 +124,18 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
checkFilters(httpRequest); checkFilters(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/list?"
"GET https://api.gogrid.com/api/grid/server/list?" + + "v=1.3&isSandbox=true&sig=3f446f171455fbb5574aecff4997b273&api_key=foo "
"v=1.3&isSandbox=true&sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + + "HTTP/1.1");
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Test @Test
public void testGetServersByName() throws NoSuchMethodException, IOException { public void testGetServersByName() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("getServersByName", String[].class); Method method = GridServerAsyncClient.class.getMethod("getServersByName", String[].class);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method, "server1"); GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
"server1");
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/get?v=1.3&name=server1 HTTP/1.1"); "GET https://api.gogrid.com/api/grid/server/get?v=1.3&name=server1 HTTP/1.1");
@ -150,20 +149,18 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
checkFilters(httpRequest); checkFilters(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/get?"
"GET https://api.gogrid.com/api/grid/server/get?" + + "v=1.3&name=server1&" + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo "
"v=1.3&name=server1&" + + "HTTP/1.1");
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Test @Test
public void testGetServersById() throws NoSuchMethodException, IOException { public void testGetServersById() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("getServersById", Long[].class); Method method = GridServerAsyncClient.class.getMethod("getServersById", Long[].class);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method, 123L); GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
123L);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/get?v=1.3&id=123 HTTP/1.1"); "GET https://api.gogrid.com/api/grid/server/get?v=1.3&id=123 HTTP/1.1");
@ -177,29 +174,21 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
checkFilters(httpRequest); checkFilters(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/get?"
"GET https://api.gogrid.com/api/grid/server/get?" + + "v=1.3&id=123&" + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
"v=1.3&id=123&" +
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Test @Test
public void testAddServerNoOptions() throws NoSuchMethodException, IOException { public void testAddServerNoOptions() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("addServer", String.class, String.class, Method method = GridServerAsyncClient.class.getMethod("addServer", String.class,
String.class, String.class, String.class, String.class, String.class, AddServerOptions[].class);
AddServerOptions[].class); GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = "serverName", "img55", "memory", "127.0.0.1");
processor.createRequest(method, "serverName", "img55",
"memory", "127.0.0.1");
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/add?v=1.3&"
"GET https://api.gogrid.com/api/grid/server/add?v=1.3&" + + "name=serverName&server.ram=memory&image=img55&ip=127.0.0.1 " + "HTTP/1.1");
"name=serverName&server.ram=memory&image=img55&ip=127.0.0.1 " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
@ -210,27 +199,51 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
checkFilters(httpRequest); checkFilters(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/add?"
"GET https://api.gogrid.com/api/grid/server/add?" + + "v=1.3&name=serverName&server.ram=memory&" + "image=img55&ip=127.0.0.1&"
"v=1.3&name=serverName&server.ram=memory&" + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
"image=img55&ip=127.0.0.1&" +
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Test
public void testAddServerOptions() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("addServer", String.class,
String.class, String.class, String.class, AddServerOptions[].class);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
"serverName", "img55", "memory", "127.0.0.1", new AddServerOptions()
.asSandboxType().withDescription("fooy"));
assertRequestLineEquals(
httpRequest,
"GET https://api.gogrid.com/api/grid/server/add?v=1.3&name=serverName&server.ram=memory&image=img55&ip=127.0.0.1&isSandbox=true&description=fooy HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(
httpRequest,
"GET https://api.gogrid.com/api/grid/server/add?v=1.3&name=serverName&server.ram=memory&image=img55&ip=127.0.0.1&isSandbox=true&description=fooy&sig=3f446f171455fbb5574aecff4997b273&api_key=foo HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
@Test @Test
public void testPowerServer() throws NoSuchMethodException, IOException { public void testPowerServer() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("power", String.class, PowerCommand.class); Method method = GridServerAsyncClient.class.getMethod("power", String.class,
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = PowerCommand.class);
processor.createRequest(method, "PowerServer", PowerCommand.RESTART); GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
"PowerServer", PowerCommand.RESTART);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/power?v=1.3&" + "GET https://api.gogrid.com/api/grid/server/power?v=1.3&"
"server=PowerServer&power=restart " + + "server=PowerServer&power=restart " + "HTTP/1.1");
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
@ -242,25 +255,22 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/power?v=1.3&" + "GET https://api.gogrid.com/api/grid/server/power?v=1.3&"
"server=PowerServer&power=restart&" + + "server=PowerServer&power=restart&"
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Test @Test
public void testDeleteByName() throws NoSuchMethodException, IOException { public void testDeleteByName() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("deleteByName", String.class); Method method = GridServerAsyncClient.class.getMethod("deleteByName", String.class);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
processor.createRequest(method, "PowerServer"); "PowerServer");
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/delete?v=1.3&" + "GET https://api.gogrid.com/api/grid/server/delete?v=1.3&" + "name=PowerServer "
"name=PowerServer " + + "HTTP/1.1");
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
@ -272,24 +282,20 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/delete?v=1.3&" + "GET https://api.gogrid.com/api/grid/server/delete?v=1.3&" + "name=PowerServer&"
"name=PowerServer&" + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Test @Test
public void testGetRamSizes() throws NoSuchMethodException, IOException { public void testGetRamSizes() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("getRamSizes"); Method method = GridServerAsyncClient.class.getMethod("getRamSizes");
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method);
processor.createRequest(method);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram " + "GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram "
"HTTP/1.1"); + "HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
@ -301,14 +307,12 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram&" + "GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram&"
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
"HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
} }
@Override @Override
protected void checkFilters(GeneratedHttpRequest<GridServerAsyncClient> httpMethod) { protected void checkFilters(GeneratedHttpRequest<GridServerAsyncClient> httpMethod) {
assertEquals(httpMethod.getFilters().size(), 1); assertEquals(httpMethod.getFilters().size(), 1);
@ -335,10 +339,11 @@ public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncCli
}); });
} }
@SuppressWarnings("unused")
@Provides @Provides
@Singleton @Singleton
public SharedKeyLiteAuthentication provideAuthentication(EncryptionService encryptionService) public SharedKeyLiteAuthentication provideAuthentication(
throws UnsupportedEncodingException { EncryptionService encryptionService) throws UnsupportedEncodingException {
return new SharedKeyLiteAuthentication("foo", "bar", 1267243795L, encryptionService); return new SharedKeyLiteAuthentication("foo", "bar", 1267243795L, encryptionService);
} }
}; };

View File

@ -109,10 +109,8 @@ public class CloudServersComputeServiceContextModule extends CloudServersContext
} }
@Provides @Provides
TemplateBuilder provideTemplate(Map<String, ? extends Location> locations, TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes, return template.osFamily(UBUNTU);
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).osFamily(UBUNTU);
} }
@Provides @Provides

View File

@ -112,11 +112,8 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
} }
@Provides @Provides
TemplateBuilder provideTemplate(Map<String, ? extends Location> locations, TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes, return template.sizeId("MIRO1B").osFamily(UBUNTU);
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).sizeId("MIRO1B")
.osFamily(UBUNTU);
} }
@Provides @Provides

View File

@ -50,16 +50,19 @@ public class ParseDestroyResponseFromJsonResponse extends ParseJson<List<String>
return cancel_messages; return cancel_messages;
} }
@SuppressWarnings("unused")
public void setCancelMessages(List<String> cancel_messages) { public void setCancelMessages(List<String> cancel_messages) {
this.cancel_messages = cancel_messages; this.cancel_messages = cancel_messages;
} }
} }
@Override @Override
protected List<String> apply(InputStream stream) { protected List<String> apply(InputStream stream) {
Type setType = new TypeToken<Map<String, DestroyResponse>>() { Type setType = new TypeToken<Map<String, DestroyResponse>>() {
}.getType(); }.getType();
try { try {
Map<String, DestroyResponse> responseMap = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType); Map<String, DestroyResponse> responseMap = gson.fromJson(new InputStreamReader(stream,
"UTF-8"), setType);
return responseMap.values().iterator().next().getCancelMessages(); return responseMap.values().iterator().next().getCancelMessages();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e); throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -18,14 +18,6 @@
*/ */
package org.jclouds.rimuhosting.miro.functions; package org.jclouds.rimuhosting.miro.functions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.Image;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -33,10 +25,19 @@ import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.Image;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
/** /**
* @author Ivan Meredith * @author Ivan Meredith
*/ */
@Singleton @Singleton
public class ParseImagesFromJsonResponse extends ParseJson<SortedSet<Image>> { public class ParseImagesFromJsonResponse extends ParseJson<SortedSet<Image>> {
@ -52,6 +53,7 @@ public class ParseImagesFromJsonResponse extends ParseJson<SortedSet<Image>> {
return distro_infos; return distro_infos;
} }
@SuppressWarnings("unused")
public void setDistroInfos(SortedSet<Image> distro_infos) { public void setDistroInfos(SortedSet<Image> distro_infos) {
this.distro_infos = distro_infos; this.distro_infos = distro_infos;
} }
@ -61,7 +63,8 @@ public class ParseImagesFromJsonResponse extends ParseJson<SortedSet<Image>> {
Type setType = new TypeToken<Map<String, DistroResponse>>() { Type setType = new TypeToken<Map<String, DistroResponse>>() {
}.getType(); }.getType();
try { try {
Map<String, DistroResponse> t = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType); Map<String, DistroResponse> t = gson.fromJson(new InputStreamReader(stream, "UTF-8"),
setType);
return t.values().iterator().next().getDistroInfos(); return t.values().iterator().next().getDistroInfos();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e); throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -18,24 +18,25 @@
*/ */
package org.jclouds.rimuhosting.miro.functions; package org.jclouds.rimuhosting.miro.functions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
/** /**
* @author Ivan Meredith * @author Ivan Meredith
*/ */
@Singleton @Singleton
public class ParseInstanceFromJsonResponse extends ParseJson<Server> { public class ParseInstanceFromJsonResponse extends ParseJson<Server> {
@Inject @Inject
@ -45,20 +46,24 @@ public class ParseInstanceFromJsonResponse extends ParseJson<Server> {
private static class OrderResponse extends RimuHostingResponse { private static class OrderResponse extends RimuHostingResponse {
private Server about_order; private Server about_order;
public Server getAboutOrder() { public Server getAboutOrder() {
return about_order; return about_order;
} }
@SuppressWarnings("unused")
public void setAboutOrder(Server about_orders) { public void setAboutOrder(Server about_orders) {
this.about_order = about_orders; this.about_order = about_orders;
} }
} }
@Override @Override
protected Server apply(InputStream stream) { protected Server apply(InputStream stream) {
Type setType = new TypeToken<Map<String, OrderResponse>>() { Type setType = new TypeToken<Map<String, OrderResponse>>() {
}.getType(); }.getType();
try { try {
Map<String, OrderResponse> responseMap = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType); Map<String, OrderResponse> responseMap = gson.fromJson(new InputStreamReader(stream,
"UTF-8"), setType);
return responseMap.values().iterator().next().getAboutOrder(); return responseMap.values().iterator().next().getAboutOrder();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e); throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -18,20 +18,22 @@
*/ */
package org.jclouds.rimuhosting.miro.functions; package org.jclouds.rimuhosting.miro.functions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.ServerInfo;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.ServerInfo;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
/** /**
* @author Ivan Meredith * @author Ivan Meredith
*/ */
@ -49,16 +51,19 @@ public class ParseInstanceInfoFromJsonResponse extends ParseJson<ServerInfo> {
return running_vps_info; return running_vps_info;
} }
@SuppressWarnings("unused")
public void setInstanceInfo(ServerInfo running_vps_info) { public void setInstanceInfo(ServerInfo running_vps_info) {
this.running_vps_info = running_vps_info; this.running_vps_info = running_vps_info;
} }
} }
@Override @Override
protected ServerInfo apply(InputStream stream) { protected ServerInfo apply(InputStream stream) {
Type setType = new TypeToken<Map<String, OrderResponse>>() { Type setType = new TypeToken<Map<String, OrderResponse>>() {
}.getType(); }.getType();
try { try {
Map<String, OrderResponse> responseMap = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType); Map<String, OrderResponse> responseMap = gson.fromJson(new InputStreamReader(stream,
"UTF-8"), setType);
return responseMap.values().iterator().next().getInstanceInfo(); return responseMap.values().iterator().next().getInstanceInfo();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e); throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -18,14 +18,6 @@
*/ */
package org.jclouds.rimuhosting.miro.functions; package org.jclouds.rimuhosting.miro.functions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -33,6 +25,16 @@ import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
/** /**
* @author Ivan Meredith * @author Ivan Meredith
*/ */
@ -45,20 +47,24 @@ public class ParseInstancesFromJsonResponse extends ParseJson<SortedSet<Server>>
private static class OrderResponse extends RimuHostingResponse { private static class OrderResponse extends RimuHostingResponse {
private SortedSet<Server> about_orders; private SortedSet<Server> about_orders;
public SortedSet<Server> getAboutOrders() { public SortedSet<Server> getAboutOrders() {
return about_orders; return about_orders;
} }
@SuppressWarnings("unused")
public void setAboutOrders(SortedSet<Server> about_orders) { public void setAboutOrders(SortedSet<Server> about_orders) {
this.about_orders = about_orders; this.about_orders = about_orders;
} }
} }
@Override @Override
protected SortedSet<Server> apply(InputStream stream) { protected SortedSet<Server> apply(InputStream stream) {
Type setType = new TypeToken<Map<String, OrderResponse>>() { Type setType = new TypeToken<Map<String, OrderResponse>>() {
}.getType(); }.getType();
try { try {
Map<String, OrderResponse> responseMap = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType); Map<String, OrderResponse> responseMap = gson.fromJson(new InputStreamReader(stream,
"UTF-8"), setType);
return responseMap.values().iterator().next().getAboutOrders(); return responseMap.values().iterator().next().getAboutOrders();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e); throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -18,14 +18,6 @@
*/ */
package org.jclouds.rimuhosting.miro.functions; package org.jclouds.rimuhosting.miro.functions;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.PricingPlan;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
@ -33,6 +25,16 @@ import java.lang.reflect.Type;
import java.util.Map; import java.util.Map;
import java.util.SortedSet; import java.util.SortedSet;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.jclouds.http.functions.ParseJson;
import org.jclouds.rimuhosting.miro.domain.PricingPlan;
import org.jclouds.rimuhosting.miro.domain.internal.RimuHostingResponse;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
/** /**
* @author Ivan Meredith * @author Ivan Meredith
*/ */
@ -50,16 +52,19 @@ public class ParsePricingPlansFromJsonResponse extends ParseJson<SortedSet<Prici
return pricing_plan_infos; return pricing_plan_infos;
} }
@SuppressWarnings("unused")
public void setPricingPlanInfos(SortedSet<PricingPlan> pricing_plan_infos) { public void setPricingPlanInfos(SortedSet<PricingPlan> pricing_plan_infos) {
this.pricing_plan_infos = pricing_plan_infos; this.pricing_plan_infos = pricing_plan_infos;
} }
} }
@Override @Override
protected SortedSet<PricingPlan> apply(InputStream stream) { protected SortedSet<PricingPlan> apply(InputStream stream) {
Type setType = new TypeToken<Map<String, PlansResponse>>() { Type setType = new TypeToken<Map<String, PlansResponse>>() {
}.getType(); }.getType();
try { try {
Map<String, PlansResponse> responseMap = gson.fromJson(new InputStreamReader(stream, "UTF-8"), setType); Map<String, PlansResponse> responseMap = gson.fromJson(new InputStreamReader(stream,
"UTF-8"), setType);
return responseMap.values().iterator().next().getPricingPlanInfos(); return responseMap.values().iterator().next().getPricingPlanInfos();
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new RuntimeException("jclouds requires UTF-8 encoding", e); throw new RuntimeException("jclouds requires UTF-8 encoding", e);

View File

@ -1,74 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro;
import com.google.common.base.Predicate;
import org.jclouds.logging.Logger;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.rimuhosting.miro.domain.NewServerResponse;
import org.jclouds.ssh.SshClient.Factory;
import javax.annotation.Resource;
import javax.inject.Inject;
import java.net.InetSocketAddress;
/**
* @author Ivan Meredith
*/
public class RimuHostingComputeClient {
@Resource
protected Logger logger = Logger.NULL;
private final Predicate<InetSocketAddress> socketTester;
private final RimuHostingClient rhClient;
@Inject
public RimuHostingComputeClient(RimuHostingClient rhClient, Factory sshFactory,
Predicate<InetSocketAddress> socketTester) {
this.rhClient = rhClient;
this.sshFactory = sshFactory;
this.socketTester = socketTester;
}
private final Factory sshFactory;
public Long start(String name, String planId, String imageId) {
logger.debug(">> instantiating RimuHosting VPS name(%s) plan(%s) image(%s)", name, planId, imageId);
NewServerResponse serverRespone = rhClient.createServer(name, imageId, planId);
logger.debug(">> VPS id(%d) started and running.", serverRespone.getServer().getId());
return serverRespone.getServer().getId();
}
public void reboot(Long id) {
Server server = rhClient.getServer(id);
logger.debug(">> rebooting VPS(%d)", server.getId());
rhClient.restartServer(id);
logger.debug("<< on VPS(%d)", server.getId());
}
public void destroy(Long id) {
Server server = rhClient.getServer(id);
logger.debug(">> destroy VPS(%d)", server.getId());
rhClient.destroyServer(id);
logger.debug(">> destroyed VPS");
}
}

View File

@ -1,105 +0,0 @@
/**
*
* Copyright (C) 2009 Cloud Conscious, LLC. <info@cloudconscious.com>
*
* ====================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
package org.jclouds.rimuhosting.miro;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.testng.Assert.assertEquals;
import java.io.IOException;
import java.net.InetAddress;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.jclouds.logging.log4j.config.Log4JLoggingModule;
import org.jclouds.predicates.AddressReachable;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rimuhosting.miro.domain.Server;
import org.jclouds.ssh.jsch.config.JschSshClientModule;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provides;
import com.google.inject.TypeLiteral;
/**
* Tests behavior of {@code TerremarkVCloudClient}
*
* @author Adrian Cole
*/
@Test(groups = "live", sequential = true, testName = "rimuhosting.RimuHostingComputeClientLiveTest")
public class RimuHostingComputeClientLiveTest {
RimuHostingComputeClient client;
RimuHostingClient rhClient;
private Long id;
private InetAddress publicIp;
private Predicate<InetAddress> addressTester;
@Test
public void testPowerOn() throws InterruptedException, ExecutionException, TimeoutException,
IOException {
String imageId = "lenny";
String serverName = "test.compute.jclouds.org";
String planId = "MIRO1B";
id = client.start(serverName, planId, imageId);
Server server = rhClient.getServer(id);
assertEquals(imageId, server.getImageId());
assertEquals(serverName, server.getName());
assertEquals(new Integer(160), server.getInstanceParameters().getRam());
}
@AfterTest
void cleanup() throws InterruptedException, ExecutionException, TimeoutException {
if (id != null)
client.destroy(id);
}
@BeforeGroups(groups = { "live" })
public void setupClient() {
String key = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
Injector injector = new RimuHostingContextBuilder(new RimuHostingPropertiesBuilder(key)
.relaxSSLHostname(true).build()).withModules(new Log4JLoggingModule(),
new JschSshClientModule(), new AbstractModule() {
@Override
protected void configure() {
}
@SuppressWarnings("unused")
@Provides
private Predicate<InetAddress> addressTester(AddressReachable reachable) {
return new RetryablePredicate<InetAddress>(reachable, 60, 5, TimeUnit.SECONDS);
}
}).buildInjector();
client = injector.getInstance(RimuHostingComputeClient.class);
rhClient = injector.getInstance(RimuHostingClient.class);
addressTester = injector.getInstance(Key.get(new TypeLiteral<Predicate<InetAddress>>() {
}));
}
}

View File

@ -114,10 +114,8 @@ public class VCloudComputeServiceContextModule extends VCloudContextModule {
} }
@Provides @Provides
protected TemplateBuilder provideTemplate(Map<String, ? extends Location> locations, protected TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes, return template.osFamily(UBUNTU);
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).osFamily(UBUNTU);
} }
@Override @Override

View File

@ -20,19 +20,12 @@ package org.jclouds.vcloud.hostingdotcom.compute.config;
import static org.jclouds.compute.domain.OsFamily.CENTOS; import static org.jclouds.compute.domain.OsFamily.CENTOS;
import java.util.Map;
import org.jclouds.compute.domain.Image;
import org.jclouds.compute.domain.Size;
import org.jclouds.compute.domain.TemplateBuilder; import org.jclouds.compute.domain.TemplateBuilder;
import org.jclouds.compute.internal.TemplateBuilderImpl; import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.domain.Location;
import org.jclouds.vcloud.compute.VCloudComputeClient; import org.jclouds.vcloud.compute.VCloudComputeClient;
import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule; import org.jclouds.vcloud.compute.config.VCloudComputeServiceContextModule;
import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeClient; import org.jclouds.vcloud.hostingdotcom.compute.HostingDotComVCloudComputeClient;
import com.google.inject.Provides;
/** /**
* Configures the {@link HostingDotComVCloudComputeServiceContext}; requires * Configures the {@link HostingDotComVCloudComputeServiceContext}; requires
* {@link HostingDotComVCloudComputeClient} bound. * {@link HostingDotComVCloudComputeClient} bound.
@ -49,11 +42,8 @@ public class HostingDotComVCloudComputeServiceContextModule extends
} }
@Override @Override
@Provides protected TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
protected TemplateBuilder provideTemplate(Map<String, ? extends Location> locations, return template.osFamily(CENTOS);
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes,
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).osFamily(CENTOS);
} }
} }

View File

@ -42,7 +42,6 @@ import org.jclouds.compute.domain.internal.SizeImpl;
import org.jclouds.compute.internal.TemplateBuilderImpl; import org.jclouds.compute.internal.TemplateBuilderImpl;
import org.jclouds.concurrent.ConcurrentUtils; import org.jclouds.concurrent.ConcurrentUtils;
import org.jclouds.domain.Credentials; import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
import org.jclouds.vcloud.VCloudClient; import org.jclouds.vcloud.VCloudClient;
import org.jclouds.vcloud.VCloudMediaType; import org.jclouds.vcloud.VCloudMediaType;
import org.jclouds.vcloud.compute.VCloudComputeClient; import org.jclouds.vcloud.compute.VCloudComputeClient;
@ -63,7 +62,6 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.inject.Provides;
/** /**
* Configures the {@link TerremarkVCloudComputeServiceContext}; requires * Configures the {@link TerremarkVCloudComputeServiceContext}; requires
@ -80,11 +78,8 @@ public class TerremarkVCloudComputeServiceContextModule extends VCloudComputeSer
} }
@Override @Override
@Provides protected TemplateBuilder provideTemplate(TemplateBuilderImpl template) {
protected TemplateBuilder provideTemplate(Map<String, ? extends Location> locations, return template.osFamily(JEOS);
Map<String, ? extends Image> images, Map<String, ? extends Size> sizes,
Location defaultLocation) {
return new TemplateBuilderImpl(locations, images, sizes, defaultLocation).osFamily(JEOS);
} }
private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize(); private static final ComputeOptionsToSize sizeConverter = new ComputeOptionsToSize();