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

@ -65,14 +65,13 @@ public class EC2ComputeServiceLiveTest extends BaseComputeServiceLiveTest {
@Test @Test
public void testScriptExecution() throws Exception { public void testScriptExecution() throws Exception {
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");
} }
@Override @Override

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;
@ -48,18 +47,18 @@ public abstract class ComputeServiceContextBuilder<A, S> extends RestContextBuil
} }
@Override @Override
public Injector buildInjector() { public Injector buildInjector() {
addImageResolutionModuleIfNotPresent(); addImageResolutionModuleIfNotPresent();
return super.buildInjector(); return super.buildInjector();
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
public ComputeServiceContextBuilder<A, S> withModules(Module... modules) { public ComputeServiceContextBuilder<A, S> withModules(Module... modules) {
return (ComputeServiceContextBuilder<A, S>) super.withModules(modules); return (ComputeServiceContextBuilder<A, S>) super.withModules(modules);
} }
public ComputeServiceContext buildComputeServiceContext() { public ComputeServiceContext buildComputeServiceContext() {
@ -70,7 +69,7 @@ public abstract class ComputeServiceContextBuilder<A, S> extends RestContextBuil
} }
protected void addImageResolutionModuleIfNotPresent() { protected void addImageResolutionModuleIfNotPresent() {
if (!Iterables.any(modules, new Predicate<Module>() { if (!Iterables.any(modules, new Predicate<Module>() {
public boolean apply(Module input) { public boolean apply(Module input) {
return input.getClass().isAnnotationPresent(ResolvesImages.class); return input.getClass().isAnnotationPresent(ResolvesImages.class);
} }
@ -80,9 +79,8 @@ 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

@ -93,372 +93,369 @@ import com.google.inject.TypeLiteral;
*/ */
public class GoGridComputeServiceContextModule extends GoGridContextModule { public class GoGridComputeServiceContextModule extends GoGridContextModule {
@Override @Override
protected void configure() { protected void configure() {
super.configure(); super.configure();
bind(new TypeLiteral<Function<Server, NodeMetadata>>() { bind(new TypeLiteral<Function<Server, NodeMetadata>>() {
}).to(ServerToNodeMetadata.class); }).to(ServerToNodeMetadata.class);
bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class); bind(AddNodeWithTagStrategy.class).to(GoGridAddNodeWithTagStrategy.class);
bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class); bind(ListNodesStrategy.class).to(GoGridListNodesStrategy.class);
bind(GetNodeMetadataStrategy.class).to(GoGridGetNodeMetadataStrategy.class); bind(GetNodeMetadataStrategy.class).to(GoGridGetNodeMetadataStrategy.class);
bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class); bind(RebootNodeStrategy.class).to(GoGridRebootNodeStrategy.class);
bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class); bind(DestroyNodeStrategy.class).to(GoGridDestroyNodeStrategy.class);
} }
@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
@Named("NAMING_CONVENTION") @Named("NAMING_CONVENTION")
@Singleton @Singleton
String provideNamingConvention() { String provideNamingConvention() {
return "%s-%d"; return "%s-%d";
} }
@Singleton @Singleton
public static class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy { public static class GoGridAddNodeWithTagStrategy implements AddNodeWithTagStrategy {
private final GoGridClient client; private final GoGridClient client;
private final Function<Size, String> sizeToRam; private final Function<Size, String> sizeToRam;
private final Function<Server, NodeMetadata> serverToNodeMetadata; private final Function<Server, NodeMetadata> serverToNodeMetadata;
private RetryablePredicate<Server> serverLatestJobCompleted; private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<Server> serverLatestJobCompletedShort; private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Inject @Inject
protected GoGridAddNodeWithTagStrategy(GoGridClient client, protected GoGridAddNodeWithTagStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata, Function<Size, String> sizeToRam) { Function<Server, NodeMetadata> serverToNodeMetadata, Function<Size, String> sizeToRam) {
this.client = client; this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata; this.serverToNodeMetadata = serverToNodeMetadata;
this.sizeToRam = sizeToRam; this.sizeToRam = sizeToRam;
this.serverLatestJobCompleted = new RetryablePredicate<Server>( this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS); new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>( this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS); new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
} }
@Override @Override
public NodeMetadata execute(String tag, String name, Template template) { public NodeMetadata execute(String tag, String name, Template template) {
Server addedServer = null; Server addedServer = null;
boolean notStarted = true; boolean notStarted = true;
int numOfRetries = 20; int numOfRetries = 20;
// lock-free consumption of a shared resource: IP address pool // lock-free consumption of a shared resource: IP address pool
while (notStarted) { // TODO: replace with Predicate-based thread collision avoidance for while (notStarted) { // TODO: replace with Predicate-based thread collision avoidance for
// simplicity // simplicity
Set<Ip> availableIps = client.getIpServices().getIpList( Set<Ip> availableIps = client.getIpServices().getIpList(
new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC)); new GetIpListOptions().onlyUnassigned().onlyWithType(IpType.PUBLIC));
if (availableIps.size() == 0) if (availableIps.size() == 0)
throw new RuntimeException("No public IPs available on this account."); throw new RuntimeException("No public IPs available on this account.");
int ipIndex = new SecureRandom().nextInt(availableIps.size()); int ipIndex = new SecureRandom().nextInt(availableIps.size());
Ip availableIp = Iterables.get(availableIps, ipIndex); Ip availableIp = Iterables.get(availableIps, ipIndex);
try {
addedServer = client.getServerServices().addServer(name,
checkNotNull(template.getImage().getId()),
sizeToRam.apply(template.getSize()), availableIp.getIp());
notStarted = false;
} catch (Exception e) {
if (--numOfRetries == 0)
Throwables.propagate(e);
notStarted = true;
}
}
serverLatestJobCompleted.apply(addedServer);
client.getServerServices().power(addedServer.getName(), PowerCommand.START);
serverLatestJobCompletedShort.apply(addedServer);
addedServer = Iterables.getOnlyElement(client.getServerServices().getServersByName(
addedServer.getName()));
return serverToNodeMetadata.apply(addedServer);
}
}
@Singleton
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Inject
protected GoGridRebootNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
serverLatestJobCompleted.apply(server);
client.getServerServices().power(server.getName(), PowerCommand.START);
return serverLatestJobCompletedShort.apply(server);
}
}
@Singleton
public static class GoGridListNodesStrategy implements ListNodesStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected GoGridListNodesStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public Iterable<? extends ComputeMetadata> execute() {
return Iterables.transform(client.getServerServices().getServerList(),
serverToNodeMetadata);
}
}
@Singleton
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected GoGridGetNodeMetadataStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
return server == null ? null : serverToNodeMetadata.apply(server);
}
}
@Singleton
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
@Inject
protected GoGridDestroyNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().deleteByName(server.getName());
return serverLatestJobCompleted.apply(server);
}
}
@Singleton
@Provides
Map<String, NodeState> provideServerToNodeState() {
return ImmutableMap.<String, NodeState> builder().put("On", NodeState.RUNNING).put(
"Starting", NodeState.PENDING).put("Off", NodeState.SUSPENDED).put("Saving",
NodeState.PENDING).put("Restarting", NodeState.PENDING).put("Stopping",
NodeState.PENDING).build();
}
@Singleton
@Provides
Function<String, InetAddress> provideStringIpToInetAddress() {
return new Function<String, InetAddress>() {
@Override
public InetAddress apply(String from) {
try {
return InetAddress.getByName(from);
} catch (UnknownHostException e) {
// TODO: log the failure.
return null;
}
}
};
}
/**
* Finds matches to required configurations. GoGrid's documentation only specifies how much RAM
* one can get with different instance types. The # of cores and disk sizes are purely empyrical
* and aren't guaranteed. However, these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28
* GB Ram: 1GB, CPU: 1 core, HDD: 57 GB Ram: 2GB, CPU: 1 core, HDD: 113 GB Ram: 4GB, CPU: 3
* cores, HDD: 233 GB Ram: 8GB, CPU: 6 cores, HDD: 462 GB (as of March 2010)
*
* @return matched size
*/
@Singleton
@Provides
Function<Size, String> provideSizeToRam() {
return new Function<Size, String>() {
@Override
public String apply(Size size) {
if (size.getRam() >= 8 * 1024 || size.getCores() >= 6 || size.getDisk() >= 450)
return "8GB";
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230)
return "4GB";
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
return "2GB";
if (size.getRam() >= 1024 || size.getDisk() >= 55)
return "1GB";
return "512MB"; /* smallest */
}
};
}
@Singleton
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
private final Map<String, NodeState> serverStateToNodeState;
private final Function<String, InetAddress> stringIpToInetAddress;
private final GoGridClient client;
@SuppressWarnings("unused")
@Inject
ServerToNodeMetadata(Map<String, NodeState> serverStateToNodeState,
Function<String, InetAddress> stringIpToInetAddress, GoGridClient client) {
this.serverStateToNodeState = serverStateToNodeState;
this.stringIpToInetAddress = stringIpToInetAddress;
this.client = client;
}
@Override
public NodeMetadata apply(Server from) {
String locationId = "Unavailable";
String tag = CharMatcher.JAVA_LETTER.retainFrom(from.getName());
Set<InetAddress> ipSet = ImmutableSet
.of(stringIpToInetAddress.apply(from.getIp().getIp()));
NodeState state = serverStateToNodeState.get(from.getState().getName());
Credentials creds = client.getServerServices().getServerCredentialsList().get(
from.getName());
return new NodeMetadataImpl(from.getId() + "", from.getName(), locationId, null,
ImmutableMap.<String, String> of(), tag, state, ipSet, ImmutableList
.<InetAddress> of(), ImmutableMap.<String, String> of(), creds);
}
}
@Provides
@Singleton
ComputeServiceContext provideContext(ComputeService computeService,
RestContext<GoGridAsyncClient, GoGridClient> context) {
return new ComputeServiceContextImpl<GoGridAsyncClient, GoGridClient>(computeService, context);
}
@Provides
@Singleton
@Named("NOT_RUNNING")
protected Predicate<SshClient> runScriptRunning(RunScriptRunning stateRunning) {
return new RetryablePredicate<SshClient>(Predicates.not(stateRunning), 600, 3,
TimeUnit.SECONDS);
}
@Provides
@Singleton
Location getDefaultLocation(Map<String, ? extends Location> locations) {
return locations.get("SANFRANCISCO");
}
@Provides
@Singleton
Map<String, ? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer) {
final Set<Location> locations = Sets.newHashSet();
holder.logger.debug(">> providing locations");
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA", null,
true));
holder.logger.debug("<< locations(%d)", locations.size());
return Maps.uniqueIndex(locations, new Function<Location, String>() {
@Override
public String apply(Location from) {
return from.getId();
}
});
}
@Provides
@Singleton
protected Function<ComputeMetadata, String> indexer() {
return new Function<ComputeMetadata, String>() {
@Override
public String apply(ComputeMetadata from) {
return from.getId();
}
};
}
@Provides
@Singleton
protected Map<String, ? extends Size> provideSizes(GoGridClient sync,
Map<String, ? extends Image> images, LogHolder holder,
Function<ComputeMetadata, String> indexer) throws InterruptedException,
TimeoutException, ExecutionException {
final Set<Size> sizes = Sets.newHashSet();
holder.logger.debug(">> providing sizes");
sizes.add(new SizeImpl("1", "1", null, null, ImmutableMap.<String, String> of(), 1, 512, 28,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("2", "2", null, null, ImmutableMap.<String, String> of(), 1, 1024, 57,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("3", "3", null, null, ImmutableMap.<String, String> of(), 1, 2048,
113, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("4", "4", null, null, ImmutableMap.<String, String> of(), 3, 4096,
233, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("5", "5", null, null, ImmutableMap.<String, String> of(), 6, 8192,
462, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
holder.logger.debug("<< sizes(%d)", sizes.size());
return Maps.uniqueIndex(sizes, indexer);
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)");
@Provides
@Singleton
protected Map<String, ? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer, Location location,
PopulateDefaultLoginCredentialsForImageStrategy authenticator)
throws InterruptedException, ExecutionException, TimeoutException {
final Set<Image> images = Sets.newHashSet();
holder.logger.debug(">> providing images");
Set<ServerImage> allImages = sync.getImageServices().getImageList();
for (ServerImage from : allImages) {
OsFamily os = null;
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from.getDescription()
.indexOf("64") == -1) ? Architecture.X86_32 : Architecture.X86_64;
String osDescription;
String version = "";
osDescription = from.getOs().getName();
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs()
.getName(), GOGRID_OS_NAME_PATTERN, 1);
try { try {
os = OsFamily.fromValue(matchedOs.toLowerCase()); addedServer = client.getServerServices().addServer(name,
} catch (IllegalArgumentException e) { checkNotNull(template.getImage().getId()),
holder.logger.debug("<< didn't match os(%s)", matchedOs); sizeToRam.apply(template.getSize()), availableIp.getIp());
notStarted = false;
} catch (Exception e) {
if (--numOfRetries == 0)
Throwables.propagate(e);
notStarted = true;
} }
Credentials defaultCredentials = authenticator.execute(from); }
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(), location.getId(), serverLatestJobCompleted.apply(addedServer);
null, ImmutableMap.<String, String> of(), from.getDescription(), version, os,
osDescription, arch, defaultCredentials)); client.getServerServices().power(addedServer.getName(), PowerCommand.START);
} serverLatestJobCompletedShort.apply(addedServer);
holder.logger.debug("<< images(%d)", images.size());
return Maps.uniqueIndex(images, indexer); addedServer = Iterables.getOnlyElement(client.getServerServices().getServersByName(
} addedServer.getName()));
return serverToNodeMetadata.apply(addedServer);
}
}
@Singleton
public static class GoGridRebootNodeStrategy implements RebootNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
private RetryablePredicate<Server> serverLatestJobCompletedShort;
@Inject
protected GoGridRebootNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
this.serverLatestJobCompletedShort = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 60, 20, TimeUnit.SECONDS);
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().power(server.getName(), PowerCommand.RESTART);
serverLatestJobCompleted.apply(server);
client.getServerServices().power(server.getName(), PowerCommand.START);
return serverLatestJobCompletedShort.apply(server);
}
}
@Singleton
public static class GoGridListNodesStrategy implements ListNodesStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected GoGridListNodesStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public Iterable<? extends ComputeMetadata> execute() {
return Iterables.transform(client.getServerServices().getServerList(),
serverToNodeMetadata);
}
}
@Singleton
public static class GoGridGetNodeMetadataStrategy implements GetNodeMetadataStrategy {
private final GoGridClient client;
private final Function<Server, NodeMetadata> serverToNodeMetadata;
@Inject
protected GoGridGetNodeMetadataStrategy(GoGridClient client,
Function<Server, NodeMetadata> serverToNodeMetadata) {
this.client = client;
this.serverToNodeMetadata = serverToNodeMetadata;
}
@Override
public NodeMetadata execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
return server == null ? null : serverToNodeMetadata.apply(server);
}
}
@Singleton
public static class GoGridDestroyNodeStrategy implements DestroyNodeStrategy {
private final GoGridClient client;
private RetryablePredicate<Server> serverLatestJobCompleted;
@Inject
protected GoGridDestroyNodeStrategy(GoGridClient client) {
this.client = client;
this.serverLatestJobCompleted = new RetryablePredicate<Server>(
new ServerLatestJobCompleted(client.getJobServices()), 800, 20, TimeUnit.SECONDS);
}
@Override
public boolean execute(ComputeMetadata node) {
Server server = Iterables.getOnlyElement(client.getServerServices().getServersByName(
node.getName()));
client.getServerServices().deleteByName(server.getName());
return serverLatestJobCompleted.apply(server);
}
}
@Singleton
@Provides
Map<String, NodeState> provideServerToNodeState() {
return ImmutableMap.<String, NodeState> builder().put("On", NodeState.RUNNING).put(
"Starting", NodeState.PENDING).put("Off", NodeState.SUSPENDED).put("Saving",
NodeState.PENDING).put("Restarting", NodeState.PENDING).put("Stopping",
NodeState.PENDING).build();
}
@Singleton
@Provides
Function<String, InetAddress> provideStringIpToInetAddress() {
return new Function<String, InetAddress>() {
@Override
public InetAddress apply(String from) {
try {
return InetAddress.getByName(from);
} catch (UnknownHostException e) {
// TODO: log the failure.
return null;
}
}
};
}
/**
* Finds matches to required configurations. GoGrid's documentation only specifies how much RAM
* one can get with different instance types. The # of cores and disk sizes are purely empyrical
* and aren't guaranteed. However, these are the matches found: Ram: 512MB, CPU: 1 core, HDD: 28
* GB Ram: 1GB, CPU: 1 core, HDD: 57 GB Ram: 2GB, CPU: 1 core, HDD: 113 GB Ram: 4GB, CPU: 3
* cores, HDD: 233 GB Ram: 8GB, CPU: 6 cores, HDD: 462 GB (as of March 2010)
*
* @return matched size
*/
@Singleton
@Provides
Function<Size, String> provideSizeToRam() {
return new Function<Size, String>() {
@Override
public String apply(Size size) {
if (size.getRam() >= 8 * 1024 || size.getCores() >= 6 || size.getDisk() >= 450)
return "8GB";
if (size.getRam() >= 4 * 1024 || size.getCores() >= 3 || size.getDisk() >= 230)
return "4GB";
if (size.getRam() >= 2 * 1024 || size.getDisk() >= 110)
return "2GB";
if (size.getRam() >= 1024 || size.getDisk() >= 55)
return "1GB";
return "512MB"; /* smallest */
}
};
}
@Singleton
private static class ServerToNodeMetadata implements Function<Server, NodeMetadata> {
private final Map<String, NodeState> serverStateToNodeState;
private final Function<String, InetAddress> stringIpToInetAddress;
private final GoGridClient client;
@SuppressWarnings("unused")
@Inject
ServerToNodeMetadata(Map<String, NodeState> serverStateToNodeState,
Function<String, InetAddress> stringIpToInetAddress, GoGridClient client) {
this.serverStateToNodeState = serverStateToNodeState;
this.stringIpToInetAddress = stringIpToInetAddress;
this.client = client;
}
@Override
public NodeMetadata apply(Server from) {
String locationId = "Unavailable";
String tag = CharMatcher.JAVA_LETTER.retainFrom(from.getName());
Set<InetAddress> ipSet = ImmutableSet
.of(stringIpToInetAddress.apply(from.getIp().getIp()));
NodeState state = serverStateToNodeState.get(from.getState().getName());
Credentials creds = client.getServerServices().getServerCredentialsList().get(
from.getName());
return new NodeMetadataImpl(from.getId() + "", from.getName(), locationId, null,
ImmutableMap.<String, String> of(), tag, state, ipSet, ImmutableList
.<InetAddress> of(), ImmutableMap.<String, String> of(), creds);
}
}
@Provides
@Singleton
ComputeServiceContext provideContext(ComputeService computeService,
RestContext<GoGridAsyncClient, GoGridClient> context) {
return new ComputeServiceContextImpl<GoGridAsyncClient, GoGridClient>(computeService, context);
}
@Provides
@Singleton
@Named("NOT_RUNNING")
protected Predicate<SshClient> runScriptRunning(RunScriptRunning stateRunning) {
return new RetryablePredicate<SshClient>(Predicates.not(stateRunning), 600, 3,
TimeUnit.SECONDS);
}
@Provides
@Singleton
Location getDefaultLocation(Map<String, ? extends Location> locations) {
return locations.get("SANFRANCISCO");
}
@Provides
@Singleton
Map<String, ? extends Location> getDefaultLocations(GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer) {
final Set<Location> locations = Sets.newHashSet();
holder.logger.debug(">> providing locations");
locations.add(new LocationImpl(LocationScope.ZONE, "SANFRANCISCO", "San Francisco, CA", null,
true));
holder.logger.debug("<< locations(%d)", locations.size());
return Maps.uniqueIndex(locations, new Function<Location, String>() {
@Override
public String apply(Location from) {
return from.getId();
}
});
}
@Provides
@Singleton
protected Function<ComputeMetadata, String> indexer() {
return new Function<ComputeMetadata, String>() {
@Override
public String apply(ComputeMetadata from) {
return from.getId();
}
};
}
@Provides
@Singleton
protected Map<String, ? extends Size> provideSizes(GoGridClient sync,
Map<String, ? extends Image> images, LogHolder holder,
Function<ComputeMetadata, String> indexer) throws InterruptedException,
TimeoutException, ExecutionException {
final Set<Size> sizes = Sets.newHashSet();
holder.logger.debug(">> providing sizes");
sizes.add(new SizeImpl("1", "1", null, null, ImmutableMap.<String, String> of(), 1, 512, 28,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("2", "2", null, null, ImmutableMap.<String, String> of(), 1, 1024, 57,
ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("3", "3", null, null, ImmutableMap.<String, String> of(), 1, 2048,
113, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("4", "4", null, null, ImmutableMap.<String, String> of(), 3, 4096,
233, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
sizes.add(new SizeImpl("5", "5", null, null, ImmutableMap.<String, String> of(), 6, 8192,
462, ImmutableSet.<Architecture> of(Architecture.X86_32, Architecture.X86_64)));
holder.logger.debug("<< sizes(%d)", sizes.size());
return Maps.uniqueIndex(sizes, indexer);
}
private static class LogHolder {
@Resource
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
protected Logger logger = Logger.NULL;
}
public static final Pattern GOGRID_OS_NAME_PATTERN = Pattern.compile("([a-zA-Z]*)(.*)");
@Provides
@Singleton
protected Map<String, ? extends Image> provideImages(final GoGridClient sync, LogHolder holder,
Function<ComputeMetadata, String> indexer, Location location,
PopulateDefaultLoginCredentialsForImageStrategy authenticator)
throws InterruptedException, ExecutionException, TimeoutException {
final Set<Image> images = Sets.newHashSet();
holder.logger.debug(">> providing images");
Set<ServerImage> allImages = sync.getImageServices().getImageList();
for (ServerImage from : allImages) {
OsFamily os = null;
Architecture arch = (from.getOs().getName().indexOf("64") == -1 && from.getDescription()
.indexOf("64") == -1) ? Architecture.X86_32 : Architecture.X86_64;
String osDescription;
String version = "";
osDescription = from.getOs().getName();
String matchedOs = GoGridUtils.parseStringByPatternAndGetNthMatchGroup(from.getOs()
.getName(), GOGRID_OS_NAME_PATTERN, 1);
try {
os = OsFamily.fromValue(matchedOs.toLowerCase());
} catch (IllegalArgumentException e) {
holder.logger.debug("<< didn't match os(%s)", matchedOs);
}
Credentials defaultCredentials = authenticator.execute(from);
images.add(new ImageImpl(from.getId() + "", from.getFriendlyName(), location.getId(),
null, ImmutableMap.<String, String> of(), from.getDescription(), version, os,
osDescription, arch, defaultCredentials));
}
holder.logger.debug("<< images(%d)", images.size());
return Maps.uniqueIndex(images, indexer);
}
} }

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");
queryParameters.put(DESCRIPTION_KEY, description); checkState(!queryParameters.containsKey(DESCRIPTION_KEY),
return this; "Can't have duplicate server description");
} queryParameters.put(DESCRIPTION_KEY, description);
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 asSandboxType() {
public AddServerOptions makeSandboxType() { checkState(!queryParameters.containsKey(IS_SANDBOX_KEY),
checkState(!queryParameters.containsKey(IS_SANDBOX_KEY), "Can only have one sandbox option per server"); "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

@ -28,44 +28,44 @@ package org.jclouds.gogrid.reference;
*/ */
public interface GoGridQueryParams { public interface GoGridQueryParams {
public static final String ID_KEY = "id"; public static final String ID_KEY = "id";
public static final String NAME_KEY = "name"; public static final String NAME_KEY = "name";
public static final String SERVER_ID_OR_NAME_KEY = "server"; public static final String SERVER_ID_OR_NAME_KEY = "server";
public static final String SERVER_TYPE_KEY = "server.type"; public static final String SERVER_TYPE_KEY = "server.type";
public static final String IS_SANDBOX_KEY = "isSandbox"; public static final String IS_SANDBOX_KEY = "isSandbox";
public static final String IMAGE_KEY = "image"; public static final String IMAGE_KEY = "image";
public static final String IP_KEY = "ip"; public static final String IP_KEY = "ip";
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";
public static final String START_DATE_KEY = "startdate"; public static final String START_DATE_KEY = "startdate";
public static final String END_DATE_KEY = "enddate"; public static final String END_DATE_KEY = "enddate";
public static final String OWNER_KEY = "owner"; public static final String OWNER_KEY = "owner";
public static final String JOB_STATE_KEY = "job.state"; public static final String JOB_STATE_KEY = "job.state";
public static final String JOB_OBJECT_TYPE_KEY = "job.objecttype"; public static final String JOB_OBJECT_TYPE_KEY = "job.objecttype";
public static final String OBJECT_KEY = "object"; public static final String OBJECT_KEY = "object";
public static final String IP_STATE_KEY = "ip.state"; public static final String IP_STATE_KEY = "ip.state";
public static final String IP_TYPE_KEY = "ip.type"; public static final String IP_TYPE_KEY = "ip.type";
public static final String LOAD_BALANCER_KEY = "loadbalancer"; public static final String LOAD_BALANCER_KEY = "loadbalancer";
public static final String LOAD_BALANCER_TYPE_KEY = "loadbalancer.type"; public static final String LOAD_BALANCER_TYPE_KEY = "loadbalancer.type";
public static final String LOAD_BALANCER_PERSISTENCE_TYPE_KEY = "loadbalancer.persistence"; public static final String LOAD_BALANCER_PERSISTENCE_TYPE_KEY = "loadbalancer.persistence";
public static final String VIRTUAL_IP_KEY = "virtualip."; public static final String VIRTUAL_IP_KEY = "virtualip.";
public static final String REAL_IP_LIST_KEY = "realiplist."; public static final String REAL_IP_LIST_KEY = "realiplist.";
public static final String IS_PUBLIC_KEY = "isPublic"; public static final String IS_PUBLIC_KEY = "isPublic";
public static final String IMAGE_TYPE_KEY = "image.type"; public static final String IMAGE_TYPE_KEY = "image.type";
public static final String IMAGE_STATE_KEY = "image.state"; public static final String IMAGE_STATE_KEY = "image.state";
public static final String IMAGE_FRIENDLY_NAME_KEY = "friendlyName"; public static final String IMAGE_FRIENDLY_NAME_KEY = "friendlyName";
public static final String IMAGE_DESCRIPTION_KEY = "description"; public static final String IMAGE_DESCRIPTION_KEY = "description";
public static final String LOOKUP_LIST_KEY = "lookup"; public static final String LOOKUP_LIST_KEY = "lookup";
} }

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,297 +74,318 @@ 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;
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>();
@BeforeGroups(groups = { "live" }) @BeforeGroups(groups = { "live" })
public void setupClient() { public void setupClient() {
String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user"); String user = checkNotNull(System.getProperty("jclouds.test.user"), "jclouds.test.user");
String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key"); String password = checkNotNull(System.getProperty("jclouds.test.key"), "jclouds.test.key");
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()), 800, 20,
new LoadBalancerLatestJobCompleted(client.getJobServices()), TimeUnit.SECONDS);
800, 20, TimeUnit.SECONDS); }
}
/** @Test(enabled = false)
* Tests server start, reboot and deletion. public void testDescriptionIs500Characters() {
* Also verifies IP services and job services. final String nameOfServer = "Description" + String.valueOf(new Date().getTime()).substring(6);
*/ serversToDeleteAfterTheTests.add(nameOfServer);
@Test(enabled=true)
public void testServerLifecycle() {
int serverCountBeforeTest = client.getServerServices().getServerList().size();
final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6); Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList();
serversToDeleteAfterTheTests.add(nameOfServer); Ip availableIp = Iterables.getLast(availableIps);
Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList(); String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName();
Ip availableIp = Iterables.getLast(availableIps); StringBuilder builder = new StringBuilder();
String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName(); for (int i = 0; i < 1 * 500; i++)
builder.append('a');
Server createdServer = client.getServerServices().addServer(nameOfServer, String description = builder.toString();
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c",
ram,
availableIp.getIp());
assertNotNull(createdServer);
assert serverLatestJobCompleted.apply(createdServer);
//get server by name Server createdServer = client.getServerServices().addServer(nameOfServer,
Set<Server> response = client.getServerServices().getServersByName(nameOfServer); "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", ram, availableIp.getIp(),
assert (response.size() == 1); new AddServerOptions().withDescription(description));
assertNotNull(createdServer);
assert serverLatestJobCompleted.apply(createdServer);
//restart the server assertEquals(Iterables.getLast(client.getServerServices().getServersByName(nameOfServer))
client.getServerServices().power(nameOfServer, PowerCommand.RESTART); .getDescription(), description);
Set<Job> jobs = client.getJobServices().getJobsForObjectName(nameOfServer); }
assert("RestartVirtualServer".equals(Iterables.getLast(jobs).getCommand().getName()));
assert serverLatestJobCompleted.apply(createdServer); /**
* Tests server start, reboot and deletion. Also verifies IP services and job services.
*/
@Test(enabled = false)
public void testServerLifecycle() {
int serverCountBeforeTest = client.getServerServices().getServerList().size();
int serverCountAfterAddingOneServer = client.getServerServices().getServerList().size(); final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6);
assert serverCountAfterAddingOneServer == serverCountBeforeTest + 1 : serversToDeleteAfterTheTests.add(nameOfServer);
"There should be +1 increase in the number of servers since the test started";
//delete the server Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList();
client.getServerServices().deleteByName(nameOfServer); Ip availableIp = Iterables.getLast(availableIps);
jobs = client.getJobServices().getJobsForObjectName(nameOfServer); String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName();
assert("DeleteVirtualServer".equals(Iterables.getLast(jobs).getCommand().getName()));
assert serverLatestJobCompleted.apply(createdServer); Server createdServer = client.getServerServices().addServer(nameOfServer,
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c", ram, availableIp.getIp());
assertNotNull(createdServer);
assert serverLatestJobCompleted.apply(createdServer);
int serverCountAfterDeletingTheServer = client.getServerServices().getServerList().size(); // get server by name
assert serverCountAfterDeletingTheServer == serverCountBeforeTest : Set<Server> response = client.getServerServices().getServersByName(nameOfServer);
"There should be the same # of servers as since the test started"; assert (response.size() == 1);
//make sure that IP is put back to "unassigned" // restart the server
assert client.getIpServices().getUnassignedIpList().contains(availableIp); client.getServerServices().power(nameOfServer, PowerCommand.RESTART);
}
/** Set<Job> jobs = client.getJobServices().getJobsForObjectName(nameOfServer);
* Starts a servers, verifies that jobs are created correctly and assert ("RestartVirtualServer".equals(Iterables.getLast(jobs).getCommand().getName()));
* an be retrieved from the job services
*/
@Test(dependsOnMethods = "testServerLifecycle", enabled=true)
public void testJobs() {
final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6);
serversToDeleteAfterTheTests.add(nameOfServer);
Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList(); assert serverLatestJobCompleted.apply(createdServer);
String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName(); int serverCountAfterAddingOneServer = client.getServerServices().getServerList().size();
assert serverCountAfterAddingOneServer == serverCountBeforeTest + 1 : "There should be +1 increase in the number of servers since the test started";
Server createdServer = client.getServerServices().addServer(nameOfServer, // delete the server
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c", client.getServerServices().deleteByName(nameOfServer);
ram,
Iterables.getLast(availableIps).getIp());
assert serverLatestJobCompleted.apply(createdServer); jobs = client.getJobServices().getJobsForObjectName(nameOfServer);
assert ("DeleteVirtualServer".equals(Iterables.getLast(jobs).getCommand().getName()));
//restart the server assert serverLatestJobCompleted.apply(createdServer);
client.getServerServices().power(nameOfServer, PowerCommand.RESTART);
Set<Job> jobs = client.getJobServices().getJobsForObjectName(nameOfServer); int serverCountAfterDeletingTheServer = client.getServerServices().getServerList().size();
assert serverCountAfterDeletingTheServer == serverCountBeforeTest : "There should be the same # of servers as since the test started";
Job latestJob = Iterables.getLast(jobs); // make sure that IP is put back to "unassigned"
Long latestJobId = latestJob.getId(); assert client.getIpServices().getUnassignedIpList().contains(availableIp);
}
Job latestJobFetched = Iterables.getOnlyElement(client.getJobServices().getJobsById(latestJobId)); /**
* Starts a servers, verifies that jobs are created correctly and an be retrieved from the job
* services
*/
@Test(dependsOnMethods = "testServerLifecycle", enabled = false)
public void testJobs() {
final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6);
serversToDeleteAfterTheTests.add(nameOfServer);
assert latestJob.equals(latestJobFetched) : "Job and its reprentation found by ID don't match"; Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList();
List<Long> idsOfAllJobs = new ArrayList<Long>(); String ram = Iterables.get(client.getServerServices().getRamSizes(), 0).getName();
for(Job job : jobs) {
idsOfAllJobs.add(job.getId());
}
Set<Job> jobsFetched = client.getJobServices().getJobsById(idsOfAllJobs.toArray(new Long[jobs.size()])); Server createdServer = client.getServerServices().addServer(nameOfServer,
assert jobsFetched.size() == jobs.size() : format("Number of jobs fetched by ids doesn't match the number of jobs " + "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", ram,
"requested. Requested/expected: %d. Found: %d.", Iterables.getLast(availableIps).getIp());
jobs.size(), jobsFetched.size());
//delete the server assert serverLatestJobCompleted.apply(createdServer);
client.getServerServices().deleteByName(nameOfServer);
}
// restart the server
client.getServerServices().power(nameOfServer, PowerCommand.RESTART);
/** Set<Job> jobs = client.getJobServices().getJobsForObjectName(nameOfServer);
* Tests common load balancer operations.
* Also verifies IP services and job services.
*/
@Test(enabled=true)
public void testLoadBalancerLifecycle() {
int lbCountBeforeTest = client.getLoadBalancerServices().getLoadBalancerList().size();
final String nameOfLoadBalancer = "LoadBalancer" + String.valueOf(new Date().getTime()).substring(6); Job latestJob = Iterables.getLast(jobs);
loadBalancersToDeleteAfterTest.add(nameOfLoadBalancer); Long latestJobId = latestJob.getId();
Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList(); Job latestJobFetched = Iterables.getOnlyElement(client.getJobServices().getJobsById(
latestJobId));
if(availableIps.size() < 4) throw new SkipException("Not enough available IPs (4 needed) to run the test"); assert latestJob.equals(latestJobFetched) : "Job and its reprentation found by ID don't match";
Iterator<Ip> ipIterator = availableIps.iterator();
Ip vip = ipIterator.next();
Ip realIp1 = ipIterator.next();
Ip realIp2 = ipIterator.next();
Ip realIp3 = ipIterator.next();
AddLoadBalancerOptions options = new AddLoadBalancerOptions.Builder(). List<Long> idsOfAllJobs = new ArrayList<Long>();
create(LoadBalancerType.LEAST_CONNECTED, LoadBalancerPersistenceType.SOURCE_ADDRESS); for (Job job : jobs) {
LoadBalancer createdLoadBalancer = client.getLoadBalancerServices(). idsOfAllJobs.add(job.getId());
addLoadBalancer(nameOfLoadBalancer, new IpPortPair(vip, 80), }
Arrays.asList(new IpPortPair(realIp1, 80),
new IpPortPair(realIp2, 80)), options);
assertNotNull(createdLoadBalancer);
assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer);
//get load balancer by name Set<Job> jobsFetched = client.getJobServices().getJobsById(
Set<LoadBalancer> response = client.getLoadBalancerServices().getLoadBalancersByName(nameOfLoadBalancer); idsOfAllJobs.toArray(new Long[jobs.size()]));
assert (response.size() == 1); assert jobsFetched.size() == jobs.size() : format(
createdLoadBalancer = Iterables.getOnlyElement(response); "Number of jobs fetched by ids doesn't match the number of jobs "
assertNotNull(createdLoadBalancer.getRealIpList()); + "requested. Requested/expected: %d. Found: %d.", jobs.size(), jobsFetched
assertEquals(createdLoadBalancer.getRealIpList().size(), 2); .size());
assertNotNull(createdLoadBalancer.getVirtualIp());
assertEquals(createdLoadBalancer.getVirtualIp().getIp().getIp(), vip.getIp());
LoadBalancer editedLoadBalancer = client.getLoadBalancerServices(). // delete the server
editLoadBalancer(nameOfLoadBalancer, Arrays.asList(new IpPortPair(realIp3, 8181))); client.getServerServices().deleteByName(nameOfServer);
assert loadBalancerLatestJobCompleted.apply(editedLoadBalancer); }
assertNotNull(editedLoadBalancer.getRealIpList());
assertEquals(editedLoadBalancer.getRealIpList().size(), 1);
assertEquals(Iterables.getOnlyElement(editedLoadBalancer.getRealIpList()).getIp().getIp(), realIp3.getIp());
int lbCountAfterAddingOneServer = client.getLoadBalancerServices().getLoadBalancerList().size(); /**
assert lbCountAfterAddingOneServer == lbCountBeforeTest + 1 : * Tests common load balancer operations. Also verifies IP services and job services.
"There should be +1 increase in the number of load balancers since the test started"; */
@Test(enabled = false)
public void testLoadBalancerLifecycle() {
int lbCountBeforeTest = client.getLoadBalancerServices().getLoadBalancerList().size();
//delete the load balancer final String nameOfLoadBalancer = "LoadBalancer"
client.getLoadBalancerServices().deleteByName(nameOfLoadBalancer); + String.valueOf(new Date().getTime()).substring(6);
loadBalancersToDeleteAfterTest.add(nameOfLoadBalancer);
Set<Job> jobs = client.getJobServices().getJobsForObjectName(nameOfLoadBalancer); Set<Ip> availableIps = client.getIpServices().getUnassignedPublicIpList();
assert("DeleteLoadBalancer".equals(Iterables.getLast(jobs).getCommand().getName()));
assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer); if (availableIps.size() < 4)
throw new SkipException("Not enough available IPs (4 needed) to run the test");
Iterator<Ip> ipIterator = availableIps.iterator();
Ip vip = ipIterator.next();
Ip realIp1 = ipIterator.next();
Ip realIp2 = ipIterator.next();
Ip realIp3 = ipIterator.next();
int lbCountAfterDeletingTheServer = client.getLoadBalancerServices().getLoadBalancerList().size(); AddLoadBalancerOptions options = new AddLoadBalancerOptions.Builder().create(
assert lbCountAfterDeletingTheServer == lbCountBeforeTest : LoadBalancerType.LEAST_CONNECTED, LoadBalancerPersistenceType.SOURCE_ADDRESS);
"There should be the same # of load balancers as since the test started"; LoadBalancer createdLoadBalancer = client.getLoadBalancerServices().addLoadBalancer(
} nameOfLoadBalancer, new IpPortPair(vip, 80),
Arrays.asList(new IpPortPair(realIp1, 80), new IpPortPair(realIp2, 80)), options);
assertNotNull(createdLoadBalancer);
assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer);
/** // get load balancer by name
* Tests common server image operations. Set<LoadBalancer> response = client.getLoadBalancerServices().getLoadBalancersByName(
*/ nameOfLoadBalancer);
@Test(enabled=true) assert (response.size() == 1);
public void testImageLifecycle() { createdLoadBalancer = Iterables.getOnlyElement(response);
GetImageListOptions options = new GetImageListOptions.Builder().publicDatabaseServers(); assertNotNull(createdLoadBalancer.getRealIpList());
Set<ServerImage> images = client.getImageServices().getImageList(options); assertEquals(createdLoadBalancer.getRealIpList().size(), 2);
assertNotNull(createdLoadBalancer.getVirtualIp());
assertEquals(createdLoadBalancer.getVirtualIp().getIp().getIp(), vip.getIp());
Predicate<ServerImage> isDatabaseServer = new Predicate<ServerImage>() { LoadBalancer editedLoadBalancer = client.getLoadBalancerServices().editLoadBalancer(
@Override nameOfLoadBalancer, Arrays.asList(new IpPortPair(realIp3, 8181)));
public boolean apply(@Nullable ServerImage serverImage) { assert loadBalancerLatestJobCompleted.apply(editedLoadBalancer);
return checkNotNull(serverImage).getType() == ServerImageType.DATABASE_SERVER; assertNotNull(editedLoadBalancer.getRealIpList());
} assertEquals(editedLoadBalancer.getRealIpList().size(), 1);
}; assertEquals(Iterables.getOnlyElement(editedLoadBalancer.getRealIpList()).getIp().getIp(),
realIp3.getIp());
assert Iterables.all(images, isDatabaseServer) : "All of the images should've been of database type"; int lbCountAfterAddingOneServer = client.getLoadBalancerServices().getLoadBalancerList()
.size();
assert lbCountAfterAddingOneServer == lbCountBeforeTest + 1 : "There should be +1 increase in the number of load balancers since the test started";
ServerImage image = Iterables.getLast(images); // delete the load balancer
ServerImage imageFromServer = Iterables.getOnlyElement( client.getLoadBalancerServices().deleteByName(nameOfLoadBalancer);
client.getImageServices().getImagesByName(image.getName()));
assertEquals(image, imageFromServer);
try { Set<Job> jobs = client.getJobServices().getJobsForObjectName(nameOfLoadBalancer);
client.getImageServices().editImageDescription(image.getName(), "newDescription"); assert ("DeleteLoadBalancer".equals(Iterables.getLast(jobs).getCommand().getName()));
throw new TestException("An exception hasn't been thrown where expected; expected GoGridResponseException");
} catch(GoGridResponseException e) {
//expected situation - check and proceed
assertTrue(e.getMessage().contains("GoGridIllegalArgumentException"));
}
} assert loadBalancerLatestJobCompleted.apply(createdLoadBalancer);
@Test(enabled=true) int lbCountAfterDeletingTheServer = client.getLoadBalancerServices().getLoadBalancerList()
public void testShellAccess() throws IOException { .size();
final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6); assert lbCountAfterDeletingTheServer == lbCountBeforeTest : "There should be the same # of load balancers as since the test started";
serversToDeleteAfterTheTests.add(nameOfServer); }
Set<Ip> availableIps = client.getIpServices().getUnassignedIpList(); /**
Ip availableIp = Iterables.getLast(availableIps); * Tests common server image operations.
*/
@Test(enabled = false)
public void testImageLifecycle() {
GetImageListOptions options = new GetImageListOptions.Builder().publicDatabaseServers();
Set<ServerImage> images = client.getImageServices().getImageList(options);
Server createdServer = client.getServerServices().addServer(nameOfServer, Predicate<ServerImage> isDatabaseServer = new Predicate<ServerImage>() {
"GSI-f8979644-e646-4711-ad58-d98a5fa3612c", @Override
"1", public boolean apply(@Nullable ServerImage serverImage) {
availableIp.getIp()); return checkNotNull(serverImage).getType() == ServerImageType.DATABASE_SERVER;
assertNotNull(createdServer); }
assert serverLatestJobCompleted.apply(createdServer); };
//get server by name assert Iterables.all(images, isDatabaseServer) : "All of the images should've been of database type";
Set<Server> response = client.getServerServices().getServersByName(nameOfServer);
assert (response.size() == 1);
createdServer = Iterables.getOnlyElement(response);
Map<String, Credentials> credsMap = client.getServerServices().getServerCredentialsList(); ServerImage image = Iterables.getLast(images);
Credentials instanceCredentials = credsMap.get(createdServer.getName()); ServerImage imageFromServer = Iterables.getOnlyElement(client.getImageServices()
assertNotNull(instanceCredentials); .getImagesByName(image.getName()));
assertEquals(image, imageFromServer);
InetSocketAddress socket = new InetSocketAddress(InetAddress.getByName(createdServer.getIp().getIp()), 22); try {
client.getImageServices().editImageDescription(image.getName(), "newDescription");
throw new TestException(
"An exception hasn't been thrown where expected; expected GoGridResponseException");
} catch (GoGridResponseException e) {
// expected situation - check and proceed
assertTrue(e.getMessage().contains("GoGridIllegalArgumentException"));
}
Predicate<InetSocketAddress> socketOpen = }
new RetryablePredicate<InetSocketAddress>(new SocketOpen(), 180, 5, TimeUnit.SECONDS);
socketOpen.apply(socket); @Test(enabled = false)
public void testShellAccess() throws IOException {
final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6);
serversToDeleteAfterTheTests.add(nameOfServer);
SshClient sshClient = Set<Ip> availableIps = client.getIpServices().getUnassignedIpList();
new JschSshClient(socket, 60000, Ip availableIp = Iterables.getLast(availableIps);
instanceCredentials.account, instanceCredentials.key);
sshClient.connect();
String output = sshClient.exec("df").getOutput();
assertTrue(output.contains("Filesystem"),
"The output should've contained filesystem information, but it didn't. Output: " + output);
sshClient.disconnect();
//delete the server Server createdServer = client.getServerServices().addServer(nameOfServer,
client.getServerServices().deleteByName(nameOfServer); "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", "1", availableIp.getIp());
} assertNotNull(createdServer);
assert serverLatestJobCompleted.apply(createdServer);
/** // get server by name
* In case anything went wrong during the tests, removes the objects Set<Server> response = client.getServerServices().getServersByName(nameOfServer);
* created in the tests. assert (response.size() == 1);
*/ createdServer = Iterables.getOnlyElement(response);
@AfterTest
public void cleanup() {
for(String serverName : serversToDeleteAfterTheTests) {
try {
client.getServerServices().deleteByName(serverName);
} catch(Exception e) {
// it's already been deleted - proceed
}
}
for(String loadBalancerName : loadBalancersToDeleteAfterTest) {
try {
client.getLoadBalancerServices().deleteByName(loadBalancerName);
} catch(Exception e) {
// it's already been deleted - proceed
}
}
} Map<String, Credentials> credsMap = client.getServerServices().getServerCredentialsList();
Credentials instanceCredentials = credsMap.get(createdServer.getName());
assertNotNull(instanceCredentials);
InetSocketAddress socket = new InetSocketAddress(InetAddress.getByName(createdServer.getIp()
.getIp()), 22);
Predicate<InetSocketAddress> socketOpen = new RetryablePredicate<InetSocketAddress>(
new SocketOpen(), 180, 5, TimeUnit.SECONDS);
socketOpen.apply(socket);
SshClient sshClient = new JschSshClient(socket, 60000, instanceCredentials.account,
instanceCredentials.key);
sshClient.connect();
String output = sshClient.exec("df").getOutput();
assertTrue(output.contains("Filesystem"),
"The output should've contained filesystem information, but it didn't. Output: "
+ output);
sshClient.disconnect();
// delete the server
client.getServerServices().deleteByName(nameOfServer);
}
/**
* In case anything went wrong during the tests, removes the objects created in the tests.
*/
@AfterTest
public void cleanup() {
for (String serverName : serversToDeleteAfterTheTests) {
try {
client.getServerServices().deleteByName(serverName);
} catch (Exception e) {
// it's already been deleted - proceed
}
}
for (String loadBalancerName : loadBalancersToDeleteAfterTest) {
try {
client.getLoadBalancerServices().deleteByName(loadBalancerName);
} catch (Exception e) {
// it's already been deleted - proceed
}
}
}
} }

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;
@ -82,265 +81,271 @@ import com.google.inject.TypeLiteral;
@Test(groups = "unit", testName = "gogrid.GoGridAsyncClientTest") @Test(groups = "unit", testName = "gogrid.GoGridAsyncClientTest")
public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncClient> { public class GridServerAsyncClientTest extends RestClientTest<GridServerAsyncClient> {
@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",
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method); GetServerListOptions[].class);
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,
assertHeadersEqual(httpRequest, ""); "GET https://api.gogrid.com/api/grid/server/list?v=1.3 HTTP/1.1");
assertPayloadEquals(httpRequest, null); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class); assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
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 " + assertHeadersEqual(httpRequest, "");
"HTTP/1.1"); assertPayloadEquals(httpRequest, null);
assertHeadersEqual(httpRequest, ""); }
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",
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method, GetServerListOptions[].class);
new GetServerListOptions.Builder().onlySandboxServers()); GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
new GetServerListOptions.Builder().onlySandboxServers());
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/list?v=1.3&isSandbox=true HTTP/1.1"); "GET https://api.gogrid.com/api/grid/server/list?v=1.3&isSandbox=true HTTP/1.1");
assertHeadersEqual(httpRequest, ""); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null); assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class); assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
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
public void testGetServersByName() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("getServersByName", String[].class);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
"server1");
@Test assertRequestLineEquals(httpRequest,
public void testGetServersByName() throws NoSuchMethodException, IOException { "GET https://api.gogrid.com/api/grid/server/get?v=1.3&name=server1 HTTP/1.1");
Method method = GridServerAsyncClient.class.getMethod("getServersByName", String[].class); assertHeadersEqual(httpRequest, "");
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method, "server1"); assertPayloadEquals(httpRequest, null);
assertRequestLineEquals(httpRequest, assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class);
"GET https://api.gogrid.com/api/grid/server/get?v=1.3&name=server1 HTTP/1.1"); assertSaxResponseParserClassEquals(method, null);
assertHeadersEqual(httpRequest, ""); assertExceptionParserClassEquals(method, null);
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class); checkFilters(httpRequest);
assertSaxResponseParserClassEquals(method, null); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest); assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/get?"
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); + "v=1.3&name=server1&" + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo "
+ "HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
assertRequestLineEquals(httpRequest, @Test
"GET https://api.gogrid.com/api/grid/server/get?" + public void testGetServersById() throws NoSuchMethodException, IOException {
"v=1.3&name=server1&" + Method method = GridServerAsyncClient.class.getMethod("getServersById", Long[].class);
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
"HTTP/1.1"); 123L);
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/get?v=1.3&id=123 HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
@Test assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class);
public void testGetServersById() throws NoSuchMethodException, IOException { assertSaxResponseParserClassEquals(method, null);
Method method = GridServerAsyncClient.class.getMethod("getServersById", Long[].class); assertExceptionParserClassEquals(method, null);
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method, 123L);
assertRequestLineEquals(httpRequest, checkFilters(httpRequest);
"GET https://api.gogrid.com/api/grid/server/get?v=1.3&id=123 HTTP/1.1"); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseServerListFromJsonResponse.class); assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/get?"
assertSaxResponseParserClassEquals(method, null); + "v=1.3&id=123&" + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
assertExceptionParserClassEquals(method, null); assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
checkFilters(httpRequest); @Test
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); public void testAddServerNoOptions() 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");
assertRequestLineEquals(httpRequest, assertRequestLineEquals(httpRequest, "GET https://api.gogrid.com/api/grid/server/add?v=1.3&"
"GET https://api.gogrid.com/api/grid/server/get?" + + "name=serverName&server.ram=memory&image=img55&ip=127.0.0.1 " + "HTTP/1.1");
"v=1.3&id=123&" + assertHeadersEqual(httpRequest, "");
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + assertPayloadEquals(httpRequest, null);
"HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class);
assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
@Test checkFilters(httpRequest);
public void testAddServerNoOptions() throws NoSuchMethodException, IOException { Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
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");
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&" + + "v=1.3&name=serverName&server.ram=memory&" + "image=img55&ip=127.0.0.1&"
"name=serverName&server.ram=memory&image=img55&ip=127.0.0.1 " + + "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
"HTTP/1.1"); assertHeadersEqual(httpRequest, "");
assertHeadersEqual(httpRequest, ""); assertPayloadEquals(httpRequest, null);
assertPayloadEquals(httpRequest, null); }
assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class); @Test
assertSaxResponseParserClassEquals(method, null); public void testAddServerOptions() throws NoSuchMethodException, IOException {
assertExceptionParserClassEquals(method, null); 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"));
checkFilters(httpRequest); assertRequestLineEquals(
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); 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);
assertRequestLineEquals(httpRequest, assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class);
"GET https://api.gogrid.com/api/grid/server/add?" + assertSaxResponseParserClassEquals(method, null);
"v=1.3&name=serverName&server.ram=memory&" + assertExceptionParserClassEquals(method, null);
"image=img55&ip=127.0.0.1&" +
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
checkFilters(httpRequest);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
@Test assertRequestLineEquals(
public void testPowerServer() throws NoSuchMethodException, IOException { httpRequest,
Method method = GridServerAsyncClient.class.getMethod("power", String.class, PowerCommand.class); "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");
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = assertHeadersEqual(httpRequest, "");
processor.createRequest(method, "PowerServer", PowerCommand.RESTART); assertPayloadEquals(httpRequest, null);
}
assertRequestLineEquals(httpRequest, @Test
"GET https://api.gogrid.com/api/grid/server/power?v=1.3&" + public void testPowerServer() throws NoSuchMethodException, IOException {
"server=PowerServer&power=restart " + Method method = GridServerAsyncClient.class.getMethod("power", String.class,
"HTTP/1.1"); PowerCommand.class);
assertHeadersEqual(httpRequest, ""); GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method,
assertPayloadEquals(httpRequest, null); "PowerServer", PowerCommand.RESTART);
assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class); assertRequestLineEquals(httpRequest,
assertSaxResponseParserClassEquals(method, null); "GET https://api.gogrid.com/api/grid/server/power?v=1.3&"
assertExceptionParserClassEquals(method, null); + "server=PowerServer&power=restart " + "HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
checkFilters(httpRequest); assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class);
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null);
assertRequestLineEquals(httpRequest, checkFilters(httpRequest);
"GET https://api.gogrid.com/api/grid/server/power?v=1.3&" + Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
"server=PowerServer&power=restart&" +
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " +
"HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
assertRequestLineEquals(httpRequest,
"GET https://api.gogrid.com/api/grid/server/power?v=1.3&"
+ "server=PowerServer&power=restart&"
+ "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
assertHeadersEqual(httpRequest, "");
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);
assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class); assertResponseParserClassEquals(method, httpRequest, ParseServerFromJsonResponse.class);
assertSaxResponseParserClassEquals(method, null); assertSaxResponseParserClassEquals(method, null);
assertExceptionParserClassEquals(method, null); assertExceptionParserClassEquals(method, null);
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/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 " + assertHeadersEqual(httpRequest, "");
"HTTP/1.1"); assertPayloadEquals(httpRequest, null);
assertHeadersEqual(httpRequest, ""); }
assertPayloadEquals(httpRequest, null);
}
@Test
public void testGetRamSizes() throws NoSuchMethodException, IOException {
Method method = GridServerAsyncClient.class.getMethod("getRamSizes");
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = processor.createRequest(method);
@Test assertRequestLineEquals(httpRequest,
public void testGetRamSizes() throws NoSuchMethodException, IOException { "GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram "
Method method = GridServerAsyncClient.class.getMethod("getRamSizes"); + "HTTP/1.1");
GeneratedHttpRequest<GridServerAsyncClient> httpRequest = assertHeadersEqual(httpRequest, "");
processor.createRequest(method); assertPayloadEquals(httpRequest, null);
assertRequestLineEquals(httpRequest, assertResponseParserClassEquals(method, httpRequest, ParseOptionsFromJsonResponse.class);
"GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram " + assertSaxResponseParserClassEquals(method, null);
"HTTP/1.1"); assertExceptionParserClassEquals(method, null);
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
assertResponseParserClassEquals(method, httpRequest, ParseOptionsFromJsonResponse.class); checkFilters(httpRequest);
assertSaxResponseParserClassEquals(method, null); Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest);
assertExceptionParserClassEquals(method, null);
checkFilters(httpRequest); assertRequestLineEquals(httpRequest,
Iterables.getOnlyElement(httpRequest.getFilters()).filter(httpRequest); "GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram&"
+ "sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + "HTTP/1.1");
assertHeadersEqual(httpRequest, "");
assertPayloadEquals(httpRequest, null);
}
assertRequestLineEquals(httpRequest, @Override
"GET https://api.gogrid.com/api/common/lookup/list?v=1.3&lookup=server.ram&" + protected void checkFilters(GeneratedHttpRequest<GridServerAsyncClient> httpMethod) {
"sig=3f446f171455fbb5574aecff4997b273&api_key=foo " + assertEquals(httpMethod.getFilters().size(), 1);
"HTTP/1.1"); assertEquals(httpMethod.getFilters().get(0).getClass(), SharedKeyLiteAuthentication.class);
assertHeadersEqual(httpRequest, ""); }
assertPayloadEquals(httpRequest, null);
}
@Override
protected TypeLiteral<RestAnnotationProcessor<GridServerAsyncClient>> createTypeLiteral() {
return new TypeLiteral<RestAnnotationProcessor<GridServerAsyncClient>>() {
};
}
@Override @Override
protected void checkFilters(GeneratedHttpRequest<GridServerAsyncClient> httpMethod) { protected Module createModule() {
assertEquals(httpMethod.getFilters().size(), 1); return new AbstractModule() {
assertEquals(httpMethod.getFilters().get(0).getClass(), SharedKeyLiteAuthentication.class); @Override
} protected void configure() {
bind(URI.class).annotatedWith(GoGrid.class).toInstance(
URI.create("https://api.gogrid.com/api"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
}
@Override @SuppressWarnings("unused")
protected TypeLiteral<RestAnnotationProcessor<GridServerAsyncClient>> createTypeLiteral() { @Provides
return new TypeLiteral<RestAnnotationProcessor<GridServerAsyncClient>>() { @Singleton
}; public SharedKeyLiteAuthentication provideAuthentication(
} EncryptionService encryptionService) throws UnsupportedEncodingException {
return new SharedKeyLiteAuthentication("foo", "bar", 1267243795L, encryptionService);
@Override }
protected Module createModule() { };
return new AbstractModule() { }
@Override
protected void configure() {
bind(URI.class).annotatedWith(GoGrid.class).toInstance(
URI.create("https://api.gogrid.com/api"));
bind(Logger.LoggerFactory.class).toInstance(new LoggerFactory() {
public Logger getLogger(String category) {
return Logger.NULL;
}
});
}
@Provides
@Singleton
public SharedKeyLiteAuthentication provideAuthentication(EncryptionService encryptionService)
throws UnsupportedEncodingException {
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
@ -417,7 +414,7 @@ public class RimuHostingComputeServiceContextModule extends RimuHostingContextMo
images.add(new ImageImpl(from.getId(), from.getDescription(), null, null, ImmutableMap images.add(new ImageImpl(from.getId(), from.getDescription(), null, null, ImmutableMap
.<String, String> of(), from.getDescription(), version, os, osDescription, arch, .<String, String> of(), from.getDescription(), version, os, osDescription, arch,
new Credentials("root", null))); new Credentials("root", null)));
} }
holder.logger.debug("<< images(%d)", images.size()); holder.logger.debug("<< images(%d)", images.size());
return Maps.uniqueIndex(images, indexer); return Maps.uniqueIndex(images, indexer);

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();