diff --git a/apis/atmos/pom.xml b/apis/atmos/pom.xml index 1d905ff05b..d55db0e29e 100644 --- a/apis/atmos/pom.xml +++ b/apis/atmos/pom.xml @@ -2,7 +2,7 @@ @@ -141,4 +142,21 @@ + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.deltacloud.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/apis/ec2/pom.xml b/apis/ec2/pom.xml index 107b73ef27..c7f44d4125 100644 --- a/apis/ec2/pom.xml +++ b/apis/ec2/pom.xml @@ -33,6 +33,7 @@ ec2 jcloud ec2 api jclouds components to access an implementation of EC2 + bundle @@ -142,6 +143,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.ec2.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/apis/ec2/src/main/clojure/org/jclouds/ec2/ebs.clj b/apis/ec2/src/main/clojure/org/jclouds/ec2/ebs.clj index 62a172c939..05203bef12 100644 --- a/apis/ec2/src/main/clojure/org/jclouds/ec2/ebs.clj +++ b/apis/ec2/src/main/clojure/org/jclouds/ec2/ebs.clj @@ -25,20 +25,20 @@ (:use (clojure.contrib def core)) (:import org.jclouds.aws.domain.Region org.jclouds.compute.domain.NodeMetadata - (org.jclouds.aws.ec2.domain Volume Volume$Status Snapshot Snapshot$Status AvailabilityZone) - (org.jclouds.aws.ec2.options DescribeSnapshotsOptions DetachVolumeOptions CreateSnapshotOptions))) + (org.jclouds.ec2.domain Volume Volume$Status Snapshot Snapshot$Status AvailabilityZoneInfo) + (org.jclouds.ec2.options DescribeSnapshotsOptions DetachVolumeOptions CreateSnapshotOptions))) (defn snapshot? - "Returns true iff the argument is a org.jclouds.aws.ec2.domain.Snapshot." + "Returns true iff the argument is a org.jclouds.ec2.domain.Snapshot." [s] (instance? Snapshot s)) (defn volume? - "Returns true iff the argument is a org.jclouds.aws.ec2.domain.Volume." + "Returns true iff the argument is a org.jclouds.ec2.domain.Volume." [v] (instance? Volume v)) -(defn #^org.jclouds.aws.ec2.services.ElasticBlockStoreClient +(defn #^org.jclouds.ec2.services.ElasticBlockStoreClient ebs-service "Returns the synchronous ElasticBlockStoreClient associated with the specified compute service, or compute/*compute* as bound by with-compute-service." @@ -74,7 +74,7 @@ (str "Can't obtain volume id from argument of type " (class v)))))) (defn volumes - "Returns a set of org.jclouds.aws.ec2.domain.Volume instances corresponding to the + "Returns a set of org.jclouds.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] (volumes)) @@ -172,7 +172,7 @@ (defn get-zone [v] (cond - (instance? AvailabilityZone v) v + (instance? AvailabilityZoneInfo v) (.getZone v) (instance? NodeMetadata v) (compute/location #^NodeMetadata v) (string? v) v (keyword? v) (name v) @@ -225,14 +225,14 @@ (defn create-volume "Creates a new volume given a set of options: - - one of :zone (keyword, string, or AvailabilityZone) or :node (NodeMetadata) + - one of :zone (keyword, string, or AvailabilityZoneInfo) or :node (NodeMetadata) - one or both of :snapshot (keyword, string, or Snapshot instance) or :size (string, keyword, or number) - :device (string or keyword) provided *only* when you want to attach the new volume to the :node you specified! - Returns a vector of [created org.jclouds.aws.ec2.domain.Volume, - optional org.jclouds.aws.ec2.domain.Attachment] + Returns a vector of [created org.jclouds.ec2.domain.Volume, + optional org.jclouds.ec2.domain.Attachment] Note that specifying :node instead of :zone will only attach the created volume :device is also provided. Otherwise, the node is only used to obtain the desired diff --git a/apis/ec2/src/main/clojure/org/jclouds/ec2/elastic_ip.clj b/apis/ec2/src/main/clojure/org/jclouds/ec2/elastic_ip.clj index 003f3a99fb..cd1a70a616 100644 --- a/apis/ec2/src/main/clojure/org/jclouds/ec2/elastic_ip.clj +++ b/apis/ec2/src/main/clojure/org/jclouds/ec2/elastic_ip.clj @@ -22,12 +22,12 @@ :doc "A clojure binding for the jclouds AWS elastic IP address interface."} org.jclouds.ec2.elastic-ip (:require (org.jclouds [compute :as compute]) - [org.jclouds.aws.ebs :as ebs]) + [org.jclouds.ec2.ebs :as ebs]) (:use (clojure.contrib def core)) (:import org.jclouds.compute.domain.NodeMetadata - (org.jclouds.aws.ec2.domain PublicIpInstanceIdPair))) + (org.jclouds.ec2.domain PublicIpInstanceIdPair))) -(defn #^org.jclouds.aws.ec2.services.ElasticIPAddressClient +(defn #^org.jclouds.ec2.services.ElasticIPAddressClient eip-service "Returns the synchronous ElasticIPAddressClient associated with the specified compute service, or compute/*compute* as bound by with-compute-service." diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java index 7cbbb0dd5a..ae6f0e663e 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/compute/EC2ComputeService.java @@ -37,6 +37,7 @@ import org.jclouds.Constants; import org.jclouds.aws.util.AWSUtils; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.callables.RunScriptOnNode; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; @@ -91,14 +92,16 @@ public class EC2ComputeService extends BaseComputeService { @Named("NODE_RUNNING") Predicate nodeRunning, @Named("NODE_TERMINATED") Predicate nodeTerminated, @Named("NODE_SUSPENDED") Predicate nodeSuspended, - InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, + RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, EC2Client ec2Client, Map credentialsMap, @Named("SECURITY") Map securityGroupMap) { super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, - initScriptRunnerFactory, initAdminAccess, persistNodeCredentials, timeouts, executor); + initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, timeouts, + executor); this.ec2Client = ec2Client; this.credentialsMap = credentialsMap; this.securityGroupMap = securityGroupMap; diff --git a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Volume.java b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Volume.java index 7312524c55..c5f15810ce 100644 --- a/apis/ec2/src/main/java/org/jclouds/ec2/domain/Volume.java +++ b/apis/ec2/src/main/java/org/jclouds/ec2/domain/Volume.java @@ -65,7 +65,7 @@ public class Volume implements Comparable { } public static enum Status { - CREATING, AVAILABLE, IN_USE, DELETING, UNRECOGNIZED; + CREATING, AVAILABLE, IN_USE, DELETING, ERROR, UNRECOGNIZED; public String value() { return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_HYPHEN, name()); } diff --git a/apis/elasticstack/pom.xml b/apis/elasticstack/pom.xml index bbeda69387..7ede5a3de7 100644 --- a/apis/elasticstack/pom.xml +++ b/apis/elasticstack/pom.xml @@ -34,6 +34,7 @@ elasticstack jclouds elasticstack core jclouds components to access elasticstack + bundle @@ -147,4 +148,20 @@ + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.elastichosts.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/apis/eucalyptus/pom.xml b/apis/eucalyptus/pom.xml index 385ac0d096..9bc3d05365 100644 --- a/apis/eucalyptus/pom.xml +++ b/apis/eucalyptus/pom.xml @@ -33,6 +33,7 @@ eucalyptus jclouds Eucalyptus api EC2 implementation based on Eucalyptus + bundle http://ecc.eucalyptus.com:8773/services/Eucalyptus @@ -136,6 +137,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.eucalyptus.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/apis/filesystem/pom.xml b/apis/filesystem/pom.xml index edda5c8599..a094f69d49 100644 --- a/apis/filesystem/pom.xml +++ b/apis/filesystem/pom.xml @@ -33,6 +33,7 @@ filesystem jcloud filesystem core jclouds components to access filesystem + bundle @@ -72,5 +73,21 @@ org.jclouds.filesystem.integration.FilesystemTestInitializer + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.filesystem.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/apis/nova/pom.xml b/apis/nova/pom.xml index 0104b4bd9c..f029512e81 100644 --- a/apis/nova/pom.xml +++ b/apis/nova/pom.xml @@ -33,6 +33,7 @@ nova jcloud nova api jclouds components to access an implementation of OpenStack Nova + bundle @@ -96,22 +97,6 @@ - - - - maven-remote-resources-plugin - 1.2 - - - process-remote-resources - - - - - - - - live @@ -175,5 +160,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.openstack.nova.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java b/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java index 6728c0acf1..15f2a35eab 100644 --- a/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java +++ b/apis/nova/src/test/java/org/jclouds/openstack/nova/NovaAsyncClientTest.java @@ -66,7 +66,7 @@ import static org.testng.Assert.assertEquals; * @author Adrian Cole */ // NOTE:without testName, this will not call @Before* and fail w/NPE during surefire -@Test(groups = "unit", testName = "NovaAsyncClientTest") +@Test(groups = "unit", singleThreaded = true, testName = "NovaAsyncClientTest") public class NovaAsyncClientTest extends RestClientTest { private static final Class listOptionsVarargsClass = new ListOptions[]{}.getClass(); private static final Class createServerOptionsVarargsClass = new CreateServerOptions[]{} diff --git a/apis/s3/pom.xml b/apis/s3/pom.xml index a8a4542cfc..c5deb1bb9f 100644 --- a/apis/s3/pom.xml +++ b/apis/s3/pom.xml @@ -33,6 +33,7 @@ s3 jcloud s3 api jclouds components to access an implementation of S3 + bundle org.jclouds.s3.blobstore.integration.S3TestInitializer @@ -143,6 +144,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.s3.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/apis/scality-rs2/pom.xml b/apis/scality-rs2/pom.xml index 0a90bf7c36..4191aa583b 100644 --- a/apis/scality-rs2/pom.xml +++ b/apis/scality-rs2/pom.xml @@ -33,6 +33,7 @@ scality-rs2 jclouds Eucalyptus Walrus api Simple Storage Service (S3) implementation based on Scality RING RS2 + bundle org.jclouds.scality.rs2.blobstore.ScalityRS2TestInitializer @@ -139,6 +140,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.scality.rs2.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/apis/swift/pom.xml b/apis/swift/pom.xml index d2c81ef2db..cc777879b4 100644 --- a/apis/swift/pom.xml +++ b/apis/swift/pom.xml @@ -33,6 +33,7 @@ swift jcloud swift api jclouds components to access an implementation of OpenStack Swift + bundle org.jclouds.openstack.swift.blobstore.integration.SwiftTestInitializer @@ -143,6 +144,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.openstack.swift.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/apis/vcloud/pom.xml b/apis/vcloud/pom.xml index ef13db1328..1931c88099 100644 --- a/apis/vcloud/pom.xml +++ b/apis/vcloud/pom.xml @@ -32,6 +32,7 @@ vcloud jcloud vcloud api jclouds components to access an implementation of VMWare vCloud + bundle @@ -156,4 +157,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.vcloud.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/apis/vcloudexpress/pom.xml b/apis/vcloudexpress/pom.xml index 04a6fc9663..229cfdc70a 100644 --- a/apis/vcloudexpress/pom.xml +++ b/apis/vcloudexpress/pom.xml @@ -32,6 +32,7 @@ vcloudexpress jcloud vcloudexpress api jclouds components to access an implementation of VMWare vCloud Express + bundle @@ -156,4 +157,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.vcloud.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/apis/walrus/pom.xml b/apis/walrus/pom.xml index 045191c9d4..704060ddf8 100644 --- a/apis/walrus/pom.xml +++ b/apis/walrus/pom.xml @@ -33,6 +33,7 @@ walrus jclouds Eucalyptus Walrus api Simple Storage Service (S3) implementation based on Eucalyptus Walrus + bundle org.jclouds.walrus.blobstore.WalrusTestInitializer @@ -139,6 +140,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.walrus.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/blobstore/pom.xml b/blobstore/pom.xml index b4c0301569..1a80f77774 100644 --- a/blobstore/pom.xml +++ b/blobstore/pom.xml @@ -32,6 +32,7 @@ jclouds-blobstore jclouds blobstore core jclouds components to access blobstore + bundle scm:svn:http://jclouds.googlecode.com/svn/trunk/blobstore @@ -118,6 +119,18 @@ + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.blobstore.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + jclouds-core;version="${project.version}" + + + diff --git a/common/aws/pom.xml b/common/aws/pom.xml index 48812242ab..dbddac8ce2 100644 --- a/common/aws/pom.xml +++ b/common/aws/pom.xml @@ -32,6 +32,8 @@ aws-common jclouds Amazon AWS Components Core jclouds Core components to access Amazon AWS + bundle + org.jclouds @@ -47,4 +49,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.aws.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/common/azure/pom.xml b/common/azure/pom.xml index 5310bf0177..f0c9a62c2f 100644 --- a/common/azure/pom.xml +++ b/common/azure/pom.xml @@ -2,7 +2,7 @@ + + META-INF/services/ + org/jclouds/providers/ProvidersTest.class + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + com.google.gson;-split-package:=merge-first, + org.jclouds.*;version=${project.version} + + + + + + distribution diff --git a/core/src/main/java/com/google/gson/JsonLiteral.java b/core/src/main/java/com/google/gson/JsonLiteral.java index bef99b7ea7..e3cb87bc02 100644 --- a/core/src/main/java/com/google/gson/JsonLiteral.java +++ b/core/src/main/java/com/google/gson/JsonLiteral.java @@ -23,11 +23,12 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.io.IOException; /** - * The gson project use package to control access to their objects. However, - * this prevents us from doing valid work, like controling the json emitted on a - * per-object basis. This is here to afford us to do this. + * The gson project use package to control access to their objects. However, this prevents us from + * doing valid work, like controling the json emitted on a per-object basis. This is here to afford + * us to do this. * * @author Adrian Cole + * @see */ public final class JsonLiteral extends JsonElement { private final CharSequence literal; diff --git a/core/src/main/java/com/google/gson/MapTypeAdapter.java b/core/src/main/java/com/google/gson/MapTypeAdapter.java deleted file mode 100644 index cfab58edc9..0000000000 --- a/core/src/main/java/com/google/gson/MapTypeAdapter.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * - * Copyright (C) 2011 Cloud Conscious, LLC. - * - * ==================================================================== - * 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 com.google.gson; - -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.jclouds.json.internal.ParseObjectFromElement; - -@SuppressWarnings({ "unchecked", "rawtypes" }) -public class MapTypeAdapter implements JsonSerializer, JsonDeserializer, InstanceCreator { - - public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) { - JsonObject map = new JsonObject(); - Type childGenericType = null; - if (typeOfSrc instanceof ParameterizedType) { - childGenericType = new TypeInfoMap(typeOfSrc).getValueType(); - } - - for (Map.Entry entry : (Set) src.entrySet()) { - Object value = entry.getValue(); - - JsonElement valueElement; - if (value == null) { - valueElement = JsonNull.createJsonNull(); - } else { - Type childType = (childGenericType == null) ? value.getClass() : childGenericType; - valueElement = context.serialize(value, childType); - } - map.add(String.valueOf(entry.getKey()), valueElement); - } - return map; - } - - public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { - // Use ObjectConstructor to create instance instead of hard-coding a specific type. - // This handles cases where users are using their own subclass of Map. - Map map = constructMapType(typeOfT, context); - TypeInfoMap mapTypeInfo = new TypeInfoMap(typeOfT); - for (Map.Entry entry : json.getAsJsonObject().entrySet()) { - Object key = context.deserialize(new JsonPrimitive(entry.getKey()), mapTypeInfo.getKeyType()); - // START JCLOUDS PATCH - Object value = null; - if (mapTypeInfo.getValueType() == Object.class) { - value = ParseObjectFromElement.SINGLETON.apply(entry.getValue()); - } - if (value == null) { - value = context.deserialize(entry.getValue(), mapTypeInfo.getValueType()); - } - // END JCLOUDS PATCH - map.put(key, value); - } - return map; - } - - private Map constructMapType(Type mapType, JsonDeserializationContext context) { - JsonDeserializationContextDefault contextImpl = (JsonDeserializationContextDefault) context; - ObjectConstructor objectConstructor = contextImpl.getObjectConstructor(); - return (Map) objectConstructor.construct(mapType); - } - - public Map createInstance(Type type) { - return new LinkedHashMap(); - } - - @Override - public String toString() { - return MapTypeAdapter.class.getSimpleName(); - } -} \ No newline at end of file diff --git a/core/src/main/java/com/google/gson/ObjectMapTypeAdapter.java b/core/src/main/java/com/google/gson/ObjectMapTypeAdapter.java new file mode 100644 index 0000000000..ed91ae86ee --- /dev/null +++ b/core/src/main/java/com/google/gson/ObjectMapTypeAdapter.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * 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 com.google.gson; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Map; +import java.util.Set; + +import org.jclouds.json.internal.ParseObjectFromElement; + +import com.google.gson.internal.$Gson$Types; + +/** + * Default serialization and deserialization of a map type. This implementation really only works + * well with simple primitive types as the map key. If the key is not a simple primitive then the + * object is {@code toString}ed and that value is used as its key. + *

+ * Patched depending on this + * @author Joel Leitch + */ +@SuppressWarnings("unchecked") +public final class ObjectMapTypeAdapter extends BaseMapTypeAdapter { + + public JsonElement serialize(Map src, Type typeOfSrc, JsonSerializationContext context) { + JsonObject map = new JsonObject(); + Type childGenericType = null; + if (typeOfSrc instanceof ParameterizedType) { + Class rawTypeOfSrc = $Gson$Types.getRawType(typeOfSrc); + childGenericType = $Gson$Types.getMapKeyAndValueTypes(typeOfSrc, rawTypeOfSrc)[1]; + } + + for (Map.Entry entry : (Set) src.entrySet()) { + Object value = entry.getValue(); + + JsonElement valueElement; + if (value == null) { + valueElement = JsonNull.createJsonNull(); + } else { + Type childType = (childGenericType == null) + ? value.getClass() : childGenericType; + valueElement = serialize(context, value, childType); + } + map.add(String.valueOf(entry.getKey()), valueElement); + } + return map; + } + + public Map deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) + throws JsonParseException { + // Use ObjectConstructor to create instance instead of hard-coding a specific type. + // This handles cases where users are using their own subclass of Map. + Map map = constructMapType(typeOfT, context); + Type[] keyAndValueTypes = $Gson$Types.getMapKeyAndValueTypes(typeOfT, $Gson$Types.getRawType(typeOfT)); + for (Map.Entry entry : json.getAsJsonObject().entrySet()) { + Object key = context.deserialize(new JsonPrimitive(entry.getKey()), keyAndValueTypes[0]); + // START JCLOUDS PATCH + // http://code.google.com/p/google-gson/issues/detail?id=325 + Object value = null; + if (keyAndValueTypes[1] == Object.class) { + value = ParseObjectFromElement.SINGLETON.apply(entry.getValue()); + } + if (value == null) { + value = context.deserialize(entry.getValue(), keyAndValueTypes[1]); + } + // END JCLOUDS PATCH + map.put(key, value); + } + return map; + } + + @Override + public String toString() { + return MapTypeAdapter.class.getSimpleName(); + } +} \ No newline at end of file diff --git a/core/src/main/java/com/google/gson/Streams.java b/core/src/main/java/com/google/gson/Streams.java index 24e2167553..c6b05f89bf 100644 --- a/core/src/main/java/com/google/gson/Streams.java +++ b/core/src/main/java/com/google/gson/Streams.java @@ -1,8 +1,6 @@ -/** +/* + * Copyright (C) 2010 Google Inc. * - * Copyright (C) 2011 Cloud Conscious, LLC. - * - * ==================================================================== * 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 @@ -14,8 +12,8 @@ * 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 com.google.gson; import com.google.gson.stream.JsonReader; @@ -104,7 +102,8 @@ final class Streams { if (serializeNulls) { writer.nullValue(); } -//BEGIN JCLOUDS PATCH + //BEGIN JCLOUDS PATCH + // * @see } else if (element instanceof JsonLiteral ) { writer.value(JsonLiteral.class.cast(element)); //END JCLOUDS PATCH diff --git a/core/src/main/java/com/google/gson/stream/JsonWriter.java b/core/src/main/java/com/google/gson/stream/JsonWriter.java index bd01290581..bcf12bac95 100644 --- a/core/src/main/java/com/google/gson/stream/JsonWriter.java +++ b/core/src/main/java/com/google/gson/stream/JsonWriter.java @@ -1,21 +1,19 @@ -/** +/* + * Copyright (C) 2010 Google Inc. * - * Copyright (C) 2011 Cloud Conscious, LLC. - * - * ==================================================================== * 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 + * 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 com.google.gson.stream; import java.io.Closeable; @@ -344,7 +342,7 @@ public final class JsonWriter implements Closeable { return this; } //BEGIN JCLOUDS PATCH - +// * @see /** * Writes {@code value} literally * @@ -356,7 +354,6 @@ public final class JsonWriter implements Closeable { return this; } //END JCLOUDS PATCH - /** * Encodes {@code value}. * diff --git a/core/src/main/java/org/jclouds/domain/JsonBall.java b/core/src/main/java/org/jclouds/domain/JsonBall.java index 227d5797d3..b5f524ad48 100644 --- a/core/src/main/java/org/jclouds/domain/JsonBall.java +++ b/core/src/main/java/org/jclouds/domain/JsonBall.java @@ -27,6 +27,7 @@ import org.jclouds.util.Patterns; * As String is final, using a different marker to imply this is a json object * * @author Adrian Cole + * @see */ public class JsonBall implements java.io.Serializable, Comparable, CharSequence { diff --git a/sandbox-providers/ibmdev/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java b/core/src/main/java/org/jclouds/http/functions/UnwrapOnlyJsonValueInSet.java similarity index 69% rename from sandbox-providers/ibmdev/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java rename to core/src/main/java/org/jclouds/http/functions/UnwrapOnlyJsonValueInSet.java index 87480deaa1..e1fc24b7b0 100644 --- a/sandbox-providers/ibmdev/src/main/java/org/jclouds/ibmdev/functions/GetFirstInstanceInList.java +++ b/core/src/main/java/org/jclouds/http/functions/UnwrapOnlyJsonValueInSet.java @@ -16,13 +16,14 @@ * limitations under the License. * ==================================================================== */ -package org.jclouds.ibmdev.functions; +package org.jclouds.http.functions; + +import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.http.HttpResponse; -import org.jclouds.ibmdev.domain.Instance; import com.google.common.base.Function; import com.google.common.collect.Iterables; @@ -31,16 +32,20 @@ import com.google.common.collect.Iterables; * @author Adrian Cole */ @Singleton -public class GetFirstInstanceInList implements Function { - private ParseInstancesFromJson listParser; +public class UnwrapOnlyJsonValueInSet implements Function { + + private final UnwrapOnlyJsonValue> json; @Inject - public GetFirstInstanceInList(ParseInstancesFromJson mapper) { - this.listParser = mapper; + UnwrapOnlyJsonValueInSet(UnwrapOnlyJsonValue> json) { + this.json = json; } @Override - public Instance apply(HttpResponse from) { - return Iterables.getOnlyElement(listParser.apply(from)); + public T apply(HttpResponse arg0) { + Set set = json.apply(arg0); + if (set == null || set.size() == 0) + return null; + return Iterables.getOnlyElement(set); } } \ No newline at end of file diff --git a/sandbox-providers/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java b/core/src/main/java/org/jclouds/io/CopyInputStreamInputSupplierMap.java similarity index 57% rename from sandbox-providers/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java rename to core/src/main/java/org/jclouds/io/CopyInputStreamInputSupplierMap.java index fc3ba33060..909a470303 100644 --- a/sandbox-providers/ibmdev/src/main/java/org/jclouds/ibmdev/functions/ParseImageFromJson.java +++ b/core/src/main/java/org/jclouds/io/CopyInputStreamInputSupplierMap.java @@ -16,34 +16,32 @@ * limitations under the License. * ==================================================================== */ -package org.jclouds.ibmdev.functions; +package org.jclouds.io; + +import java.io.InputStream; +import java.util.Map; import javax.inject.Inject; -import javax.inject.Singleton; -import org.jclouds.http.HttpResponse; -import org.jclouds.http.functions.ParseJson; -import org.jclouds.ibmdev.domain.Image; +import org.jclouds.collect.InputSupplierMap; -import com.google.common.base.Function; +import com.google.common.annotations.Beta; +import com.google.common.io.InputSupplier; /** + * * @author Adrian Cole */ -@Singleton -public class ParseImageFromJson implements Function { - - private final ParseJson json; - +@Beta +public class CopyInputStreamInputSupplierMap extends InputSupplierMap { @Inject - ParseImageFromJson(ParseJson json) { - this.json = json; + public CopyInputStreamInputSupplierMap(Map> toMap, + CopyInputStreamIntoSupplier putFunction) { + super(toMap, putFunction); } - @Override - public Image apply(HttpResponse arg0) { - Image input = json.apply(arg0); - ParseUtils.CLEAN_IMAGE.apply(input); - return input; + public CopyInputStreamInputSupplierMap(Map> toMap) { + super(toMap, new CopyInputStreamIntoSupplier()); } + } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/io/CopyInputStreamIntoSupplier.java b/core/src/main/java/org/jclouds/io/CopyInputStreamIntoSupplier.java new file mode 100644 index 0000000000..e83157dcfe --- /dev/null +++ b/core/src/main/java/org/jclouds/io/CopyInputStreamIntoSupplier.java @@ -0,0 +1,64 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.io; + +import java.io.IOException; +import java.io.InputStream; + +import javax.annotation.Resource; + +import org.jclouds.logging.Logger; + +import com.google.common.annotations.Beta; +import com.google.common.base.Function; +import com.google.common.io.ByteStreams; +import com.google.common.io.Closeables; +import com.google.common.io.InputSupplier; + +/** + * + * @author Adrian Cole + */ +@Beta +public class CopyInputStreamIntoSupplier implements Function> { + @Resource + protected Logger logger = Logger.NULL; + + @SuppressWarnings("unchecked") + @Override + public InputSupplier apply(InputStream from) { + if (from == null) + return new InputSupplier() { + + @Override + public InputStream getInput() throws IOException { + return null; + } + + }; + try { + return InputSupplier.class.cast(ByteStreams.newInputStreamSupplier(ByteStreams.toByteArray(from))); + } catch (Exception e) { + logger.warn(e, "ignoring problem retrieving credentials"); + return null; + } finally { + Closeables.closeQuietly(from); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/json/config/GsonModule.java b/core/src/main/java/org/jclouds/json/config/GsonModule.java index e0353efc7c..38a852cee1 100644 --- a/core/src/main/java/org/jclouds/json/config/GsonModule.java +++ b/core/src/main/java/org/jclouds/json/config/GsonModule.java @@ -24,6 +24,8 @@ import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.inject.Inject; import javax.inject.Singleton; @@ -36,12 +38,11 @@ import org.jclouds.json.internal.EnumTypeAdapterThatReturnsFromValue; import org.jclouds.json.internal.GsonWrapper; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Maps; +import com.google.common.collect.ImmutableMap.Builder; import com.google.common.primitives.Bytes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.google.gson.JcloudsGsonPackageAccessor; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; @@ -50,7 +51,7 @@ import com.google.gson.JsonParseException; import com.google.gson.JsonPrimitive; import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; -import com.google.gson.MapTypeAdapter; +import com.google.gson.ObjectMapTypeAdapter; import com.google.gson.reflect.TypeToken; import com.google.inject.AbstractModule; import com.google.inject.ImplementedBy; @@ -68,12 +69,12 @@ public class GsonModule extends AbstractModule { @Provides @Singleton Gson provideGson(JsonBallAdapter jsonAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter, - ByteArrayAdapter byteArrayAdapter, SerializePropertiesDefaults propertiesAdapter, JsonAdapterBindings bindings) - throws ClassNotFoundException, Exception { + ByteArrayAdapter byteArrayAdapter, SerializePropertiesDefaults propertiesAdapter, + JsonAdapterBindings bindings) throws ClassNotFoundException, Exception { GsonBuilder builder = new GsonBuilder(); - JcloudsGsonPackageAccessor.registerTypeHierarchyAdapter(builder, Enum.class, - new EnumTypeAdapterThatReturnsFromValue()); - JcloudsGsonPackageAccessor.registerTypeHierarchyAdapter(builder, Map.class, new MapTypeAdapter()); + Logger.getLogger("com.google.gson.ParameterizedTypeHandlerMap").setLevel(Level.OFF); + builder.registerTypeHierarchyAdapter(Enum.class, new EnumTypeAdapterThatReturnsFromValue()); + builder.registerTypeHierarchyAdapter(Map.class, new ObjectMapTypeAdapter()); builder.registerTypeAdapter(JsonBall.class, jsonAdapter); builder.registerTypeAdapter(Date.class, adapter); builder.registerTypeAdapter(Properties.class, propertiesAdapter); @@ -86,6 +87,7 @@ public class GsonModule extends AbstractModule { return builder.create(); } + // http://code.google.com/p/google-gson/issues/detail?id=326 @ImplementedBy(JsonBallAdapterImpl.class) public static interface JsonBallAdapter extends JsonSerializer, JsonDeserializer { @@ -99,7 +101,7 @@ public class GsonModule extends AbstractModule { } public JsonBall deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { return new JsonBall(json.toString()); } @@ -125,7 +127,7 @@ public class GsonModule extends AbstractModule { @Override public List deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { return Bytes.asList(CryptoStreams.hex(json.getAsString())); } @@ -141,7 +143,7 @@ public class GsonModule extends AbstractModule { @Override public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { return CryptoStreams.hex(json.getAsString()); } @@ -165,7 +167,7 @@ public class GsonModule extends AbstractModule { } public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { String toParse = json.getAsJsonPrimitive().getAsString(); try { return dateService.iso8601DateParse(toParse); @@ -212,7 +214,7 @@ public class GsonModule extends AbstractModule { } public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { String toParse = json.getAsJsonPrimitive().getAsString(); Date toReturn = dateService.cDateParse(toParse); return toReturn; @@ -228,7 +230,7 @@ public class GsonModule extends AbstractModule { } public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) - throws JsonParseException { + throws JsonParseException { long toParse = json.getAsJsonPrimitive().getAsLong(); if (toParse == -1) return null; diff --git a/core/src/main/java/org/jclouds/json/internal/JsonObjectAsMap.java b/core/src/main/java/org/jclouds/json/internal/JsonObjectAsMap.java index c25969dc6a..f307da024f 100644 --- a/core/src/main/java/org/jclouds/json/internal/JsonObjectAsMap.java +++ b/core/src/main/java/org/jclouds/json/internal/JsonObjectAsMap.java @@ -27,7 +27,7 @@ import com.google.gson.JsonObject; /** * Exposes the JsonObject as a map so that we can use gauva apis on it. - * + * http://code.google.com/p/google-gson/issues/detail?id=325 * @author Adrian Cole */ public enum JsonObjectAsMap implements Function> { diff --git a/core/src/main/java/org/jclouds/json/internal/ParseObjectFromElement.java b/core/src/main/java/org/jclouds/json/internal/ParseObjectFromElement.java index ed3a293b97..8aa5ca8ca2 100644 --- a/core/src/main/java/org/jclouds/json/internal/ParseObjectFromElement.java +++ b/core/src/main/java/org/jclouds/json/internal/ParseObjectFromElement.java @@ -24,12 +24,11 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gson.JsonElement; import com.google.gson.JsonPrimitive; -import com.google.gson.MapTypeAdapter; /** * This is a class that helps the default {@link MapTypeAdapter} make a sane object graph when the * value is set to {@code Object} - * + * http://code.google.com/p/google-gson/issues/detail?id=325 * @author Adrian Cole */ public enum ParseObjectFromElement implements Function { diff --git a/core/src/main/java/org/jclouds/providers/BaseProviderMetadata.java b/core/src/main/java/org/jclouds/providers/BaseProviderMetadata.java new file mode 100644 index 0000000000..039236bff1 --- /dev/null +++ b/core/src/main/java/org/jclouds/providers/BaseProviderMetadata.java @@ -0,0 +1,158 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.providers; + +import java.net.URI; +import java.util.Set; + +import com.google.common.collect.ImmutableSet; + +/** + * The BaseProviderMetadata class is an abstraction of {@link ProviderMetadata} to be extended by + * those implementing ProviderMetadata. + * + * (Note: This class must be abstract to allow {@link java.util.ServiceLoader} to work properly. + * + * @author Jeremy Whitlock + */ +public abstract class BaseProviderMetadata implements ProviderMetadata { + + /** + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + URI console = getConsole(); + URI homepage = getHomepage(); + URI docs = getApiDocumentation(); + String id = getId(); + String name = getName(); + String identityName = getIdentityName(); + String credentialName = getCredentialName(); + String type = getType(); + Set linkedServices = getLinkedServices(); + + result = prime * result + ((console == null) ? 0 : console.hashCode()); + result = prime * result + ((homepage == null) ? 0 : homepage.hashCode()); + result = prime * result + ((docs == null) ? 0 : docs.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((identityName == null) ? 0 : identityName.hashCode()); + result = prime * result + ((credentialName == null) ? 0 : credentialName.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((linkedServices == null) ? 0 : linkedServices.hashCode()); + + return result; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + URI tConsole = getConsole(); + URI tHomepage = getHomepage(); + URI tDocs = getApiDocumentation(); + String tId = getId(); + String tName = getName(); + String tIdentityName = getIdentityName(); + String tCredentialName = getCredentialName(); + String tType = getType(); + Set tLinkedServices = getLinkedServices(); + + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + ProviderMetadata other = (ProviderMetadata) obj; + URI oConsole = other.getConsole(); + URI oHomepage = other.getHomepage(); + URI oDocs = other.getApiDocumentation(); + String oId = other.getId(); + String oName = other.getName(); + String oIdentityName = other.getIdentityName(); + String oCredentialName = other.getCredentialName(); + String oType = other.getType(); + Set oLinkedServices = other.getLinkedServices(); + + if (tConsole == null) { + if (oConsole != null) + return false; + } else if (!tConsole.equals(oConsole)) + return false; + if (tDocs == null) { + if (oDocs != null) + return false; + } else if (!tDocs.equals(oDocs)) + return false; + if (tHomepage == null) { + if (oHomepage != null) + return false; + } else if (!tHomepage.equals(oHomepage)) + return false; + if (tId == null) { + if (oId != null) + return false; + } else if (!tId.equals(oId)) + return false; + if (tName == null) { + if (oName != null) + return false; + } else if (!tName.equals(oName)) + return false; + if (tIdentityName == null) { + if (oIdentityName != null) + return false; + } else if (!tIdentityName.equals(oIdentityName)) + return false; + if (tCredentialName == null) { + if (oCredentialName != null) + return false; + } else if (!tCredentialName.equals(oCredentialName)) + return false; + if (tType == null) { + if (oType != null) + return false; + } else if (!tType.equals(oType)) + return false; + if (tLinkedServices == null) { + if (oLinkedServices != null) + return false; + } else if (!tLinkedServices.equals(oLinkedServices)) + return false; + return true; + } + + @Override + public String toString() { + return "[id=" + getId() + ", type=" + getType() + ", name=" + getName() + ", identityName=" + getIdentityName() + + ", credentialName=" + getCredentialName() + ", homePage=" + getHomepage() + ", console=" + + getConsole() + ", apiDocs=" + getApiDocumentation() + ", linkedServices=" + getLinkedServices() + "]"; + } + + @Override + public Set getLinkedServices() { + return ImmutableSet.of(getId()); + } +} diff --git a/core/src/main/java/org/jclouds/providers/ProviderMetadata.java b/core/src/main/java/org/jclouds/providers/ProviderMetadata.java index 2866aebdcc..20fab4e720 100644 --- a/core/src/main/java/org/jclouds/providers/ProviderMetadata.java +++ b/core/src/main/java/org/jclouds/providers/ProviderMetadata.java @@ -19,51 +19,78 @@ package org.jclouds.providers; import java.net.URI; +import java.util.Set; + +import javax.annotation.Nullable; /** - * The ProviderMetadata interface allows jclouds to provide a plugin framework - * for gathering cloud provider metadata. - * + * The ProviderMetadata interface allows jclouds to provide a plugin framework for gathering cloud + * provider metadata. + * * @author Jeremy Whitlock */ public interface ProviderMetadata { public static final String BLOBSTORE_TYPE = "blobstore"; public static final String COMPUTE_TYPE = "compute"; + public static final String LOADBALANCER_TYPE = "loadbalancer"; + public static final String TABLE_TYPE = "table"; + public static final String QUEUE_TYPE = "queue"; - /** - * Returns an identifier unique to the provider. - * - * @return the provider's unique identifier - */ - public String getId(); + /** + * + * @return the provider's unique identifier + */ + public String getId(); - /** - * Returns the provider type. - * - * @return the provider's type - */ - public String getType(); + /** + * + * @return the provider's type + */ + public String getType(); - /** - * Returns the name of the provider. - * - * @return the name (display name) of the provider - */ - public String getName(); + /** + * + * @return the name (display name) of the provider + */ + public String getName(); - /** - * Returns the URI to the provider's homepage. - * - * @return the url for the provider's homepage - */ - public URI getHomepage(); + /** + * + * @return the name (display name) of an identity on this provider (ex. user, email, account, + * apikey) + */ + public String getIdentityName(); - /** - * Returns the URI to the provider's console. - * - * @return the url for the provider's console - */ - public URI getConsole(); + /** + * + * @return the name (display name) of a credential on this provider, or null if there is none + * (ex. password, secret, rsaKey) + */ + @Nullable + public String getCredentialName(); + /** + * + * @return the url for the provider's homepage + */ + public URI getHomepage(); + + /** + * + * @return the url for the provider's console + */ + public URI getConsole(); + + /** + * + * @return the url for the API documentation related to this service + */ + public URI getApiDocumentation(); + + /** + * + * @return all known services linked to the same account on this provider + */ + public Set getLinkedServices(); } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/providers/Providers.java b/core/src/main/java/org/jclouds/providers/Providers.java index 7688fe99fe..b646ae1fe8 100644 --- a/core/src/main/java/org/jclouds/providers/Providers.java +++ b/core/src/main/java/org/jclouds/providers/Providers.java @@ -26,15 +26,14 @@ import java.util.ServiceLoader; /** * The Providers class provides static methods for accessing providers. - * + * * @author Jeremy Whitlock */ public class Providers { /** - * Returns the providers located on the classpath via - * {@link java.util.ServiceLoader}. - * + * Returns the providers located on the classpath via {@link java.util.ServiceLoader}. + * * @return all available providers loaded from classpath via ServiceLoader */ private static Iterable fromServiceLoader() { @@ -43,7 +42,7 @@ public class Providers { /** * Returns all available providers. - * + * * @return all available providers */ public static Iterable all() { @@ -52,24 +51,23 @@ public class Providers { /** * Returns the first provider with the provided id - * + * * @param id * the id of the provider to return - * + * * @return the provider with the given id - * + * * @throws NoSuchElementException - * whenever there are no providers with the provided id + * whenever there are no providers with the provided id */ - public static ProviderMetadata withId(String id) - throws NoSuchElementException { + public static ProviderMetadata withId(String id) throws NoSuchElementException { return find(all(), ProviderPredicates.id(id)); } /** * Returns the providers that are of type * {@link org.jclouds.providers.ProviderMetadata#BLOBSTORE_TYPE}. - * + * * @return the blobstore providers */ public static Iterable allBlobStore() { @@ -79,19 +77,49 @@ public class Providers { /** * Returns the providers that are of type * {@link org.jclouds.providers.ProviderMetadata#COMPUTE_TYPE}. - * + * * @return the compute service providers */ public static Iterable allCompute() { return filter(all(), ProviderPredicates.type(ProviderMetadata.COMPUTE_TYPE)); } + /** + * Returns the providers that are of type + * {@link org.jclouds.providers.ProviderMetadata#QUEUE_TYPE}. + * + * @return the queue service providers + */ + public static Iterable allQueue() { + return filter(all(), ProviderPredicates.type(ProviderMetadata.QUEUE_TYPE)); + } + + /** + * Returns the providers that are of type + * {@link org.jclouds.providers.ProviderMetadata#TABLE_TYPE}. + * + * @return the table service providers + */ + public static Iterable allTable() { + return filter(all(), ProviderPredicates.type(ProviderMetadata.TABLE_TYPE)); + } + + /** + * Returns the providers that are of type + * {@link org.jclouds.providers.ProviderMetadata#LOADBALANCER_TYPE}. + * + * @return the load balancer service providers + */ + public static Iterable allLoadBalancer() { + return filter(all(), ProviderPredicates.type(ProviderMetadata.LOADBALANCER_TYPE)); + } + /** * Returns the providers that are of the provided type. - * + * * @param type * the type to providers to return - * + * * @return the providers of the provided type */ public static Iterable ofType(String type) { diff --git a/core/src/main/java/org/jclouds/rest/config/CredentialStoreModule.java b/core/src/main/java/org/jclouds/rest/config/CredentialStoreModule.java index 4baf672602..05a7e5102a 100644 --- a/core/src/main/java/org/jclouds/rest/config/CredentialStoreModule.java +++ b/core/src/main/java/org/jclouds/rest/config/CredentialStoreModule.java @@ -20,7 +20,6 @@ package org.jclouds.rest.config; import static com.google.common.base.Preconditions.checkNotNull; -import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -29,9 +28,9 @@ import javax.annotation.Resource; import javax.inject.Inject; import javax.inject.Singleton; -import org.jclouds.collect.InputSupplierMap; import org.jclouds.collect.TransformingMap; import org.jclouds.domain.Credentials; +import org.jclouds.io.CopyInputStreamInputSupplierMap; import org.jclouds.json.Json; import org.jclouds.logging.Logger; import org.jclouds.rest.ConfiguresCredentialStore; @@ -39,8 +38,6 @@ import org.jclouds.util.Strings2; import com.google.common.annotations.Beta; import com.google.common.base.Function; -import com.google.common.io.ByteStreams; -import com.google.common.io.Closeables; import com.google.common.io.InputSupplier; import com.google.inject.AbstractModule; import com.google.inject.Provides; @@ -97,48 +94,6 @@ public class CredentialStoreModule extends AbstractModule { } } - @Singleton - public static class CopyInputStreamInputSupplierMap extends InputSupplierMap { - @Singleton - public static class CopyInputStreamIntoSupplier implements Function> { - @Resource - protected Logger logger = Logger.NULL; - - @SuppressWarnings("unchecked") - @Override - public InputSupplier apply(InputStream from) { - if (from == null) - return new InputSupplier() { - - @Override - public InputStream getInput() throws IOException { - return null; - } - - }; - try { - return InputSupplier.class.cast(ByteStreams.newInputStreamSupplier(ByteStreams.toByteArray(from))); - } catch (Exception e) { - logger.warn(e, "ignoring problem retrieving credentials"); - return null; - } finally { - Closeables.closeQuietly(from); - } - } - } - - @Inject - public CopyInputStreamInputSupplierMap(Map> toMap, - CopyInputStreamIntoSupplier putFunction) { - super(toMap, putFunction); - } - - public CopyInputStreamInputSupplierMap(Map> toMap) { - super(toMap, new CopyInputStreamIntoSupplier()); - } - - } - @Singleton public static class CredentialsFromJsonInputStream implements Function { @Resource diff --git a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java index d1d3527fb9..36627ff5df 100755 --- a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java +++ b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java @@ -82,6 +82,7 @@ import org.jclouds.http.functions.ReturnInputStream; import org.jclouds.http.functions.ReturnStringIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.UnwrapOnlyJsonValue; +import org.jclouds.http.functions.UnwrapOnlyJsonValueInSet; import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue; import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet; import org.jclouds.http.functions.ParseSax.HandlerWithResult; @@ -743,34 +744,7 @@ public class RestAnnotationProcessor { || TypeLiteral.get(method.getGenericReturnType()).equals(futureHttpResponseLiteral)) { return Key.get((Class) IdentityFunction.class); } else if (getAcceptHeadersOrNull(method).contains(MediaType.APPLICATION_JSON)) { - Type returnVal; - if (method.getReturnType().getTypeParameters().length == 0) { - returnVal = method.getReturnType(); - } else if (method.getReturnType().equals(ListenableFuture.class)) { - ParameterizedType futureType = ((ParameterizedType) method.getGenericReturnType()); - returnVal = futureType.getActualTypeArguments()[0]; - if (returnVal instanceof WildcardType) - returnVal = WildcardType.class.cast(returnVal).getUpperBounds()[0]; - } else { - returnVal = method.getGenericReturnType(); - } - ParameterizedType parserType; - if (method.isAnnotationPresent(Unwrap.class)) { - int depth = method.getAnnotation(Unwrap.class).depth(); - Class edgeCollection = method.getAnnotation(Unwrap.class).edgeCollection(); - if (depth == 1 && edgeCollection == Map.class) - parserType = Types.newParameterizedType(UnwrapOnlyJsonValue.class, returnVal); - else if (depth == 2 && edgeCollection == Map.class) - parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, returnVal); - else if (depth == 3 && edgeCollection == Set.class) - parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValueInSet.class, returnVal); - else - throw new IllegalStateException(String.format( - "depth(%d) edgeCollection(%s) not yet supported for @Unwrap", depth, edgeCollection)); - } else { - parserType = Types.newParameterizedType(ParseJson.class, returnVal); - } - return (Key>) Key.get(parserType); + return getJsonParserKeyForMethod(method); } else if (method.getReturnType().equals(String.class) || TypeLiteral.get(method.getGenericReturnType()).equals(futureStringLiteral)) { return Key.get(ReturnStringIf2xx.class); @@ -784,6 +758,49 @@ public class RestAnnotationProcessor { return Key.get(annotation.value()); } + public static Key> getJsonParserKeyForMethod(Method method) { + Type returnVal = getReturnTypeForMethod(method); + return getJsonParserKeyForMethodAnType(method, returnVal); + } + + public static Type getReturnTypeForMethod(Method method) { + Type returnVal; + if (method.getReturnType().getTypeParameters().length == 0) { + returnVal = method.getReturnType(); + } else if (method.getReturnType().equals(ListenableFuture.class)) { + ParameterizedType futureType = ((ParameterizedType) method.getGenericReturnType()); + returnVal = futureType.getActualTypeArguments()[0]; + if (returnVal instanceof WildcardType) + returnVal = WildcardType.class.cast(returnVal).getUpperBounds()[0]; + } else { + returnVal = method.getGenericReturnType(); + } + return returnVal; + } + + @SuppressWarnings( { "unchecked", "rawtypes" }) + public static Key> getJsonParserKeyForMethodAnType(Method method, Type returnVal) { + ParameterizedType parserType; + if (method.isAnnotationPresent(Unwrap.class)) { + int depth = method.getAnnotation(Unwrap.class).depth(); + Class edgeCollection = method.getAnnotation(Unwrap.class).edgeCollection(); + if (depth == 1 && edgeCollection == Map.class) + parserType = Types.newParameterizedType(UnwrapOnlyJsonValue.class, returnVal); + else if (depth == 2 && edgeCollection == Map.class) + parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, returnVal); + else if (depth == 2 && edgeCollection == Set.class) + parserType = Types.newParameterizedType(UnwrapOnlyJsonValueInSet.class, returnVal); + else if (depth == 3 && edgeCollection == Set.class) + parserType = Types.newParameterizedType(UnwrapOnlyNestedJsonValueInSet.class, returnVal); + else + throw new IllegalStateException(String.format("depth(%d) edgeCollection(%s) not yet supported for @Unwrap", + depth, edgeCollection)); + } else { + parserType = Types.newParameterizedType(ParseJson.class, returnVal); + } + return (Key>) Key.get(parserType); + } + public static Class> getSaxResponseParserClassOrNull(Method method) { XMLResponseParser annotation = method.getAnnotation(XMLResponseParser.class); if (annotation != null) { diff --git a/core/src/main/resources/rest.properties b/core/src/main/resources/rest.properties index 664ee1076a..27b3da4a8f 100644 --- a/core/src/main/resources/rest.properties +++ b/core/src/main/resources/rest.properties @@ -126,8 +126,8 @@ openhosting-east1.contextbuilder=org.jclouds.openhosting.OpenHostingEast1Context cloudsigma-zrh.propertiesbuilder=org.jclouds.cloudsigma.CloudSigmaZurichPropertiesBuilder cloudsigma-zrh.contextbuilder=org.jclouds.cloudsigma.CloudSigmaContextBuilder -ibmdev.propertiesbuilder=org.jclouds.ibmdev.IBMDeveloperCloudPropertiesBuilder -ibmdev.contextbuilder=org.jclouds.ibmdev.IBMDeveloperCloudContextBuilder +ibm-smartcloud.propertiesbuilder=org.jclouds.ibm.smartcloud.IBMSmartCloudPropertiesBuilder +ibm-smartcloud.contextbuilder=org.jclouds.ibm.smartcloud.IBMSmartCloudContextBuilder stub.contextbuilder=org.jclouds.compute.stub.StubComputeServiceContextBuilder # example of where to change your endpoint diff --git a/core/src/test/java/org/jclouds/json/BaseParserTest.java b/core/src/test/java/org/jclouds/json/BaseParserTest.java index c9fd77926e..423099f4e0 100644 --- a/core/src/test/java/org/jclouds/json/BaseParserTest.java +++ b/core/src/test/java/org/jclouds/json/BaseParserTest.java @@ -20,18 +20,24 @@ package org.jclouds.json; import static org.testng.Assert.assertEquals; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.inject.Qualifier; + import org.jclouds.http.HttpResponse; -import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue; +import org.jclouds.io.Payload; import org.jclouds.io.Payloads; import org.jclouds.json.config.GsonModule; +import org.jclouds.rest.internal.RestAnnotationProcessor; import org.testng.annotations.Test; import com.google.common.base.Function; +import com.google.common.base.Throwables; import com.google.inject.Guice; import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.TypeLiteral; -import com.google.inject.util.Types; /** * @@ -39,22 +45,41 @@ import com.google.inject.util.Types; */ public abstract class BaseParserTest { + @Retention(value = RetentionPolicy.RUNTIME) + @Target(value = { ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) + @Qualifier + public @interface Nested { + + } + + @SuppressWarnings("unchecked") + protected Function parser(Injector i) { + try { + return (Function) i.getInstance(RestAnnotationProcessor.getJsonParserKeyForMethod(getClass() + .getMethod("expected"))); + } catch (Exception e) { + Throwables.propagate(e); + return null; + } + } + @Test public void test() { - T expects = expected(); - - Function parser = getParser(getInjector()); - T response = parser.apply(new HttpResponse(200, "ok", Payloads.newInputStreamPayload(getClass() - .getResourceAsStream(resource())))); + Function parser = parser(injector()); + T response = parser.apply(new HttpResponse(200, "ok", payload())); compare(expects, response); } + protected Payload payload() { + return Payloads.newInputStreamPayload(getClass().getResourceAsStream(resource())); + } + public void compare(T expects, T response) { assertEquals(response.toString(), expects.toString()); } - protected Injector getInjector() { + protected Injector injector() { return Guice.createInjector(new GsonModule() { @Override @@ -67,15 +92,9 @@ public abstract class BaseParserTest { } - @SuppressWarnings("unchecked") - protected Function getParser(Injector i) { - return (Function) i.getInstance(Key.get(TypeLiteral.get( - Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, type())).getType())); + protected String resource() { + throw new IllegalStateException("please define resource such as \"/testaddresses.json\""); } - public abstract Class type(); - - public abstract String resource(); - public abstract T expected(); } diff --git a/core/src/test/java/org/jclouds/json/BaseSetParserTest.java b/core/src/test/java/org/jclouds/json/BaseSetParserTest.java index b966abd745..a781cc3219 100644 --- a/core/src/test/java/org/jclouds/json/BaseSetParserTest.java +++ b/core/src/test/java/org/jclouds/json/BaseSetParserTest.java @@ -22,15 +22,7 @@ import static org.testng.Assert.assertEquals; import java.util.Set; -import org.jclouds.http.HttpResponse; -import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue; - -import com.google.common.base.Function; import com.google.common.collect.ImmutableSortedSet; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.TypeLiteral; -import com.google.inject.util.Types; /** * @@ -38,15 +30,6 @@ import com.google.inject.util.Types; */ public abstract class BaseSetParserTest extends BaseParserTest, T> { - @SuppressWarnings("unchecked") - // crazy stuff due to type erasure - @Override - protected Function> getParser(Injector i) { - return (Function>) i.getInstance(Key.get(TypeLiteral.get( - Types.newParameterizedType(UnwrapOnlyNestedJsonValue.class, Types - .newParameterizedType(Set.class, type()))).getType())); - } - public void compare(Set expects, Set response) { assertEquals(ImmutableSortedSet.copyOf(response).toString(), ImmutableSortedSet.copyOf(expects).toString()); } diff --git a/core/src/test/java/org/jclouds/json/JsonTest.java b/core/src/test/java/org/jclouds/json/JsonTest.java index 9224822a84..cb3e145f46 100644 --- a/core/src/test/java/org/jclouds/json/JsonTest.java +++ b/core/src/test/java/org/jclouds/json/JsonTest.java @@ -37,6 +37,52 @@ import com.google.inject.TypeLiteral; public class JsonTest { private Json json = Guice.createInjector(new GsonModule()).getInstance(Json.class); + private static class ObjectNoDefaultConstructor { + private final String stringValue; + private final int intValue; + + public ObjectNoDefaultConstructor(String stringValue, int intValue) { + this.stringValue = stringValue; + this.intValue = intValue; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + intValue; + result = prime * result + ((stringValue == null) ? 0 : stringValue.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ObjectNoDefaultConstructor other = (ObjectNoDefaultConstructor) obj; + if (intValue != other.intValue) + return false; + if (stringValue == null) { + if (other.stringValue != null) + return false; + } else if (!stringValue.equals(other.stringValue)) + return false; + return true; + } + } + + public void testObjectNoDefaultConstructor() { + ObjectNoDefaultConstructor obj = new ObjectNoDefaultConstructor("foo", 1); + assertEquals(json.toJson(obj), "{\"stringValue\":\"foo\",\"intValue\":1}"); + ObjectNoDefaultConstructor obj2 = json.fromJson(json.toJson(obj), ObjectNoDefaultConstructor.class); + assertEquals(obj2, obj); + assertEquals(json.toJson(obj2), json.toJson(obj)); + } + private static class EnumInside { private static enum Test { FOO, BAR; @@ -66,7 +112,7 @@ public class JsonTest { map.put("map", ImmutableMap.of("key", "value")); map.put("list", ImmutableList.of("key", "value")); assertEquals(json.toJson(map), - "{\"string\":\"string\",\"map\":{\"key\":\"value\"},\"list\":[\"key\",\"value\"],\"boolean\":true,\"number\":1}"); + "{\"string\":\"string\",\"map\":{\"key\":\"value\"},\"list\":[\"key\",\"value\"],\"boolean\":true,\"number\":1}"); Map map2 = json.fromJson(json.toJson(map), new TypeLiteral>() { }.getType()); assertEquals(map2, map); @@ -121,12 +167,12 @@ public class JsonTest { public void testDeserializeEnumWithParser() { assertEquals(json.fromJson("{enumValue : \"FOO\"}", EnumInsideWithParser.class).enumValue, - EnumInsideWithParser.Test.FOO); + EnumInsideWithParser.Test.FOO); } public void testDeserializeEnumWithParserAndBadValue() { assertEquals(json.fromJson("{enumValue : \"sd\"}", EnumInsideWithParser.class).enumValue, - EnumInsideWithParser.Test.UNRECOGNIZED); + EnumInsideWithParser.Test.UNRECOGNIZED); } } diff --git a/core/src/test/java/org/jclouds/providers/BaseProviderMetadataTest.java b/core/src/test/java/org/jclouds/providers/BaseProviderMetadataTest.java new file mode 100644 index 0000000000..1ee8f73553 --- /dev/null +++ b/core/src/test/java/org/jclouds/providers/BaseProviderMetadataTest.java @@ -0,0 +1,73 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.providers; + +import static org.testng.Assert.assertEquals; + +import java.util.Set; + +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * + * @author Jeremy Whitlock + */ +@Test(groups = "unit") +public abstract class BaseProviderMetadataTest { + protected Set allTypes = ImmutableSet.of(ProviderMetadata.BLOBSTORE_TYPE, ProviderMetadata.COMPUTE_TYPE, + ProviderMetadata.LOADBALANCER_TYPE, ProviderMetadata.QUEUE_TYPE, ProviderMetadata.TABLE_TYPE); + + private final ProviderMetadata toTest; + private final String expectedType; + + public BaseProviderMetadataTest(ProviderMetadata toTest, String expectedType) { + this.toTest = toTest; + this.expectedType = expectedType; + } + + @Test + public void testWithId() { + ProviderMetadata providerMetadata = Providers.withId(toTest.getId()); + + assertEquals(toTest, providerMetadata); + assert providerMetadata.getLinkedServices().contains(toTest.getId()); + } + + // it is ok to have multiple services in the same classpath (ex. ec2 vs elb) + @Test + public void testOfTypeContains() { + ImmutableSet ofType = ImmutableSet.copyOf(Providers.ofType(expectedType)); + assert ofType.contains(toTest) : String.format("%s not found in %s", toTest, ofType); + } + + @Test + public void testAllContains() { + ImmutableSet all = ImmutableSet.copyOf(Providers.all()); + assert all.contains(toTest) : String.format("%s not found in %s", toTest, all); + } + + @Test + public void testInRestProperties() { + Iterable providers = org.jclouds.rest.Providers.getSupportedProviders(); + assert Iterables.contains(providers, toTest.getId()) : providers; + } +} \ No newline at end of file diff --git a/core/src/test/java/org/jclouds/providers/JcloudsTestBlobStoreProviderMetadata.java b/core/src/test/java/org/jclouds/providers/JcloudsTestBlobStoreProviderMetadata.java index 7ddc6f7310..41fa1533d6 100644 --- a/core/src/test/java/org/jclouds/providers/JcloudsTestBlobStoreProviderMetadata.java +++ b/core/src/test/java/org/jclouds/providers/JcloudsTestBlobStoreProviderMetadata.java @@ -21,14 +21,14 @@ package org.jclouds.providers; import java.net.URI; /** - * Implementation of {@ link org.jclouds.types.ProviderMetadata} for testing. - * + * Implementation of @ link org.jclouds.types.ProviderMetadata} for testing. + * * @author Jeremy Whitlock */ -public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata { +public class JcloudsTestBlobStoreProviderMetadata extends BaseProviderMetadata { /** - * {@ see org.jclouds.types.ProviderMetadata#getId()} + * {@inheritDoc} */ @Override public String getId() { @@ -36,7 +36,7 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata { } /** - * {@ see org.jclouds.types.ProviderMetadata#getType()} + * {@inheritDoc} */ @Override public String getType() { @@ -44,7 +44,7 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata { } /** - * {@ see org.jclouds.types.ProviderMetadata#getName()} + * {@inheritDoc} */ @Override public String getName() { @@ -52,7 +52,23 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata { } /** - * {@ see org.jclouds.types.ProviderMetadata#getHomepage()} + * {@inheritDoc} + */ + @Override + public String getCredentialName() { + return "user"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentityName() { + return "password"; + } + + /** + * {@inheritDoc} */ @Override public URI getHomepage() { @@ -60,11 +76,19 @@ public class JcloudsTestBlobStoreProviderMetadata implements ProviderMetadata { } /** - * {@ see org.jclouds.types.ProviderMetadata#getConsole()} + * {@inheritDoc} */ @Override public URI getConsole() { return URI.create("http://jclouds.org/console"); } + /** + * {@inheritDoc} + */ + @Override + public URI getApiDocumentation() { + return URI.create("http://jclouds.org/documentation"); + } + } \ No newline at end of file diff --git a/core/src/test/java/org/jclouds/providers/JcloudsTestComputeProviderMetadata.java b/core/src/test/java/org/jclouds/providers/JcloudsTestComputeProviderMetadata.java index 93289c4dab..a412edb1e3 100644 --- a/core/src/test/java/org/jclouds/providers/JcloudsTestComputeProviderMetadata.java +++ b/core/src/test/java/org/jclouds/providers/JcloudsTestComputeProviderMetadata.java @@ -21,11 +21,11 @@ package org.jclouds.providers; import java.net.URI; /** - * Implementation of {@ link org.jclouds.types.ProviderMetadata} for testing. - * + * Implementation of @ link org.jclouds.types.ProviderMetadata} for testing. + * * @author Jeremy Whitlock */ -public class JcloudsTestComputeProviderMetadata implements ProviderMetadata { +public class JcloudsTestComputeProviderMetadata extends BaseProviderMetadata { /** * {@ see org.jclouds.types.ProviderMetadata#getId()} @@ -51,6 +51,22 @@ public class JcloudsTestComputeProviderMetadata implements ProviderMetadata { return "Test Compute Provider"; } + /** + * {@inheritDoc} + */ + @Override + public String getCredentialName() { + return "user"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentityName() { + return "password"; + } + /** * {@ see org.jclouds.types.ProviderMetadata#getHomepage()} */ @@ -67,4 +83,12 @@ public class JcloudsTestComputeProviderMetadata implements ProviderMetadata { return URI.create("http://jclouds.org/console"); } + /** + * {@inheritDoc} + */ + @Override + public URI getApiDocumentation() { + return URI.create("http://jclouds.org/documentation"); + } + } \ No newline at end of file diff --git a/core/src/test/java/org/jclouds/providers/ProvidersTest.java b/core/src/test/java/org/jclouds/providers/ProvidersTest.java index d4f957d7e3..2cc1ab31ca 100644 --- a/core/src/test/java/org/jclouds/providers/ProvidersTest.java +++ b/core/src/test/java/org/jclouds/providers/ProvidersTest.java @@ -33,10 +33,13 @@ import org.testng.annotations.Test; @Test( groups = "unit" ) public class ProvidersTest { + private final ProviderMetadata testBlobstoreProvider = new JcloudsTestBlobStoreProviderMetadata(); + private final ProviderMetadata testComputeProvider = new JcloudsTestComputeProviderMetadata(); + @Test public void testWithId() { ProviderMetadata providerMetadata; - + try { providerMetadata = Providers.withId("fake-id"); fail("Looking for a provider with an id that doesn't exist should " + @@ -45,9 +48,9 @@ public class ProvidersTest { ; // Expected } - providerMetadata = Providers.withId("test-blobstore-provider"); + providerMetadata = Providers.withId(testBlobstoreProvider.getId()); - assertEquals("Test Blobstore Provider", providerMetadata.getName()); + assertEquals(testBlobstoreProvider, providerMetadata); } @Test @@ -55,21 +58,13 @@ public class ProvidersTest { Iterable providersMetadata = Providers.ofType(ProviderMetadata.BLOBSTORE_TYPE); for (ProviderMetadata providerMetadata : providersMetadata) { - assertEquals("Test Blobstore Provider", providerMetadata.getName()); - assertEquals("test-blobstore-provider", providerMetadata.getId()); - assertEquals(ProviderMetadata.BLOBSTORE_TYPE, providerMetadata.getType()); - assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString()); - assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString()); + assertEquals(testBlobstoreProvider, providerMetadata); } providersMetadata = Providers.ofType(ProviderMetadata.COMPUTE_TYPE); for (ProviderMetadata providerMetadata : providersMetadata) { - assertEquals("Test Compute Provider", providerMetadata.getName()); - assertEquals("test-compute-provider", providerMetadata.getId()); - assertEquals(ProviderMetadata.COMPUTE_TYPE, providerMetadata.getType()); - assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString()); - assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString()); + assertEquals(testComputeProvider, providerMetadata); } providersMetadata = Providers.ofType("fake-type"); @@ -83,16 +78,9 @@ public class ProvidersTest { for (ProviderMetadata providerMetadata : providersMetadata) { if (providerMetadata.getName().equals("Test Blobstore Provider")) { - assertEquals("test-blobstore-provider", providerMetadata.getId()); - assertEquals(ProviderMetadata.BLOBSTORE_TYPE, providerMetadata.getType()); - assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString()); - assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString()); + assertEquals(testBlobstoreProvider, providerMetadata); } else { - assertEquals("Test Compute Provider", providerMetadata.getName()); - assertEquals("test-compute-provider", providerMetadata.getId()); - assertEquals(ProviderMetadata.COMPUTE_TYPE, providerMetadata.getType()); - assertEquals("http://jclouds.org", providerMetadata.getHomepage().toString()); - assertEquals("http://jclouds.org/console", providerMetadata.getConsole().toString()); + assertEquals(testComputeProvider, providerMetadata); } } } diff --git a/core/src/test/java/org/jclouds/rest/CredentialStoreModuleTest.java b/core/src/test/java/org/jclouds/rest/CredentialStoreModuleTest.java index 6176e861ce..7ed4ef04c7 100755 --- a/core/src/test/java/org/jclouds/rest/CredentialStoreModuleTest.java +++ b/core/src/test/java/org/jclouds/rest/CredentialStoreModuleTest.java @@ -28,10 +28,10 @@ import java.util.concurrent.ConcurrentHashMap; import org.jclouds.crypto.PemsTest; import org.jclouds.domain.Credentials; +import org.jclouds.io.CopyInputStreamInputSupplierMap; import org.jclouds.json.Json; import org.jclouds.json.config.GsonModule; import org.jclouds.rest.config.CredentialStoreModule; -import org.jclouds.rest.config.CredentialStoreModule.CopyInputStreamInputSupplierMap; import org.jclouds.util.Strings2; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -46,7 +46,7 @@ import com.google.inject.TypeLiteral; * * @author Adrian Cole */ -@Test(groups = "unit", sequential = true) +@Test(groups = "unit", singleThreaded = true) public class CredentialStoreModuleTest { Json json = createInjector().getInstance(Json.class); diff --git a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java index 7b1a94c379..7bc2fe2e06 100755 --- a/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java +++ b/core/src/test/java/org/jclouds/rest/internal/RestAnnotationProcessorTest.java @@ -97,6 +97,7 @@ import org.jclouds.http.functions.ReturnInputStream; import org.jclouds.http.functions.ReturnStringIf2xx; import org.jclouds.http.functions.ReturnTrueIf2xx; import org.jclouds.http.functions.UnwrapOnlyJsonValue; +import org.jclouds.http.functions.UnwrapOnlyJsonValueInSet; import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue; import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet; import org.jclouds.http.internal.PayloadEnclosingImpl; @@ -833,7 +834,13 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { @Unwrap(depth = 2) @Consumes(MediaType.APPLICATION_JSON) ListenableFuture testUnwrapDepth2Long(); - + + @GET + @Path("/") + @Unwrap(depth = 2, edgeCollection = Set.class) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture testUnwrapDepth2Set(); + @GET @Path("/") @Unwrap(depth = 3, edgeCollection = Set.class) @@ -1033,6 +1040,23 @@ public class RestAnnotationProcessorTest extends BaseRestClientTest { . of()); } + @SuppressWarnings("unchecked") + public void testUnwrapDepth2Set() throws SecurityException, NoSuchMethodException, IOException { + Method method = TestPut.class.getMethod("testUnwrapDepth2Set"); + HttpRequest request = factory(TestPut.class).createRequest(method); + + assertResponseParserClassEquals(method, request, UnwrapOnlyJsonValueInSet.class); + // now test that it works! + + Function> parser = (Function>) RestAnnotationProcessor + .createResponseParser(parserFactory, injector, method, request); + + assertEquals(parser.apply(new HttpResponse(200, "ok", + newStringPayload("{\"runit\":[\"0.7.0\"]}"))), "0.7.0"); + + assertEquals(parser.apply(new HttpResponse(200, "ok", newStringPayload("{\"runit\":[]}"))), null); + } + @SuppressWarnings("unchecked") public void testUnwrapDepth2Long() throws SecurityException, NoSuchMethodException, IOException { Method method = TestPut.class.getMethod("testUnwrapDepth2Long"); diff --git a/drivers/apachehc/pom.xml b/drivers/apachehc/pom.xml index 259e2d3418..230050a0c4 100644 --- a/drivers/apachehc/pom.xml +++ b/drivers/apachehc/pom.xml @@ -2,7 +2,7 @@ @@ -72,4 +72,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.http.apachehc.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/drivers/bouncycastle/pom.xml b/drivers/bouncycastle/pom.xml index 509947753f..e04f55fc33 100644 --- a/drivers/bouncycastle/pom.xml +++ b/drivers/bouncycastle/pom.xml @@ -2,7 +2,7 @@ @@ -65,4 +66,21 @@ compile + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.encryption.bouncycastle.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/drivers/enterprise/pom.xml b/drivers/enterprise/pom.xml index 0d7f5df73c..c615581773 100644 --- a/drivers/enterprise/pom.xml +++ b/drivers/enterprise/pom.xml @@ -2,7 +2,7 @@ @@ -79,4 +80,20 @@ test + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.enterprise.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/drivers/gae/pom.xml b/drivers/gae/pom.xml index b3efa6df2c..c0def2b73e 100644 --- a/drivers/gae/pom.xml +++ b/drivers/gae/pom.xml @@ -2,7 +2,7 @@ @@ -96,6 +97,17 @@ classes + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.gae.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + diff --git a/drivers/joda/pom.xml b/drivers/joda/pom.xml index 46e1193d7b..f188822bcf 100644 --- a/drivers/joda/pom.xml +++ b/drivers/joda/pom.xml @@ -33,6 +33,7 @@ jclouds-joda jclouds joda DateService Module jclouds joda DateService Module + bundle @@ -65,5 +66,22 @@ compile + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.date.joda.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/drivers/jsch/pom.xml b/drivers/jsch/pom.xml index 3312006077..7b74008307 100644 --- a/drivers/jsch/pom.xml +++ b/drivers/jsch/pom.xml @@ -33,6 +33,7 @@ jclouds-jsch jclouds jsch ssh client jclouds jsch ssh client + bundle @@ -74,4 +75,20 @@ 1.4 + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.ssh.jsch.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/drivers/log4j/pom.xml b/drivers/log4j/pom.xml index d29b710675..17cfdcbb6e 100644 --- a/drivers/log4j/pom.xml +++ b/drivers/log4j/pom.xml @@ -33,6 +33,7 @@ jclouds-log4j jclouds Log4J Logging Module jclouds Log4J Logging Module + bundle @@ -65,4 +66,21 @@ compile + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.logging.log4j.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/drivers/netty/pom.xml b/drivers/netty/pom.xml index 779bd1c909..77c9717183 100644 --- a/drivers/netty/pom.xml +++ b/drivers/netty/pom.xml @@ -33,6 +33,7 @@ jclouds-netty jclouds netty payload module jclouds netty payload module + bundle @@ -78,5 +79,21 @@ compile - + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.netty.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + + diff --git a/drivers/slf4j/pom.xml b/drivers/slf4j/pom.xml index 2efee1fa53..6d0760c45d 100644 --- a/drivers/slf4j/pom.xml +++ b/drivers/slf4j/pom.xml @@ -2,7 +2,7 @@ @@ -65,4 +66,21 @@ compile + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.logging.slf4j.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/loadbalancer/pom.xml b/loadbalancer/pom.xml index 0436777819..7fd66622ea 100644 --- a/loadbalancer/pom.xml +++ b/loadbalancer/pom.xml @@ -32,6 +32,7 @@ jclouds-loadbalancer jclouds loadbalancer core jclouds components to access loadbalancer providers + bundle @@ -75,4 +76,20 @@ test + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.loadbalancer.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + jclouds-core;version="${project.version}" + + + + + diff --git a/project/pom.xml b/project/pom.xml index d1054b8655..200680d0a5 100644 --- a/project/pom.xml +++ b/project/pom.xml @@ -525,6 +525,17 @@ pageTracker._trackPageview(); maven-release-plugin 2.1 + + org.apache.felix + maven-bundle-plugin + 2.3.4 + true + + + <_nouses>true + + + diff --git a/providers/aws-ec2/pom.xml b/providers/aws-ec2/pom.xml index d566f55547..8634072915 100644 --- a/providers/aws-ec2/pom.xml +++ b/providers/aws-ec2/pom.xml @@ -33,6 +33,7 @@ aws-ec2 jclouds Amazon EC2 provider EC2 implementation targeted to Amazon Web Services + bundle https://ec2.us-east-1.amazonaws.com @@ -141,6 +142,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.aws.ec2.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ProviderMetadata.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ProviderMetadata.java new file mode 100644 index 0000000000..4932440b60 --- /dev/null +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ProviderMetadata.java @@ -0,0 +1,108 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2; + +import java.net.URI; +import java.util.Set; + +import org.jclouds.providers.BaseProviderMetadata; +import org.jclouds.providers.ProviderMetadata; + +import com.google.common.collect.ImmutableSet; + +/** + * Implementation of {@ link org.jclouds.types.ProviderMetadata} for Amazon's + * Elastic Compute Cloud (EC2) provider. + * + * @author Jeremy Whitlock + */ +public class AWSEC2ProviderMetadata extends BaseProviderMetadata { + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return "aws-ec2"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getType() { + return ProviderMetadata.COMPUTE_TYPE; + } + + /** + * {@inheritDoc} + */ + @Override + public String getName() { + return "Amazon Elastic Compute Cloud (EC2)"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentityName() { + return "Access Key ID"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getCredentialName() { + return "Secret Access Key"; + } + + /** + * {@inheritDoc} + */ + @Override + public URI getHomepage() { + return URI.create("http://aws.amazon.com/ec2/"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getConsole() { + return URI.create("https://console.aws.amazon.com/ec2/home"); + } + /** + * {@inheritDoc} + */ + @Override + public URI getApiDocumentation() { + return URI.create("http://docs.amazonwebservices.com/AWSEC2/latest/APIReference"); + } + + /** + * {@inheritDoc} + */ + @Override + public Set getLinkedServices() { + return ImmutableSet.of("aws-s3", "aws-ec2", "aws-elb", "aws-simpledb"); + } + +} \ No newline at end of file diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java index 63ffece204..b0a4d8ae9c 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/compute/AWSEC2ComputeService.java @@ -36,6 +36,7 @@ import org.jclouds.aws.ec2.domain.PlacementGroup; import org.jclouds.aws.ec2.domain.PlacementGroup.State; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.callables.RunScriptOnNode; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; @@ -85,7 +86,8 @@ public class AWSEC2ComputeService extends EC2ComputeService { @Named("NODE_RUNNING") Predicate nodeRunning, @Named("NODE_TERMINATED") Predicate nodeTerminated, @Named("NODE_SUSPENDED") Predicate nodeSuspended, - InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, + InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, + RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess, PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, AWSEC2Client ec2Client, Map credentialsMap, @Named("SECURITY") Map securityGroupMap, @@ -94,8 +96,8 @@ public class AWSEC2ComputeService extends EC2ComputeService { super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy, stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, nodeSuspended, - initScriptRunnerFactory, initAdminAccess, persistNodeCredentials, timeouts, executor, ec2Client, - credentialsMap, securityGroupMap); + initScriptRunnerFactory, runScriptOnNodeFactory, initAdminAccess, persistNodeCredentials, timeouts, + executor, ec2Client, credentialsMap, securityGroupMap); this.ec2Client = ec2Client; this.placementGroupMap = placementGroupMap; this.placementGroupDeleted = placementGroupDeleted; diff --git a/providers/aws-ec2/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata b/providers/aws-ec2/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata new file mode 100644 index 0000000000..636b065928 --- /dev/null +++ b/providers/aws-ec2/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata @@ -0,0 +1 @@ +org.jclouds.aws.ec2.AWSEC2ProviderMetadata diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2ProviderTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2ProviderTest.java new file mode 100644 index 0000000000..38b9361748 --- /dev/null +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2ProviderTest.java @@ -0,0 +1,37 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.ec2; + +import org.jclouds.aws.ec2.AWSEC2ProviderMetadata; +import org.jclouds.providers.BaseProviderMetadataTest; +import org.jclouds.providers.ProviderMetadata; +import org.testng.annotations.Test; + +/** + * The AWSEC2ProviderTest tests the org.jclouds.providers.AWSEC2Provider class. + * + * @author Jeremy Whitlock + */ +@Test(groups = "unit", testName = "AWSEC2ProviderTest") +public class AWSEC2ProviderTest extends BaseProviderMetadataTest { + + public AWSEC2ProviderTest() { + super(new AWSEC2ProviderMetadata(), ProviderMetadata.COMPUTE_TYPE); + } +} \ No newline at end of file diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java index c796c76c71..b4879582ec 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/compute/strategy/AWSEC2ImageParserTest.java @@ -125,11 +125,11 @@ public class AWSEC2ImageParserTest { assertEquals( new Gson().toJson(Iterables.get(result, 1)), - "{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}"); + "{\"operatingSystem\":{\"family\":\"UBUNTU\",\"arch\":\"paravirtual\",\"version\":\"9.10\",\"description\":\"411009282317/RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"is64Bit\":true},\"version\":\"4.5.3_EBS_Alpha\",\"description\":\"RightImage_Ubuntu_9.10_x64_v4.5.3_EBS_Alpha\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-c19db6b5\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-c19db6b5\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}"); assertEquals( new Gson().toJson(Iterables.get(result, 2)), - "{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"providerId\":\"ami-710c2605\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}"); + "{\"operatingSystem\":{\"family\":\"WINDOWS\",\"arch\":\"hvm\",\"version\":\"2003\",\"description\":\"411009282317/RightImage Windows_2003_i386_v5.4.3\",\"is64Bit\":false},\"version\":\"5.4.3\",\"description\":\"Built by RightScale\",\"defaultCredentials\":{\"identity\":\"root\"},\"id\":\"us-east-1/ami-710c2605\",\"type\":\"IMAGE\",\"tags\":[],\"providerId\":\"ami-710c2605\",\"location\":{\"scope\":\"REGION\",\"id\":\"us-east-1\",\"description\":\"us-east-1\",\"iso3166Codes\":[],\"metadata\":{}},\"userMetadata\":{\"owner\":\"411009282317\",\"rootDeviceType\":\"ebs\"}}"); } public void testParseAmznImage() { diff --git a/providers/aws-s3/pom.xml b/providers/aws-s3/pom.xml index 30edbe413e..118fc1bd83 100644 --- a/providers/aws-s3/pom.xml +++ b/providers/aws-s3/pom.xml @@ -33,6 +33,7 @@ aws-s3 jclouds Amazon Simple Storage Service (S3) provider Simple Storage Service (S3) implementation targeted to Amazon Web Services + bundle org.jclouds.aws.s3.blobstore.integration.AWSS3TestInitializer @@ -165,6 +166,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.aws.s3.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/aws-s3/src/main/java/org/jclouds/aws/s3/AWSS3ProviderMetadata.java b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/AWSS3ProviderMetadata.java new file mode 100644 index 0000000000..173dff1956 --- /dev/null +++ b/providers/aws-s3/src/main/java/org/jclouds/aws/s3/AWSS3ProviderMetadata.java @@ -0,0 +1,109 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.aws.s3; + +import java.net.URI; +import java.util.Set; + +import org.jclouds.providers.BaseProviderMetadata; +import org.jclouds.providers.ProviderMetadata; + +import com.google.common.collect.ImmutableSet; + +/** + * Implementation of @ link org.jclouds.types.ProviderMetadata} for Amazon's Simple Storage Service + * (S3) provider. + * + * @author Adrian Cole + */ +public class AWSS3ProviderMetadata extends BaseProviderMetadata { + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return "aws-s3"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getType() { + return ProviderMetadata.BLOBSTORE_TYPE; + } + + /** + * {@inheritDoc} + */ + @Override + public String getName() { + return "Amazon Simple Storage Service (S3)"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentityName() { + return "Access Key ID"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getCredentialName() { + return "Secret Access Key"; + } + + /** + * {@inheritDoc} + */ + @Override + public URI getHomepage() { + return URI.create("http://aws.amazon.com/s3/"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getConsole() { + return URI.create("https://console.aws.amazon.com/s3/home"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getApiDocumentation() { + return URI.create("http://docs.amazonwebservices.com/AmazonS3/latest/API"); + } + + /** + * {@inheritDoc} + */ + @Override + public Set getLinkedServices() { + return ImmutableSet.of("aws-s3", "aws-ec2", "aws-elb", "aws-simpledb"); + } + +} \ No newline at end of file diff --git a/providers/aws-s3/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata b/providers/aws-s3/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata new file mode 100644 index 0000000000..be3179d7be --- /dev/null +++ b/providers/aws-s3/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata @@ -0,0 +1 @@ +org.jclouds.aws.s3.AWSS3ProviderMetadata diff --git a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/ProvidersInPropertiesTest.java b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ProviderTest.java similarity index 68% rename from providers/aws-s3/src/test/java/org/jclouds/aws/s3/ProvidersInPropertiesTest.java rename to providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ProviderTest.java index e63a4b95dd..397c4ba7bf 100644 --- a/providers/aws-s3/src/test/java/org/jclouds/aws/s3/ProvidersInPropertiesTest.java +++ b/providers/aws-s3/src/test/java/org/jclouds/aws/s3/AWSS3ProviderTest.java @@ -18,23 +18,19 @@ */ package org.jclouds.aws.s3; -import org.jclouds.rest.Providers; +import org.jclouds.providers.BaseProviderMetadataTest; +import org.jclouds.providers.ProviderMetadata; import org.testng.annotations.Test; -import com.google.common.collect.Iterables; - /** + * The AWSS3ProviderTest tests the org.jclouds.providers.AWSS3Provider class. * * @author Adrian Cole - * */ -@Test(groups = "unit") -public class ProvidersInPropertiesTest { - - @Test - public void testSupportedProviders() { - Iterable providers = Providers.getSupportedProviders(); - assert Iterables.contains(providers, "aws-s3") : providers; - } +@Test(groups = "unit", testName = "AWSS3ProviderTest") +public class AWSS3ProviderTest extends BaseProviderMetadataTest { -} + public AWSS3ProviderTest() { + super(new AWSS3ProviderMetadata(), ProviderMetadata.BLOBSTORE_TYPE); + } +} \ No newline at end of file diff --git a/providers/azureblob/pom.xml b/providers/azureblob/pom.xml index aa20937509..4d5389cfb7 100644 --- a/providers/azureblob/pom.xml +++ b/providers/azureblob/pom.xml @@ -33,6 +33,7 @@ azureblob jclouds Azure Storage provider jclouds components to access Azure Blob Service + bundle org.jclouds.azureblob.blobstore.integration.AzureBlobTestInitializer @@ -138,6 +139,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.azureblob.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/bluelock-vcdirector/pom.xml b/providers/bluelock-vcdirector/pom.xml index 7008d578c6..648c9d57a0 100644 --- a/providers/bluelock-vcdirector/pom.xml +++ b/providers/bluelock-vcdirector/pom.xml @@ -33,6 +33,7 @@ bluelock-vcdirector jclouds BlueLock vCloud Director provider vCloud implementation targeted to BlueLock + bundle https://vcenterprise.bluelock.com/api @@ -143,6 +144,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.vcloud.bluelock.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/cloudfiles-uk/pom.xml b/providers/cloudfiles-uk/pom.xml index b2d1169944..cb512c9597 100644 --- a/providers/cloudfiles-uk/pom.xml +++ b/providers/cloudfiles-uk/pom.xml @@ -33,6 +33,7 @@ cloudfiles-uk jclouds CloudFiles UK provider CloudFiles implementation targeted to Rackspace UK + bundle org.jclouds.rackspace.cloudfiles.blobstore.integration.CloudFilesUKTestInitializer @@ -146,6 +147,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.rackspace.cloudfiles.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/cloudfiles-us/pom.xml b/providers/cloudfiles-us/pom.xml index 43aea106b5..f0457f37db 100644 --- a/providers/cloudfiles-us/pom.xml +++ b/providers/cloudfiles-us/pom.xml @@ -33,6 +33,7 @@ cloudfiles-us jclouds CloudFiles US provider CloudFiles implementation targeted to Rackspace US + bundle org.jclouds.rackspace.cloudfiles.blobstore.integration.CloudFilesUSTestInitializer @@ -146,6 +147,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.rackspace.cloudfiles.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/cloudloadbalancers-us/pom.xml b/providers/cloudloadbalancers-us/pom.xml index d75be50da9..1cca29a863 100644 --- a/providers/cloudloadbalancers-us/pom.xml +++ b/providers/cloudloadbalancers-us/pom.xml @@ -34,6 +34,7 @@ cloudloadbalancers-us jclouds cloudloadbalancers-us core jclouds components to access cloudloadbalancers-us + bundle https://auth.api.rackspacecloud.com @@ -122,4 +123,20 @@ + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.rackspace.cloudloadbalancers.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancer.java b/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancer.java index e8321bf339..757ecc092a 100644 --- a/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancer.java +++ b/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancer.java @@ -141,7 +141,7 @@ public class LoadBalancer extends BaseLoadBalancer { } @Override - public Builder port(int port) { + public Builder port(Integer port) { return Builder.class.cast(super.port(port)); } @@ -218,7 +218,7 @@ public class LoadBalancer extends BaseLoadBalancer { private final Date updated; private final boolean connectionLoggingEnabled; - public LoadBalancer(String region, int id, String name, String protocol, int port, String algorithm, Status status, + public LoadBalancer(String region, int id, String name, String protocol, Integer port, String algorithm, Status status, Iterable virtualIPs, Iterable nodes, String sessionPersistenceType, String clusterName, Date created, Date updated, boolean connectionLoggingEnabled) { super(name, protocol, port, algorithm, nodes); diff --git a/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancerRequest.java b/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancerRequest.java index f69e4a54df..9d7bbec8a5 100644 --- a/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancerRequest.java +++ b/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/domain/LoadBalancerRequest.java @@ -105,7 +105,7 @@ public class LoadBalancerRequest extends BaseLoadBalancer, T extends BaseLoadBalancer< public static class Builder, T extends BaseLoadBalancer> { protected String name; protected String protocol; - protected int port = -1; + protected Integer port; protected String algorithm; protected Set nodes = Sets.newLinkedHashSet(); @@ -64,7 +63,7 @@ public class BaseLoadBalancer, T extends BaseLoadBalancer< return this; } - public Builder port(int port) { + public Builder port(Integer port) { this.port = port; return this; } @@ -103,17 +102,16 @@ public class BaseLoadBalancer, T extends BaseLoadBalancer< protected String name; protected String protocol; - protected int port; + protected Integer port; protected String algorithm; // so tests will come out consistently protected SortedSet nodes = ImmutableSortedSet.of(); - public BaseLoadBalancer(String name, String protocol, int port, String algorithm, Iterable nodes) { + public BaseLoadBalancer(String name, String protocol, Integer port, String algorithm, Iterable nodes) { this.name = checkNotNull(name, "name"); - this.protocol = checkNotNull(protocol, "protocol"); - checkArgument(port != -1, "port must be specified"); - this.port = port; - this.algorithm = algorithm; + this.protocol = protocol;// null on deleted LB + this.port = port;// null on deleted LB + this.algorithm = algorithm;// null on deleted LB this.nodes = ImmutableSortedSet.copyOf(checkNotNull(nodes, "nodes")); } @@ -130,7 +128,7 @@ public class BaseLoadBalancer, T extends BaseLoadBalancer< return protocol; } - public int getPort() { + public Integer getPort() { return port; } @@ -144,8 +142,8 @@ public class BaseLoadBalancer, T extends BaseLoadBalancer< @Override public int hashCode() { - final int prime = 31; - int result = 1; + final Integer prime = 31; + Integer result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } diff --git a/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClient.java b/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClient.java index c62319c891..ee50ea4b04 100644 --- a/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClient.java +++ b/providers/cloudloadbalancers-us/src/main/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClient.java @@ -106,6 +106,7 @@ public interface LoadBalancerAsyncClient { @DELETE @ExceptionParser(ReturnVoidOnNotFoundOr404.class) @Path("/loadbalancers/{id}") + @Consumes("*/*") ListenableFuture removeLoadBalancer(@PathParam("id") int id); } diff --git a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClientTest.java b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClientTest.java index cefc0bebce..16692d3763 100644 --- a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClientTest.java +++ b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerAsyncClientTest.java @@ -147,7 +147,7 @@ public class LoadBalancerAsyncClientTest extends BaseCloudLoadBalancersAsyncClie assertRequestLineEquals(httpRequest, "DELETE https://dfw.loadbalancers.api.rackspacecloud.com/v1.0/1234/loadbalancers/5 HTTP/1.1"); - assertNonPayloadHeadersEqual(httpRequest, ""); + assertNonPayloadHeadersEqual(httpRequest, "Accept: */*\n"); assertPayloadEquals(httpRequest, null, null, false); assertResponseParserClassEquals(method, httpRequest, ReleasePayloadAndReturn.class); diff --git a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerClientLiveTest.java b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerClientLiveTest.java index a6199de47f..9eddff9a5d 100644 --- a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerClientLiveTest.java +++ b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/features/LoadBalancerClientLiveTest.java @@ -44,7 +44,6 @@ import com.google.common.collect.Sets; public class LoadBalancerClientLiveTest extends BaseCloudLoadBalancersClientLiveTest { private Set lbs = Sets.newLinkedHashSet(); - // ticket 130960 getting 500 errors deleting load balancers @AfterGroups(groups = "live") protected void tearDown() { for (LoadBalancer lb : lbs) { @@ -60,6 +59,8 @@ public class LoadBalancerClientLiveTest extends BaseCloudLoadBalancersClientLive assert null != response; assertTrue(response.size() >= 0); for (LoadBalancer lb : response) { + if (lb.getStatus() == LoadBalancer.Status.DELETED) + continue; assert lb.getRegion() != null : lb; assert lb.getName() != null : lb; assert lb.getId() != -1 : lb; @@ -73,17 +74,21 @@ public class LoadBalancerClientLiveTest extends BaseCloudLoadBalancersClientLive assert lb.getNodes().size() == 0 : lb; LoadBalancer getDetails = client.getLoadBalancerClient(region).getLoadBalancer(lb.getId()); - assertEquals(getDetails.getRegion(), lb.getRegion()); - assertEquals(getDetails.getName(), lb.getName()); - assertEquals(getDetails.getId(), lb.getId()); - assertEquals(getDetails.getProtocol(), lb.getProtocol()); - assertEquals(getDetails.getPort(), lb.getPort()); - assertEquals(getDetails.getStatus(), lb.getStatus()); - assertEquals(getDetails.getCreated(), lb.getCreated()); - assertEquals(getDetails.getUpdated(), lb.getUpdated()); - assertEquals(getDetails.getVirtualIPs(), lb.getVirtualIPs()); - // node info not available during list; - assert getDetails.getNodes().size() > 0 : lb; + try { + assertEquals(getDetails.getRegion(), lb.getRegion()); + assertEquals(getDetails.getName(), lb.getName()); + assertEquals(getDetails.getId(), lb.getId()); + assertEquals(getDetails.getProtocol(), lb.getProtocol()); + assertEquals(getDetails.getPort(), lb.getPort()); + assertEquals(getDetails.getStatus(), lb.getStatus()); + assertEquals(getDetails.getCreated(), lb.getCreated()); + assertEquals(getDetails.getUpdated(), lb.getUpdated()); + assertEquals(getDetails.getVirtualIPs(), lb.getVirtualIPs()); + // node info not available during list; + assert getDetails.getNodes().size() > 0 : lb; + } catch (AssertionError e) { + throw new AssertionError(String.format("%s\n%s - %s", e.getMessage(),getDetails, lb)); + } } } } @@ -122,7 +127,7 @@ public class LoadBalancerClientLiveTest extends BaseCloudLoadBalancersClientLive assertEquals(lb.getRegion(), region); assertEquals(lb.getName(), name); assertEquals(lb.getProtocol(), "HTTP"); - assertEquals(lb.getPort(), 80); + assertEquals(lb.getPort(), new Integer(80)); assertEquals(Iterables.get(lb.getVirtualIPs(), 0).getType(), Type.PUBLIC); } diff --git a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancerTest.java b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancerTest.java index e93fcae313..44dffb8673 100644 --- a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancerTest.java +++ b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancerTest.java @@ -39,11 +39,6 @@ import com.google.inject.Injector; @Test(groups = "unit") public class UnwrapLoadBalancerTest extends BaseItemParserTest { - @Override - public Class type() { - return LoadBalancer.class; - } - @Override public String resource() { return "/getloadbalancer.json"; @@ -73,7 +68,7 @@ public class UnwrapLoadBalancerTest extends BaseItemParserTest { } @Override - protected Function getParser(Injector i) { + protected Function parser(Injector i) { return i.getInstance(UnwrapLoadBalancer.class).setRegion("DFW"); } } diff --git a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancersTest.java b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancersTest.java index 9a55b7a3fb..c34aa7c3ba 100644 --- a/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancersTest.java +++ b/providers/cloudloadbalancers-us/src/test/java/org/jclouds/cloudloadbalancers/functions/UnwrapLoadBalancersTest.java @@ -39,11 +39,6 @@ import com.google.inject.Injector; @Test(groups = "unit") public class UnwrapLoadBalancersTest extends BaseSetParserTest { - @Override - public Class type() { - return LoadBalancer.class; - } - @Override public String resource() { return "/listloadbalancers.json"; @@ -70,7 +65,7 @@ public class UnwrapLoadBalancersTest extends BaseSetParserTest { } @Override - protected Function> getParser(Injector i) { + protected Function> parser(Injector i) { return i.getInstance(UnwrapLoadBalancers.class).setRegion("DFW"); } } diff --git a/providers/cloudonestorage/pom.xml b/providers/cloudonestorage/pom.xml index b035c2d9c8..faf627d65f 100644 --- a/providers/cloudonestorage/pom.xml +++ b/providers/cloudonestorage/pom.xml @@ -33,6 +33,7 @@ cloudonestorage jclouds CloudOne Storage as a Service provider Atmos implementation targeted to Peer1 CloudOne Storage as a Service + bundle org.jclouds.cloudonestorage.blobstore.integration.CloudOneStorageTestInitializer @@ -139,6 +140,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.cloudonestorage.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/cloudservers-uk/pom.xml b/providers/cloudservers-uk/pom.xml index a3450706cb..cf661a8faf 100644 --- a/providers/cloudservers-uk/pom.xml +++ b/providers/cloudservers-uk/pom.xml @@ -33,6 +33,7 @@ cloudservers-uk jclouds CloudServers UK provider CloudServers implementation targeted to Rackspace UK + bundle https://lon.auth.api.rackspacecloud.com @@ -141,6 +142,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.rackspace.cloudservers.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/cloudservers-us/pom.xml b/providers/cloudservers-us/pom.xml index fa90b3d3fd..19ac0bf45f 100644 --- a/providers/cloudservers-us/pom.xml +++ b/providers/cloudservers-us/pom.xml @@ -33,6 +33,7 @@ cloudservers-us jclouds CloudServers US provider CloudServers implementation targeted to Rackspace US + bundle https://auth.api.rackspacecloud.com @@ -141,6 +142,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.rackspace.cloudservers.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/cloudsigma-zrh/pom.xml b/providers/cloudsigma-zrh/pom.xml index e2755db738..c73e1220f7 100644 --- a/providers/cloudsigma-zrh/pom.xml +++ b/providers/cloudsigma-zrh/pom.xml @@ -34,6 +34,7 @@ cloudsigma-zrh jclouds CloudSigma provider ComputeService binding to the CloudSigma datacenter in Zürich + bundle @@ -134,4 +135,21 @@ + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.cloudsigma.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/providers/elastichosts-lon-b/pom.xml b/providers/elastichosts-lon-b/pom.xml index 5c81c79319..a9cacc91be 100644 --- a/providers/elastichosts-lon-b/pom.xml +++ b/providers/elastichosts-lon-b/pom.xml @@ -33,6 +33,7 @@ elastichosts-lon-b jclouds ElasticHosts BlueSquare London provider ElasticHosts implementation targeted to BlueSquare London + bundle https://api.lon-b.elastichosts.com @@ -136,6 +137,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.elastichosts.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/elastichosts-lon-p/pom.xml b/providers/elastichosts-lon-p/pom.xml index 430c555e7a..b6428a30d2 100644 --- a/providers/elastichosts-lon-p/pom.xml +++ b/providers/elastichosts-lon-p/pom.xml @@ -33,6 +33,7 @@ elastichosts-lon-p jclouds ElasticHosts Peer1 London provider ElasticHosts implementation targeted to Peer1 London + bundle https://api.lon-p.elastichosts.com @@ -136,6 +137,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.elastichosts.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/elastichosts-sat-p/pom.xml b/providers/elastichosts-sat-p/pom.xml index 45afee45a0..9d033963d1 100644 --- a/providers/elastichosts-sat-p/pom.xml +++ b/providers/elastichosts-sat-p/pom.xml @@ -33,6 +33,7 @@ elastichosts-sat-p jclouds ElasticHosts Peer1 San Antonio provider ElasticHosts implementation targeted to Peer1 San Antonio + bundle https://api.sat-p.elastichosts.com @@ -136,6 +137,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.elastichosts.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/eucalyptus-partnercloud-ec2/pom.xml b/providers/eucalyptus-partnercloud-ec2/pom.xml index 745a89c7ea..10f626e397 100644 --- a/providers/eucalyptus-partnercloud-ec2/pom.xml +++ b/providers/eucalyptus-partnercloud-ec2/pom.xml @@ -33,6 +33,7 @@ eucalyptus-partnercloud-ec2 jclouds Eucalyptus Partner Cloud EC2 provider Eucalyptus (EC2) implementation targeted to the Eucalyptus Partner Cloud + bundle http://partnercloud.eucalyptus.com:8773/services/Eucalyptus @@ -155,6 +156,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.epc.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/eucalyptus-partnercloud-s3/pom.xml b/providers/eucalyptus-partnercloud-s3/pom.xml index f27ed56f13..b21814f6d9 100644 --- a/providers/eucalyptus-partnercloud-s3/pom.xml +++ b/providers/eucalyptus-partnercloud-s3/pom.xml @@ -33,6 +33,7 @@ eucalyptus-partnercloud-s3 jclouds Eucalyptus Partner Cloud provider Walrus (S3) implementation targeted to the Eucalyptus Partner Cloud + bundle org.jclouds.epc.blobstore.EucalyptusPartnerCloudWalrusTestInitializer @@ -151,6 +152,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.epc.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/gogrid/pom.xml b/providers/gogrid/pom.xml index d7168c4b2e..cb335d0d07 100644 --- a/providers/gogrid/pom.xml +++ b/providers/gogrid/pom.xml @@ -33,6 +33,7 @@ gogrid jclouds GoGrid provider ComputeService implementation of GoGrid datacenters + bundle @@ -132,4 +133,20 @@ + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.gogrid.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java index 4946eeedd6..c2e82e3788 100644 --- a/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java +++ b/providers/gogrid/src/main/java/org/jclouds/gogrid/compute/GoGridComputeService.java @@ -30,6 +30,7 @@ import javax.inject.Singleton; import org.jclouds.Constants; import org.jclouds.collect.Memoized; import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.callables.RunScriptOnNode; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.Image; import org.jclouds.compute.domain.NodeMetadata; @@ -71,12 +72,13 @@ public class GoGridComputeService extends BaseComputeService { @Named("NODE_TERMINATED") Predicate nodeTerminated, @Named("NODE_SUSPENDED") Predicate nodeSuspended, InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory, InitAdminAccess initAdminAccess, - PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, + RunScriptOnNode.Factory runScriptOnNodeFactory, PersistNodeCredentials persistNodeCredentials, Timeouts timeouts, @Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor) { super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated, - nodeSuspended, initScriptRunnerFactory, initAdminAccess, persistNodeCredentials, timeouts, executor); + nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials, timeouts, + executor); } /** diff --git a/providers/googlestorage/pom.xml b/providers/googlestorage/pom.xml index 7bb13e9189..1f4b81442a 100644 --- a/providers/googlestorage/pom.xml +++ b/providers/googlestorage/pom.xml @@ -33,6 +33,7 @@ googlestorage jclouds Google Storage for Developers provider Simple Storage Service (S3) implementation targeted to Google Storage for Developers + bundle org.jclouds.googlestorage.blobstore.GoogleStorageTestInitializer @@ -139,6 +140,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.googlestorage.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/hosteurope-storage/pom.xml b/providers/hosteurope-storage/pom.xml index a17ac14c26..2777fe6129 100644 --- a/providers/hosteurope-storage/pom.xml +++ b/providers/hosteurope-storage/pom.xml @@ -33,6 +33,7 @@ hosteurope-storage jclouds Host Europe Cloud Storage provider Scality RING (ScalityRS2) implementation targeted to Host Europe Cloud Storage + bundle org.jclouds.hosteurope.storage.blobstore.HostEuropeStorageTestInitializer @@ -146,6 +147,21 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.hosteurope.storage.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/ninefold-storage/pom.xml b/providers/ninefold-storage/pom.xml index be157c21b3..bf6230ad8f 100644 --- a/providers/ninefold-storage/pom.xml +++ b/providers/ninefold-storage/pom.xml @@ -33,6 +33,7 @@ ninefold-storage jclouds ninefold storage provider BlobStore implementation targeted to ninefold storage + bundle org.jclouds.ninefold.storage.blobstore.integration.NinefoldStorageTestInitializer @@ -139,6 +140,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.ninefold.storage.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/openhosting-east1/pom.xml b/providers/openhosting-east1/pom.xml index 02ed369e1e..4bd389b46e 100644 --- a/providers/openhosting-east1/pom.xml +++ b/providers/openhosting-east1/pom.xml @@ -33,6 +33,7 @@ openhosting-east1 jclouds Open Hosting East1 provider Open Hosting implementation targeted to East1 + bundle https://api.east1.openhosting.com @@ -136,6 +137,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.openhosting.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/savvis-symphonyvpdc/pom.xml b/providers/savvis-symphonyvpdc/pom.xml index 34edc7e952..0c19c904d2 100644 --- a/providers/savvis-symphonyvpdc/pom.xml +++ b/providers/savvis-symphonyvpdc/pom.xml @@ -34,6 +34,7 @@ savvis-symphonyvpdc jclouds savvis-vpdc vpdc jclouds components to access Savvis Symphony VPDC + bundle @@ -52,11 +53,11 @@ node-924 - https://api.symphonyvpdc.savvis.net/rest/api - 0.8 + https://api.symphonyvpdc.savvis.net/vpdc + 1.0 FIXME FIXME - FIXME + FIXME FIXME FIXME @@ -143,7 +144,7 @@ ${test.savvis-symphonyvpdc.credential} - savvis-symphonyvpdc.vpdc-email + test.savvis-symphonyvpdc.vdc-email ${test.savvis-symphonyvpdc.vdc-email} @@ -167,4 +168,20 @@ + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.savvis.vpdc.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BaseBindVMSpecToXmlPayload.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BaseBindVMSpecToXmlPayload.java new file mode 100644 index 0000000000..7737be725a --- /dev/null +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BaseBindVMSpecToXmlPayload.java @@ -0,0 +1,210 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.savvis.vpdc.binders; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.Map; +import java.util.Properties; +import java.util.Map.Entry; + +import javax.ws.rs.core.MediaType; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; + +import org.jclouds.cim.ResourceAllocationSettingData.ResourceType; +import org.jclouds.compute.domain.CIMOperatingSystem; +import org.jclouds.http.HttpRequest; +import org.jclouds.rest.MapBinder; +import org.jclouds.rest.binders.BindToStringPayload; +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.savvis.vpdc.domain.VMSpec; + +import com.google.common.base.Throwables; +import com.jamesmurty.utils.XMLBuilder; + +/** + * + * @author Adrian Cole + * + */ +public abstract class BaseBindVMSpecToXmlPayload extends BindToStringPayload implements MapBinder { + @Override + public R bindToRequest(R request, Object toBind) { + throw new IllegalStateException("BindVMSpecToXmlPayload needs parameters"); + } + + protected abstract T findSpecInArgsOrNull(GeneratedHttpRequest gRequest); + + @Override + public R bindToRequest(R request, Map postParams) { + checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, + "this binder is only valid for GeneratedHttpRequests!"); + GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; + checkState(gRequest.getArgs() != null, "args should be initialized at this point"); + + request = super.bindToRequest(request, generateXml(findSpecInArgsOrNull(gRequest))); + request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_XML); + return request; + } + + public String generateXml(T spec) { + try { + XMLBuilder rootBuilder = buildRoot(); + bindSpec(spec, rootBuilder); + Properties outputProperties = new Properties(); + outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes"); + return rootBuilder.asString(outputProperties); + } catch (Exception e) { + Throwables.propagate(e); + return null; + } + } + + protected abstract void bindSpec(T spec, XMLBuilder rootBuilder) throws ParserConfigurationException, + FactoryConfigurationError; + + protected void checkSpec(VMSpec spec) { + checkNotNull(spec, "VMSpec"); + checkNotNull(spec.getName(), "name"); + checkNotNull(spec.getNetworkTierName(), "networkTierName"); + } + + protected void addOperatingSystemAndVirtualHardware(VMSpec spec, XMLBuilder vAppBuilder) { + addOperatingSystemSection(vAppBuilder, spec.getOperatingSystem()); + // TODO: Savvis returns network names with a - instead of space on getNetworkInVDC + // call, + // fix this once savvis api starts returning correctly + addVirtualHardwareSection(vAppBuilder, spec.getName(), spec.getNetworkTierName().replace("-", " "), spec); + } + + void addVirtualHardwareSection(XMLBuilder rootBuilder, String name, String networkName, VMSpec spec) { + XMLBuilder virtualHardwareSectionBuilder = rootBuilder.e("ovf:VirtualHardwareSection"); + virtualHardwareSectionBuilder.e("ovf:Info").t("Virtual Hardware"); + addSystem(virtualHardwareSectionBuilder, name); + addItems(virtualHardwareSectionBuilder, spec, networkName); + } + + void addItems(XMLBuilder virtualHardwareSectionBuilder, VMSpec spec, String networkName) { + // todo make this work with fractional, which I think means setting speed to half + addCPU(virtualHardwareSectionBuilder, (int) spec.getProcessorCount()); + addMemory(virtualHardwareSectionBuilder, spec.getMemoryInGig()); + addNetwork(virtualHardwareSectionBuilder, networkName); + addDisks(virtualHardwareSectionBuilder, spec); + } + + private void addSystem(XMLBuilder virtualHardwareSectionBuilder, String name) { + XMLBuilder systemBuilder = virtualHardwareSectionBuilder.e("ovf:System"); + systemBuilder.e("vssd:Description").t("Virtual Hardware Family"); + systemBuilder.e("vssd:ElementName").t(name); + systemBuilder.e("vssd:InstanceID").t("1"); + systemBuilder.e("vssd:VirtualSystemIdentifier").t(name); + } + + private void addOperatingSystemSection(XMLBuilder rootBuilder, CIMOperatingSystem operatingSystem) { + XMLBuilder sectionBuilder = rootBuilder.e("ovf:OperatingSystemSection").a("ovf:id", + operatingSystem.getOsType().getCode() + ""); + sectionBuilder.e("ovf:Info").t("Specifies the operating system installed"); + sectionBuilder.e("ovf:Description").t(operatingSystem.getDescription()); + } + + private void addCPU(XMLBuilder sectionBuilder, int processorCount) { + XMLBuilder cpuBuilder = sectionBuilder.e("ovf:Item"); + cpuBuilder.e("rasd:AllocationUnits").t("3 GHz"); + cpuBuilder.e("rasd:Description").t("Number of Virtual CPUs"); + cpuBuilder.e("rasd:ElementName").t(processorCount + " CPU"); + cpuBuilder.e("rasd:InstanceID").t("1"); + cpuBuilder.e("rasd:ResourceType").t(ResourceType.PROCESSOR.value()); + cpuBuilder.e("rasd:VirtualQuantity").t(processorCount + ""); + } + + private void addMemory(XMLBuilder sectionBuilder, int memoryInGig) { + XMLBuilder memoryBuilder = sectionBuilder.e("ovf:Item"); + memoryBuilder.e("rasd:AllocationUnits").t("Gigabytes"); + memoryBuilder.e("rasd:Description").t("Memory Size"); + memoryBuilder.e("rasd:ElementName").t("Memory"); + memoryBuilder.e("rasd:InstanceID").t("2"); + memoryBuilder.e("rasd:ResourceType").t(ResourceType.MEMORY.value()); + memoryBuilder.e("rasd:VirtualQuantity").t(memoryInGig + ""); + } + + private void addNetwork(XMLBuilder sectionBuilder, String networkName) { + XMLBuilder networkBuilder = sectionBuilder.e("ovf:Item"); + networkBuilder.e("rasd:Caption").t("false"); + networkBuilder.e("rasd:Connection").t(networkName); + networkBuilder.e("rasd:ElementName").t("Network"); + networkBuilder.e("rasd:InstanceID").t("3"); + networkBuilder.e("rasd:ResourceType").t(ResourceType.ETHERNET_ADAPTER.value()); + networkBuilder.e("rasd:VirtualQuantity").t("1"); + } + + private void addDisks(XMLBuilder sectionBuilder, VMSpec spec) { + XMLBuilder bootDiskBuilder = sectionBuilder.e("ovf:Item"); + bootDiskBuilder.e("rasd:AllocationUnits").t("Gigabytes"); + bootDiskBuilder.e("rasd:Caption").t(""); + bootDiskBuilder.e("rasd:Description").t("Hard Disk"); + bootDiskBuilder.e("rasd:ElementName").t(spec.getBootDeviceName()); + bootDiskBuilder.e("rasd:HostResource").t("boot"); + bootDiskBuilder.e("rasd:InstanceID").t("4"); + bootDiskBuilder.e("rasd:ResourceType").t(ResourceType.BASE_PARTITIONABLE_UNIT.value()); + bootDiskBuilder.e("rasd:VirtualQuantity").t(spec.getBootDiskSize() + ""); + + int instanceId = 5; + for (Entry dataDisk : spec.getDataDiskDeviceNameToSizeInGig().entrySet()) { + XMLBuilder dataDiskBuilder = sectionBuilder.e("ovf:Item"); + dataDiskBuilder.e("rasd:AllocationUnits").t("Gigabytes"); + dataDiskBuilder.e("rasd:Caption").t(""); + dataDiskBuilder.e("rasd:Description").t("Hard Disk"); + dataDiskBuilder.e("rasd:ElementName").t(dataDisk.getKey()); + dataDiskBuilder.e("rasd:HostResource").t("data"); + dataDiskBuilder.e("rasd:InstanceID").t("" + instanceId++); + dataDiskBuilder.e("rasd:ResourceType").t(ResourceType.PARTITIONABLE_UNIT.value()); + dataDiskBuilder.e("rasd:VirtualQuantity").t(dataDisk.getValue() + ""); + } + } + + protected XMLBuilder buildRoot() throws ParserConfigurationException, FactoryConfigurationError { + XMLBuilder rootBuilder = XMLBuilder.create("vApp:VApp").a("xmlns:vApp", "http://www.vmware.com/vcloud/v0.8").a( + "xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1").a("xmlns:vssd", + "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData").a("xmlns:common", + "http://schemas.dmtf.org/wbem/wscim/1/common").a("xmlns:rasd", + "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData"); + return rootBuilder; + } + + protected XMLBuilder buildChildren(XMLBuilder rootBuilder) throws ParserConfigurationException, + FactoryConfigurationError { + XMLBuilder vAppChildrenBuilder = rootBuilder.e("vApp:Children"); + return vAppChildrenBuilder; + } + + protected XMLBuilder buildRootForName(XMLBuilder rootBuilder, String name) throws ParserConfigurationException, + FactoryConfigurationError { + XMLBuilder vAppBuilder = rootBuilder.e("vApp:VApp").a("name", name).a("type", + "application/vnd.vmware.vcloud.vApp+xml"); + return vAppBuilder; + } + + protected String ifNullDefaultTo(String value, String defaultValue) { + return value != null ? value : checkNotNull(defaultValue, "defaultValue"); + } + +} diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindVMSpecToXmlPayload.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindVMSpecToXmlPayload.java index c80178d6b9..a3e8a4f18e 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindVMSpecToXmlPayload.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindVMSpecToXmlPayload.java @@ -18,26 +18,10 @@ */ package org.jclouds.savvis.vpdc.binders; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; - import javax.inject.Singleton; -import javax.ws.rs.core.MediaType; import javax.xml.parsers.FactoryConfigurationError; import javax.xml.parsers.ParserConfigurationException; -import org.jclouds.cim.ResourceAllocationSettingData.ResourceType; -import org.jclouds.compute.domain.CIMOperatingSystem; -import org.jclouds.http.HttpRequest; -import org.jclouds.rest.MapBinder; -import org.jclouds.rest.binders.BindToStringPayload; import org.jclouds.rest.internal.GeneratedHttpRequest; import org.jclouds.savvis.vpdc.domain.VMSpec; @@ -49,173 +33,23 @@ import com.jamesmurty.utils.XMLBuilder; * */ @Singleton -public class BindVMSpecToXmlPayload extends BindToStringPayload implements MapBinder { - @Override - public R bindToRequest(R request, Object toBind) { - throw new IllegalStateException("BindVMSpecToXmlPayload needs parameters"); +public class BindVMSpecToXmlPayload extends BaseBindVMSpecToXmlPayload { - } - - protected List findSpecInArgsOrNull(GeneratedHttpRequest gRequest) { + protected VMSpec findSpecInArgsOrNull(GeneratedHttpRequest gRequest) { for (Object arg : gRequest.getArgs()) { if (arg instanceof VMSpec) { - List vmSpecs = new ArrayList(); - vmSpecs.add((VMSpec) arg); - return vmSpecs; - } else if (arg instanceof ArrayList) { - List configurations = (List) arg; - return (configurations.size() > 0) ? configurations : null; + return VMSpec.class.cast(arg); } } - return null; + throw new IllegalArgumentException("Iterbable must be included in the argument list"); } @Override - public R bindToRequest(R request, Map postParams) { - checkArgument(checkNotNull(request, "request") instanceof GeneratedHttpRequest, - "this binder is only valid for GeneratedHttpRequests!"); - GeneratedHttpRequest gRequest = (GeneratedHttpRequest) request; - checkState(gRequest.getArgs() != null, "args should be initialized at this point"); - - request = super.bindToRequest(request, - generateXml(findSpecInArgsOrNull(gRequest))); - request.getPayload().getContentMetadata().setContentType(MediaType.APPLICATION_XML); - return request; - } - - public String generateXml(List specs) { - try { - XMLBuilder rootBuilder = buildRoot(); - XMLBuilder vAppChildrenBuilder = buildChildren(rootBuilder); - for (VMSpec spec : specs) { - checkNotNull(spec, "VMSpec"); - checkNotNull(spec.getName(), "name"); - checkNotNull(spec.getNetwork(), "network"); - checkNotNull(spec.getNetwork().getName(), "networkName"); - XMLBuilder vAppBuilder = buildRootForName(vAppChildrenBuilder, spec.getName()); - addOperatingSystemSection(vAppBuilder, spec.getOperatingSystem()); - // TODO: Savvis returns network names with a - instead of space on getNetworkInVDC call, - // fix this once savvis api starts returning correctly - addVirtualHardwareSection(vAppBuilder, spec.getName(), spec.getNetwork().getName().replace("-", " "), spec); - } - Properties outputProperties = new Properties(); - outputProperties.put(javax.xml.transform.OutputKeys.OMIT_XML_DECLARATION, "yes"); - return rootBuilder.asString(outputProperties); - } catch (Exception e) { - return null; - } - } - - void addVirtualHardwareSection(XMLBuilder rootBuilder, String name, String networkName, VMSpec spec) { - XMLBuilder virtualHardwareSectionBuilder = rootBuilder.e("ovf:VirtualHardwareSection"); - virtualHardwareSectionBuilder.e("ovf:Info").t("Virtual Hardware"); - addSystem(virtualHardwareSectionBuilder, name); - addItems(virtualHardwareSectionBuilder, spec, networkName); - } - - void addItems(XMLBuilder virtualHardwareSectionBuilder, VMSpec spec, String networkName) { - //todo make this work with fractional, which I think means setting speed to half - addCPU(virtualHardwareSectionBuilder, (int)spec.getProcessorCount()); - addMemory(virtualHardwareSectionBuilder, spec.getMemoryInGig()); - addNetwork(virtualHardwareSectionBuilder, networkName); - addDisks(virtualHardwareSectionBuilder, spec); - } - - private void addSystem(XMLBuilder virtualHardwareSectionBuilder, String name) { - XMLBuilder systemBuilder = virtualHardwareSectionBuilder.e("ovf:System"); - systemBuilder.e("vssd:Description").t("Virtual Hardware Family"); - systemBuilder.e("vssd:ElementName").t(name); - systemBuilder.e("vssd:InstanceID").t("1"); - systemBuilder.e("vssd:VirtualSystemIdentifier").t(name); - } - - private void addOperatingSystemSection(XMLBuilder rootBuilder, CIMOperatingSystem operatingSystem) { - XMLBuilder sectionBuilder = rootBuilder.e("ovf:OperatingSystemSection").a("ovf:id", - operatingSystem.getOsType().getCode() + ""); - sectionBuilder.e("ovf:Info").t("Specifies the operating system installed"); - sectionBuilder.e("ovf:Description").t(operatingSystem.getDescription()); - } - - private void addCPU(XMLBuilder sectionBuilder, int processorCount) { - XMLBuilder cpuBuilder = sectionBuilder.e("ovf:Item"); - cpuBuilder.e("rasd:AllocationUnits").t("3 GHz"); - cpuBuilder.e("rasd:Description").t("Number of Virtual CPUs"); - cpuBuilder.e("rasd:ElementName").t(processorCount + " CPU"); - cpuBuilder.e("rasd:InstanceID").t("1"); - cpuBuilder.e("rasd:ResourceType").t(ResourceType.PROCESSOR.value()); - cpuBuilder.e("rasd:VirtualQuantity").t(processorCount + ""); - } - - private void addMemory(XMLBuilder sectionBuilder, int memoryInGig) { - XMLBuilder memoryBuilder = sectionBuilder.e("ovf:Item"); - memoryBuilder.e("rasd:AllocationUnits").t("Gigabytes"); - memoryBuilder.e("rasd:Description").t("Memory Size"); - memoryBuilder.e("rasd:ElementName").t("Memory"); - memoryBuilder.e("rasd:InstanceID").t("2"); - memoryBuilder.e("rasd:ResourceType").t(ResourceType.MEMORY.value()); - memoryBuilder.e("rasd:VirtualQuantity").t(memoryInGig + ""); - } - - private void addNetwork(XMLBuilder sectionBuilder, String networkName) { - XMLBuilder networkBuilder = sectionBuilder.e("ovf:Item"); - networkBuilder.e("rasd:Caption").t("false"); - networkBuilder.e("rasd:Connection").t(networkName); - networkBuilder.e("rasd:ElementName").t("Network"); - networkBuilder.e("rasd:InstanceID").t("3"); - networkBuilder.e("rasd:ResourceType").t(ResourceType.ETHERNET_ADAPTER.value()); - networkBuilder.e("rasd:VirtualQuantity").t("1"); - } - - private void addDisks(XMLBuilder sectionBuilder, VMSpec spec) { - XMLBuilder bootDiskBuilder = sectionBuilder.e("ovf:Item"); - bootDiskBuilder.e("rasd:AllocationUnits").t("Gigabytes"); - bootDiskBuilder.e("rasd:Caption").t(""); - bootDiskBuilder.e("rasd:Description").t("Hard Disk"); - bootDiskBuilder.e("rasd:ElementName").t(spec.getBootDeviceName()); - bootDiskBuilder.e("rasd:HostResource").t("boot"); - bootDiskBuilder.e("rasd:InstanceID").t("4"); - bootDiskBuilder.e("rasd:ResourceType").t(ResourceType.BASE_PARTITIONABLE_UNIT.value()); - bootDiskBuilder.e("rasd:VirtualQuantity").t(spec.getBootDiskSize() + ""); - - int instanceId = 5; - for (Entry dataDisk : spec.getDataDiskDeviceNameToSizeInGig().entrySet()) { - XMLBuilder dataDiskBuilder = sectionBuilder.e("ovf:Item"); - dataDiskBuilder.e("rasd:AllocationUnits").t("Gigabytes"); - dataDiskBuilder.e("rasd:Caption").t(""); - dataDiskBuilder.e("rasd:Description").t("Hard Disk"); - dataDiskBuilder.e("rasd:ElementName").t(dataDisk.getKey()); - dataDiskBuilder.e("rasd:HostResource").t("data"); - dataDiskBuilder.e("rasd:InstanceID").t("" + instanceId++); - dataDiskBuilder.e("rasd:ResourceType").t(ResourceType.PARTITIONABLE_UNIT.value()); - dataDiskBuilder.e("rasd:VirtualQuantity").t(dataDisk.getValue() + ""); - } - } - - protected XMLBuilder buildRoot() throws ParserConfigurationException, FactoryConfigurationError { - XMLBuilder rootBuilder = XMLBuilder.create("vApp:VApp") - .a("xmlns:vApp", "http://www.vmware.com/vcloud/v0.8") - .a("xmlns:ovf", "http://schemas.dmtf.org/ovf/envelope/1") - .a("xmlns:vssd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_VirtualSystemSettingData") - .a("xmlns:common", "http://schemas.dmtf.org/wbem/wscim/1/common") - .a("xmlns:rasd", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData") - .a("name", ""); - return rootBuilder; - } - - protected XMLBuilder buildChildren(XMLBuilder rootBuilder) throws ParserConfigurationException, FactoryConfigurationError { - XMLBuilder vAppChildrenBuilder = rootBuilder.e("vApp:Children"); - return vAppChildrenBuilder; - } - - protected XMLBuilder buildRootForName(XMLBuilder rootBuilder, String name) throws ParserConfigurationException, FactoryConfigurationError { - XMLBuilder vAppBuilder = rootBuilder.e("vApp:VApp") - .a("name", name) - .a("type", "application/vnd.vmware.vcloud.vApp+xml"); - return vAppBuilder; - } - - protected String ifNullDefaultTo(String value, String defaultValue) { - return value != null ? value : checkNotNull(defaultValue, "defaultValue"); + protected void bindSpec(VMSpec spec, XMLBuilder rootBuilder) throws ParserConfigurationException, + FactoryConfigurationError { + checkSpec(spec); + rootBuilder.a("name", spec.getName()).a("type", "application/vnd.vmware.vcloud.vApp+xml").a("href", ""); + addOperatingSystemAndVirtualHardware(spec, rootBuilder); } } diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindVMSpecsToXmlPayload.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindVMSpecsToXmlPayload.java new file mode 100644 index 0000000000..583dc63716 --- /dev/null +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/binders/BindVMSpecsToXmlPayload.java @@ -0,0 +1,64 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.savvis.vpdc.binders; + +import static com.google.common.base.Preconditions.checkArgument; + +import javax.inject.Singleton; +import javax.xml.parsers.FactoryConfigurationError; +import javax.xml.parsers.ParserConfigurationException; + +import org.jclouds.rest.internal.GeneratedHttpRequest; +import org.jclouds.savvis.vpdc.domain.VMSpec; + +import com.google.common.collect.Iterables; +import com.jamesmurty.utils.XMLBuilder; + +/** + * + * @author Adrian Cole + * + */ +@Singleton +public class BindVMSpecsToXmlPayload extends BaseBindVMSpecToXmlPayload> { + + @SuppressWarnings("unchecked") + protected Iterable findSpecInArgsOrNull(GeneratedHttpRequest gRequest) { + for (Object arg : gRequest.getArgs()) { + if (arg instanceof Iterable) { + Iterable specs = (Iterable) arg; + checkArgument(Iterables.size(specs) > 0, + "At least one VMSpec must be included in the argument list"); + return specs; + } + } + throw new IllegalArgumentException("Iterbable must be included in the argument list"); + } + + @Override + protected void bindSpec(Iterable specs, XMLBuilder rootBuilder) throws ParserConfigurationException, FactoryConfigurationError { + rootBuilder.a("name", ""); + XMLBuilder specBuilder = buildChildren(rootBuilder); + for (VMSpec spec : specs) { + checkSpec(spec); + XMLBuilder vAppBuilder = buildRootForName(specBuilder, spec.getName()); + addOperatingSystemAndVirtualHardware(spec, vAppBuilder); + } + } +} diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java index 37a133747f..e8f6e1bbee 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/compute/strategy/VPDCComputeServiceAdapter.java @@ -85,6 +85,8 @@ public class VPDCComputeServiceAdapter implements ComputeServiceAdapter dataDriveDeviceNameToSizeInGig = Maps.newLinkedHashMap(); public Builder name(String name) { - this.name = checkNotNull(name, "name"); - return this; - } - - public Builder network(Network network) { - this.network = checkNotNull(network, "network"); - return this; + this.name = checkNotNull(name, "name"); + return this; } - + + public Builder networkTierName(String networkTierName) { + this.networkTierName = checkNotNull(networkTierName, "networkTierName"); + return this; + } + public Builder operatingSystem(CIMOperatingSystem operatingSystem) { this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem"); return this; @@ -96,19 +96,19 @@ public class VMSpec { public Builder addDataDrives(Map dataDriveDeviceNameToSizeInGig) { this.dataDriveDeviceNameToSizeInGig = ImmutableMap.copyOf(checkNotNull(dataDriveDeviceNameToSizeInGig, - "dataDriveDeviceNameToSizeInGig")); + "dataDriveDeviceNameToSizeInGig")); return this; } public VMSpec build() { - return new VMSpec(name, network, operatingSystem, processorCount, memoryInGig, bootDeviceName, bootDriveSize, - dataDriveDeviceNameToSizeInGig); + return new VMSpec(name, networkTierName, operatingSystem, processorCount, memoryInGig, bootDeviceName, + bootDriveSize, dataDriveDeviceNameToSizeInGig); } public static Builder fromVMSpec(VMSpec in) { - return new Builder().operatingSystem(in.getOperatingSystem()).memoryInGig(in.getMemoryInGig()) - .bootDeviceName(in.getBootDeviceName()).bootDiskSize(in.getBootDiskSize()) - .addDataDrives(in.getDataDiskDeviceNameToSizeInGig()).processorCount(in.getProcessorCount()); + return new Builder().operatingSystem(in.getOperatingSystem()).memoryInGig(in.getMemoryInGig()).bootDeviceName( + in.getBootDeviceName()).bootDiskSize(in.getBootDiskSize()).addDataDrives( + in.getDataDiskDeviceNameToSizeInGig()).processorCount(in.getProcessorCount()); } } @@ -119,7 +119,7 @@ public class VMSpec { } private final String name; - private final Network network; + private final String networkTierName; private final CIMOperatingSystem operatingSystem; private final int processorCount; private final int memoryInGig; @@ -127,10 +127,11 @@ public class VMSpec { private final int bootDriveSize; private final Map dataDriveDeviceNameToSizeInGig; - protected VMSpec(String name, Network network, CIMOperatingSystem operatingSystem, int processorCount, int memoryInGig, String bootDeviceName, - int bootDriveSize, Map dataDriveDeviceNameToSizeInGig) { - this.name = name; - this.network = network; + protected VMSpec(String name, String networkTierName, CIMOperatingSystem operatingSystem, int processorCount, + int memoryInGig, String bootDeviceName, int bootDriveSize, + Map dataDriveDeviceNameToSizeInGig) { + this.name = name; + this.networkTierName = networkTierName; this.operatingSystem = checkNotNull(operatingSystem, "operatingSystem not specified"); checkProcessorCount(processorCount); this.processorCount = processorCount; @@ -140,16 +141,16 @@ public class VMSpec { checkArgument(bootDriveSize > 0, "bootDriveSize must be positive"); this.bootDriveSize = bootDriveSize; this.dataDriveDeviceNameToSizeInGig = ImmutableMap.copyOf(checkNotNull(dataDriveDeviceNameToSizeInGig, - "dataDriveDeviceNameToSizeInGig")); + "dataDriveDeviceNameToSizeInGig")); } public String getName() { - return name; - } + return name; + } - public Network getNetwork() { - return network; - } + public String getNetworkTierName() { + return networkTierName; + } public CIMOperatingSystem getOperatingSystem() { return operatingSystem; @@ -228,9 +229,10 @@ public class VMSpec { @Override public String toString() { - return "[name= " + name + ", operatingSystem=" + operatingSystem + ", processorCount=" + processorCount + ", memoryInGig=" - + memoryInGig + ", network=" + network.getName() + ", bootDeviceName=" + bootDeviceName + ", bootDriveSize=" + bootDriveSize - + ", dataDriveDeviceNameToSizeInGig=" + dataDriveDeviceNameToSizeInGig + "]"; + return "[name= " + name + ", operatingSystem=" + operatingSystem + ", processorCount=" + processorCount + + ", memoryInGig=" + memoryInGig + ", networkTierName=" + networkTierName + ", bootDeviceName=" + + bootDeviceName + ", bootDriveSize=" + bootDriveSize + ", dataDriveDeviceNameToSizeInGig=" + + dataDriveDeviceNameToSizeInGig + "]"; } } \ No newline at end of file diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java index a1175f4420..02d71715bb 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMAsyncClient.java @@ -19,7 +19,6 @@ package org.jclouds.savvis.vpdc.features; import java.net.URI; -import java.util.List; import java.util.Set; import javax.annotation.Nullable; @@ -40,6 +39,7 @@ import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.savvis.vpdc.binders.BindCaptureVAppTemplateToXmlPayload; import org.jclouds.savvis.vpdc.binders.BindCloneVMToXmlPayload; import org.jclouds.savvis.vpdc.binders.BindVMSpecToXmlPayload; +import org.jclouds.savvis.vpdc.binders.BindVMSpecsToXmlPayload; import org.jclouds.savvis.vpdc.domain.Task; import org.jclouds.savvis.vpdc.domain.VMSpec; import org.jclouds.savvis.vpdc.filters.SetVCloudTokenCookie; @@ -68,8 +68,7 @@ public interface VMAsyncClient { @MapBinder(BindVMSpecToXmlPayload.class) ListenableFuture addVMIntoVDC( @PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, - @PathParam("vpdcId") String vpdcId, @PayloadParam("networkName") String networkTierName, - @PayloadParam("name") String vAppName, VMSpec spec); + @PathParam("vpdcId") String vpdcId, VMSpec spec); /** * @see VMClient#addVMIntoVDC @@ -78,8 +77,18 @@ public interface VMAsyncClient { @XMLResponseParser(TaskHandler.class) @Path("vApp/") @MapBinder(BindVMSpecToXmlPayload.class) - ListenableFuture addVMIntoVDC(@EndpointParam URI vpdc, @PayloadParam("networkName") String networkTierName, - @PayloadParam("name") String vAppName, VMSpec spec); + ListenableFuture addVMIntoVDC(@EndpointParam URI vpdc, VMSpec spec); + + /** + * @see VMClient#addMultipleVMsIntoVDC + */ + @GET + @XMLResponseParser(TasksListHandler.class) + @Path("v{jclouds.api-version}/org/{billingSiteId}/vdc/{vpdcId}/vApp/") + @MapBinder(BindVMSpecsToXmlPayload.class) + ListenableFuture> addMultipleVMsIntoVDC( + @PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, + @PathParam("vpdcId") String vpdcId, Iterable vmSpecs); /** * @see VMClient#addMultipleVMsIntoVDC @@ -87,8 +96,8 @@ public interface VMAsyncClient { @GET @XMLResponseParser(TasksListHandler.class) @Path("vApp/") - @MapBinder(BindVMSpecToXmlPayload.class) - ListenableFuture> addMultipleVMsIntoVDC(@EndpointParam URI vpdc, List vmSpecs); + @MapBinder(BindVMSpecsToXmlPayload.class) + ListenableFuture> addMultipleVMsIntoVDC(@EndpointParam URI vpdc, Iterable vmSpecs); /** * @see VMClient#captureVApp @@ -97,9 +106,10 @@ public interface VMAsyncClient { @XMLResponseParser(TaskHandler.class) @Path("v{jclouds.api-version}/org/{billingSiteId}/vdc/{vpdcId}/action/captureVApp") @MapBinder(BindCaptureVAppTemplateToXmlPayload.class) - ListenableFuture captureVApp(@PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, - @PathParam("vpdcId") String vpdcId, URI vAppUri); - + ListenableFuture captureVApp( + @PathParam("billingSiteId") @Nullable @ParamParser(DefaultOrgIfNull.class) String billingSiteId, + @PathParam("vpdcId") String vpdcId, URI vAppUri); + /** * @see VMClient#cloneVApp */ @@ -107,9 +117,9 @@ public interface VMAsyncClient { @XMLResponseParser(TaskHandler.class) @Path("action/cloneVApp") @MapBinder(BindCloneVMToXmlPayload.class) - ListenableFuture cloneVApp(@EndpointParam URI vAppUri, @PayloadParam("name") String newVAppName, - @PayloadParam("networkTierName") String networkTierName); - + ListenableFuture cloneVApp(@EndpointParam URI vAppUri, @PayloadParam("name") String newVAppName, + @PayloadParam("networkTierName") String networkTierName); + /** * @see VMClient#removeVMFromVDC */ @@ -128,7 +138,7 @@ public interface VMAsyncClient { @XMLResponseParser(TaskHandler.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture removeVM(@EndpointParam URI vm); - + /** * @see VMClient#powerOffVM */ @@ -137,7 +147,7 @@ public interface VMAsyncClient { @Path("action/powerOff") @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture powerOffVM(@EndpointParam URI vm); - + /** * @see VMClient#powerOnVM */ diff --git a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java index 086d4120b7..c94038d527 100644 --- a/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java +++ b/providers/savvis-symphonyvpdc/src/main/java/org/jclouds/savvis/vpdc/features/VMClient.java @@ -19,7 +19,6 @@ package org.jclouds.savvis.vpdc.features; import java.net.URI; -import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -44,14 +43,12 @@ public interface VMClient { * billing site Id, or null for default * @param vpdcId * vpdc Id - * @param networkTierName - * network tier name * @param spec * how to * * @return VM in progress */ - Task addVMIntoVDC(String billingSiteId, String vpdcId, String networkTierName, String name, VMSpec spec); + Task addVMIntoVDC(String billingSiteId, String vpdcId, VMSpec spec); /** * @@ -59,43 +56,56 @@ public interface VMClient { * href of the vpdc * @see #addVMIntoVDC */ - Task addVMIntoVDC(URI vpdc, String networkTierName, String name, VMSpec spec); - + Task addVMIntoVDC(URI vpdc, VMSpec spec); + /** + * Add/Deploy new VMs into VDC + * + * @param billingSiteId + * billing site Id, or null for default + * @param vpdcId + * vpdc Id + * @param vmSpecs + * vm configurations + * @return VM's in progress + */ + Set addMultipleVMsIntoVDC(String billingSiteId, String vpdcId, Iterable vmSpecs); + + /** + * Add/Deploy new VMs into VDC * * @param vpdc * href of the vpdc * @param vmSpecs - * vm configurations + * vm configurations * @return VM's in progress */ - Set addMultipleVMsIntoVDC(URI vpdc, List vmSpecs); + Set addMultipleVMsIntoVDC(URI vpdc, Iterable vmSpecs); /** * - * @param billingSiteId + * @param billingSiteId * billing site Id, or null for default * @param vpdcId * vpdc Id * @param vAppUri - * href of the vApp - * @return - * Task with vAppTemplate href + * href of the vApp + * @return Task with vAppTemplate href */ Task captureVApp(String billingSiteId, String vpdcId, URI vAppUri); - + /** * * @param vAppUri - * href of the vApp + * href of the vApp * @param newVAppName - * name for the new vApp + * name for the new vApp * @param networkTierName - * network tier name for vApp + * network tier name for vApp * @return */ Task cloneVApp(URI vAppUri, String newVAppName, String networkTierName); - + /** * Remove a VM *

@@ -126,21 +136,21 @@ public interface VMClient { * @see #removeVMFromVDC */ Task removeVM(URI vm); - + /** * Power off a VM * * @param vm - * href of the vm + * href of the vm * @return */ Task powerOffVM(URI vm); - + /** * Power on a VM * * @param vm - * href of the vm + * href of the vm * @return */ Task powerOnVM(URI vm); diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindVMSpecToXmlPayloadTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindVMSpecsToXmlPayloadTest.java similarity index 70% rename from providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindVMSpecToXmlPayloadTest.java rename to providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindVMSpecsToXmlPayloadTest.java index ad60d2bd90..6d3c49eeb9 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindVMSpecToXmlPayloadTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/binders/BindVMSpecsToXmlPayloadTest.java @@ -21,36 +21,34 @@ package org.jclouds.savvis.vpdc.binders; import static org.testng.Assert.assertEquals; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Set; import org.jclouds.cim.OSType; import org.jclouds.compute.domain.CIMOperatingSystem; -import org.jclouds.savvis.vpdc.domain.Network; import org.jclouds.savvis.vpdc.domain.VMSpec; import org.jclouds.util.Strings2; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.gson.Gson; import com.google.inject.TypeLiteral; /** - * Tests behavior of {@code BindVMSpecToXmlPayload} + * Tests behavior of {@code BindVMSpecsToXmlPayload} * * @author Adrian Cole */ @Test(groups = "unit") -public class BindVMSpecToXmlPayloadTest { +public class BindVMSpecsToXmlPayloadTest { public void test() throws IOException { - CIMOperatingSystem os = Iterables.find(new Gson().> fromJson( - Strings2.toStringAndClose(getClass().getResourceAsStream( - "/savvis-symphonyvpdc/predefined_operatingsystems.json")), - new TypeLiteral>() { - }.getType()), new Predicate() { + CIMOperatingSystem os = Iterables.find(new Gson().> fromJson(Strings2 + .toStringAndClose(getClass() + .getResourceAsStream("/savvis-symphonyvpdc/predefined_operatingsystems.json")), + new TypeLiteral>() { + }.getType()), new Predicate() { @Override public boolean apply(CIMOperatingSystem arg0) { @@ -59,14 +57,10 @@ public class BindVMSpecToXmlPayloadTest { }); - Network network = Network.builder().name("VM Tier01").build(); - String expected = Strings2.toStringAndClose(getClass().getResourceAsStream("/vm-multiple-default.xml")); - VMSpec spec = VMSpec.builder().name("Test VM").operatingSystem(os).network(network).build(); - List specs = new ArrayList(); - specs.add(spec); - - assertEquals(new BindVMSpecToXmlPayload().generateXml(specs), expected); + VMSpec spec = VMSpec.builder().name("Test VM").operatingSystem(os).networkTierName("VM Tier01").build(); + + assertEquals(new BindVMSpecsToXmlPayload().generateXml(ImmutableSet.of(spec)), expected); } } diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java index a575707887..9d15ec78e2 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/FirewallAsyncClientTest.java @@ -40,38 +40,44 @@ import com.google.inject.TypeLiteral; @Test(groups = "unit") public class FirewallAsyncClientTest extends BaseVPDCAsyncClientTest { - public void testAddFirewallRule() throws NoSuchMethodException, IOException{ - Method method = FirewallAsyncClient.class.getMethod("addFirewallRule", String.class, String.class, FirewallRule.class); - HttpRequest request = processor.createRequest(method, "11", "22", FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet") - .destination("VM Tier01").port("22").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build()); + public void testAddFirewallRule() throws NoSuchMethodException, IOException { + Method method = FirewallAsyncClient.class.getMethod("addFirewallRule", String.class, String.class, + FirewallRule.class); + HttpRequest request = processor.createRequest(method, "11", "22", FirewallRule.builder().firewallType( + "SERVER_TIER_FIREWALL").isEnabled(true).source("internet").destination("VM Tier01").port("22").protocol( + "Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build()); - assertRequestLineEquals(request, "PUT https://api.symphonyvpdc.savvis.net/vpdc/v1.0/org/11/vdc/22/FirewallService/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, ""); - assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/firewallService-default.xml")), - "application/xml", false); + assertRequestLineEquals(request, + "PUT https://api.symphonyvpdc.savvis.net/vpdc/v1.0/org/11/vdc/22/FirewallService/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream( + "/firewallService-default.xml")), "application/xml", false); - assertResponseParserClassEquals(method, request, ParseSax.class); - assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); - checkFilters(request); - } - - public void testDeleteFirewallRule() throws NoSuchMethodException, IOException{ - Method method = FirewallAsyncClient.class.getMethod("deleteFirewallRule", String.class, String.class, FirewallRule.class); - HttpRequest request = processor.createRequest(method, "11", "22", FirewallRule.builder().firewallType("SERVER_TIER_FIREWALL").isEnabled(true).source("internet") - .destination("VM Tier01").port("22").protocol("Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build()); + checkFilters(request); + } - assertRequestLineEquals(request, "DELETE https://api.symphonyvpdc.savvis.net/vpdc/v1.0/org/11/vdc/22/FirewallService/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, ""); - assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/firewallService-default.xml")), - "application/xml", false); + public void testDeleteFirewallRule() throws NoSuchMethodException, IOException { + Method method = FirewallAsyncClient.class.getMethod("deleteFirewallRule", String.class, String.class, + FirewallRule.class); + HttpRequest request = processor.createRequest(method, "11", "22", FirewallRule.builder().firewallType( + "SERVER_TIER_FIREWALL").isEnabled(true).source("internet").destination("VM Tier01").port("22").protocol( + "Tcp").policy("allow").description("Server Tier Firewall Rule").isLogged(false).build()); - assertResponseParserClassEquals(method, request, ParseSax.class); - assertSaxResponseParserClassEquals(method, TaskHandler.class); - assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + assertRequestLineEquals(request, + "DELETE https://api.symphonyvpdc.savvis.net/vpdc/v1.0/org/11/vdc/22/FirewallService/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream( + "/firewallService-default.xml")), "application/xml", false); - checkFilters(request); - } + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + + checkFilters(request); + } @Override protected TypeLiteral> createTypeLiteral() { diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java index ef040102bd..8c5fcbd326 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMAsyncClientTest.java @@ -21,8 +21,6 @@ package org.jclouds.savvis.vpdc.features; import java.io.IOException; import java.lang.reflect.Method; import java.net.URI; -import java.util.ArrayList; -import java.util.List; import java.util.Set; import org.jclouds.cim.OSType; @@ -32,7 +30,6 @@ import org.jclouds.http.functions.ParseSax; import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.internal.RestAnnotationProcessor; -import org.jclouds.savvis.vpdc.domain.Network; import org.jclouds.savvis.vpdc.domain.VMSpec; import org.jclouds.savvis.vpdc.xml.TaskHandler; import org.jclouds.savvis.vpdc.xml.TasksListHandler; @@ -40,6 +37,7 @@ import org.jclouds.util.Strings2; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.inject.Key; import com.google.inject.TypeLiteral; @@ -53,8 +51,7 @@ import com.google.inject.TypeLiteral; public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { public void testAddVMIntoVDCURI() throws SecurityException, NoSuchMethodException, IOException { - Method method = VMAsyncClient.class - .getMethod("addVMIntoVDC", URI.class, String.class, String.class, VMSpec.class); + Method method = VMAsyncClient.class.getMethod("addVMIntoVDC", URI.class, VMSpec.class); CIMOperatingSystem os = Iterables.find(injector.getInstance(Key.get(new TypeLiteral>() { })), new Predicate() { @@ -67,8 +64,8 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { }); HttpRequest request = processor.createRequest(method, URI - .create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22"), "VM Tier01", "DemoHost-1", - VMSpec.builder().operatingSystem(os).build()); + .create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22"), VMSpec.builder().name( + "DemoHost-1").networkTierName("VM Tier01").operatingSystem(os).build()); assertRequestLineEquals(request, "GET https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/ HTTP/1.1"); @@ -84,8 +81,7 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { } public void testAddVMIntoVDC() throws SecurityException, NoSuchMethodException, IOException { - Method method = VMAsyncClient.class.getMethod("addVMIntoVDC", String.class, String.class, String.class, - String.class, VMSpec.class); + Method method = VMAsyncClient.class.getMethod("addVMIntoVDC", String.class, String.class, VMSpec.class); CIMOperatingSystem os = Iterables.find(injector.getInstance(Key.get(new TypeLiteral>() { })), new Predicate() { @@ -97,11 +93,10 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { }); - HttpRequest request = processor.createRequest(method, "11", "22", "VM Tier01", "DemoHost-1", VMSpec.builder() - .operatingSystem(os).build()); + HttpRequest request = processor.createRequest(method, "11", "22", VMSpec.builder().operatingSystem(os).name( + "DemoHost-1").networkTierName("VM Tier01").build()); - assertRequestLineEquals(request, - "GET https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/ HTTP/1.1"); + assertRequestLineEquals(request, "GET https://api.symphonyvpdc.savvis.net/vpdc/v1.0/org/11/vdc/22/vApp/ HTTP/1.1"); assertNonPayloadHeadersEqual(request, ""); assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/vm-default.xml")), "application/xml", false); @@ -113,38 +108,6 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { checkFilters(request); } - public void testAddMultipleVMsIntoVDC() throws SecurityException, NoSuchMethodException, IOException { - Method method = VMAsyncClient.class.getMethod("addMultipleVMsIntoVDC", URI.class, List.class); - - CIMOperatingSystem os = Iterables.find(injector.getInstance(Key.get(new TypeLiteral>() { - })), new Predicate() { - - @Override - public boolean apply(CIMOperatingSystem arg0) { - return arg0.getOsType() == OSType.RHEL_64; - } - - }); - - Network network = Network.builder().name("VM Tier01").build(); - List vmSpecs = new ArrayList(); - vmSpecs.add(VMSpec.builder().name("Test VM").operatingSystem(os).network(network).build()); - - HttpRequest request = processor.createRequest(method, URI.create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22"), vmSpecs); - - assertRequestLineEquals(request, - "GET https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/ HTTP/1.1"); - assertNonPayloadHeadersEqual(request, ""); - assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/vm-multiple-default.xml")), - "application/xml", false); - - assertResponseParserClassEquals(method, request, ParseSax.class); - assertSaxResponseParserClassEquals(method, TasksListHandler.class); - assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); - - checkFilters(request); - } - public void testCaptureVApp() throws SecurityException, NoSuchMethodException, IOException { Method method = VMAsyncClient.class.getMethod("captureVApp", String.class, String.class, URI.class); HttpRequest request = processor.createRequest(method, "100000.0", "2736", URI.create("https://api.symphonyvpdc.savvis.net/vpdc/v1.0/org/100000.0/vdc/2736/vApp/1001")); @@ -177,6 +140,65 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { checkFilters(request); } + public void testAddMultipleVMsIntoVDCURI() throws SecurityException, NoSuchMethodException, IOException { + Method method = VMAsyncClient.class.getMethod("addMultipleVMsIntoVDC", URI.class, Iterable.class); + + CIMOperatingSystem os = Iterables.find(injector.getInstance(Key.get(new TypeLiteral>() { + })), new Predicate() { + + @Override + public boolean apply(CIMOperatingSystem arg0) { + return arg0.getOsType() == OSType.RHEL_64; + } + + }); + + HttpRequest request = processor.createRequest(method, URI + .create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22"), ImmutableSet.of(VMSpec + .builder().name("Test VM").networkTierName("VM Tier01").operatingSystem(os).build())); + + assertRequestLineEquals(request, + "GET https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/vm-multiple-default.xml")), + "application/xml", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TasksListHandler.class); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(request); + } + + public void testAddMultipleVMsIntoVDC() throws SecurityException, NoSuchMethodException, IOException { + Method method = VMAsyncClient.class + .getMethod("addMultipleVMsIntoVDC", String.class, String.class, Iterable.class); + + CIMOperatingSystem os = Iterables.find(injector.getInstance(Key.get(new TypeLiteral>() { + })), new Predicate() { + + @Override + public boolean apply(CIMOperatingSystem arg0) { + return arg0.getOsType() == OSType.RHEL_64; + } + + }); + + HttpRequest request = processor.createRequest(method, "11", "22", ImmutableSet.of(VMSpec.builder() + .operatingSystem(os).name("Test VM").networkTierName("VM Tier01").build())); + + assertRequestLineEquals(request, "GET https://api.symphonyvpdc.savvis.net/vpdc/v1.0/org/11/vdc/22/vApp/ HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, Strings2.toStringAndClose(getClass().getResourceAsStream("/vm-multiple-default.xml")), + "application/xml", false); + + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TasksListHandler.class); + assertExceptionParserClassEquals(method, MapHttp4xxCodesToExceptions.class); + + checkFilters(request); + } + public void testRemoveVMFromVDC() throws SecurityException, NoSuchMethodException, IOException { Method method = VMAsyncClient.class.getMethod("removeVMFromVDC", String.class, String.class, String.class); HttpRequest request = processor.createRequest(method, "11", "22", "33"); @@ -209,7 +231,7 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { checkFilters(request); } - + public void testPowerOffVM() throws SecurityException, NoSuchMethodException, IOException { Method method = VMAsyncClient.class.getMethod("powerOffVM", URI.class); HttpRequest request = processor.createRequest(method, URI @@ -226,23 +248,23 @@ public class VMAsyncClientTest extends BaseVPDCAsyncClientTest { checkFilters(request); } - + public void testPowerOnVM() throws SecurityException, NoSuchMethodException, IOException { - Method method = VMAsyncClient.class.getMethod("powerOnVM", URI.class); - HttpRequest request = processor.createRequest(method, URI - .create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33")); + Method method = VMAsyncClient.class.getMethod("powerOnVM", URI.class); + HttpRequest request = processor.createRequest(method, URI + .create("https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33")); - assertRequestLineEquals(request, - "POST https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33/action/powerOn HTTP/1.1"); - assertNonPayloadHeadersEqual(request, ""); - assertPayloadEquals(request, null, null, false); + assertRequestLineEquals(request, + "POST https://api.symphonyvpdc.savvis.net/rest/api/v0.8/org/11/vdc/22/vApp/33/action/powerOn HTTP/1.1"); + assertNonPayloadHeadersEqual(request, ""); + assertPayloadEquals(request, null, null, false); - assertResponseParserClassEquals(method, request, ParseSax.class); - assertSaxResponseParserClassEquals(method, TaskHandler.class); - assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); + assertResponseParserClassEquals(method, request, ParseSax.class); + assertSaxResponseParserClassEquals(method, TaskHandler.class); + assertExceptionParserClassEquals(method, ReturnNullOnNotFoundOr404.class); - checkFilters(request); - } + checkFilters(request); + } @Override protected TypeLiteral> createTypeLiteral() { diff --git a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java index 78a5747e06..1a6bc1eb18 100644 --- a/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java +++ b/providers/savvis-symphonyvpdc/src/test/java/org/jclouds/savvis/vpdc/features/VMClientLiveTest.java @@ -22,8 +22,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.testng.Assert.assertEquals; import java.net.URI; -import java.util.ArrayList; -import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -39,8 +37,8 @@ import org.jclouds.savvis.vpdc.domain.Resource; import org.jclouds.savvis.vpdc.domain.Task; import org.jclouds.savvis.vpdc.domain.VDC; import org.jclouds.savvis.vpdc.domain.VM; -import org.jclouds.savvis.vpdc.domain.VM.Status; import org.jclouds.savvis.vpdc.domain.VMSpec; +import org.jclouds.savvis.vpdc.domain.VM.Status; import org.jclouds.savvis.vpdc.options.GetVMOptions; import org.jclouds.savvis.vpdc.reference.VCloudMediaType; import org.jclouds.ssh.SshClient; @@ -50,7 +48,9 @@ import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; +import com.google.common.collect.ImmutableSet.Builder; import com.google.common.net.HostSpecifier; @Test(groups = "live") @@ -59,7 +59,7 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { private VMClient client; private VM vm; private RetryablePredicate socketTester; - + private String username = checkNotNull(System.getProperty("test." + provider + ".loginUser"), "test." + provider + ".loginUser"); private String password = checkNotNull(System.getProperty("test." + provider + ".loginPassword"), "test." + provider @@ -118,8 +118,8 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { // TODO: determine the sizes available in the VDC, for example there's // a minimum size of boot disk, and also a preset combination of cpu count vs ram - Task task = client.addVMIntoVDC(billingSiteId, vpdcId, networkTierName, name, VMSpec.builder() - .operatingSystem(os).memoryInGig(2).addDataDrive("/data01", 25).build()); + Task task = client.addVMIntoVDC(billingSiteId, vpdcId, VMSpec.builder().name(name).networkTierName( + networkTierName).operatingSystem(os).memoryInGig(2).addDataDrive("/data01", 25).build()); // make sure there's no error assert task.getId() != null && task.getError() == null : task; @@ -139,9 +139,9 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { // the jclouds-wire.log @Override public boolean apply(Resource arg0) { - String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, - arg0.getId()).getDescription(); - return description.indexOf(email) != -1; + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; } }).getId(); @@ -149,8 +149,9 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { String networkTierName = Iterables.get( restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId).getAvailableNetworks(), 0) .getId(); - Network networkTier = restContext.getApi().getBrowsingClient().getNetworkInVDC(billingSiteId, vpdcId, networkTierName); - + Network networkTier = restContext.getApi().getBrowsingClient().getNetworkInVDC(billingSiteId, vpdcId, + networkTierName); + String name = prefix; // delete any old VM @@ -164,32 +165,34 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { } }); - - // TODO: Savvis returns network names with a - instead of space on getNetworkInVDC call, - // fix this once savvis api starts returning correctly - System.out.printf("vpdcId %s, vpdcName %s, networkName %s, name %s, os %s%n", vpdcId, vpdc.getName(), networkTier.getName().replace("-", " "), name, os); - List vmSpecs = new ArrayList(); + // TODO: Savvis returns network names with a - instead of space on getNetworkInVDC call, + // fix this once savvis api starts returning correctly + System.out.printf("vpdcId %s, vpdcName %s, networkName %s, name %s, os %s%n", vpdcId, vpdc.getName(), networkTier + .getName().replace("-", " "), name, os); + + Builder vmSpecs = ImmutableSet. builder(); int noOfVms = 2; for (int i = 0; i < noOfVms; i++) { - // TODO: determine the sizes available in the VDC, for example there's - // a minimum size of boot disk, and also a preset combination of cpu count vs ram - VMSpec vmSpec = VMSpec.builder().name(name + i).operatingSystem(os).memoryInGig(2).network(networkTier).addDataDrive("/data01", 25).build(); - vmSpecs.add(vmSpec); + // TODO: determine the sizes available in the VDC, for example there's + // a minimum size of boot disk, and also a preset combination of cpu count vs ram + VMSpec vmSpec = VMSpec.builder().name(name + i).operatingSystem(os).memoryInGig(2).networkTierName( + networkTierName).addDataDrive("/data01", 25).build(); + vmSpecs.add(vmSpec); } - - Set tasks = client.addMultipleVMsIntoVDC(vpdc.getHref(), vmSpecs); - + + Set tasks = client.addMultipleVMsIntoVDC(vpdc.getHref(), vmSpecs.build()); + for (Task task : tasks) { - // make sure there's no error - assert task.getId() != null && task.getError() == null : task; - - assert this.taskTester.apply(task.getId()); + // make sure there's no error + assert task.getId() != null && task.getError() == null : task; + + assert this.taskTester.apply(task.getId()); } } - + public void testCaptureVAppTemplate() throws Exception { - billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), new Predicate() { @@ -198,36 +201,36 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { // the jclouds-wire.log @Override public boolean apply(Resource arg0) { - String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, - arg0.getId()).getDescription(); - return description.indexOf(email) != -1; + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; } }).getId(); - VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); - - for (Resource vApp : Iterables.filter(vpdc.getResourceEntities(), new Predicate() { + VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); - @Override - public boolean apply(Resource arg0) { - return VCloudMediaType.VAPP_XML.equals(arg0.getType()); - } + for (Resource vApp : Iterables.filter(vpdc.getResourceEntities(), new Predicate() { - })) { - - System.out.printf("Capturing VAppTemplate for vApp - %s%n", vApp.getName()); - Task task = client.captureVApp(billingSiteId, vpdcId, vApp.getHref()); - - // make sure there's no error - assert task.getId() != null && task.getError() == null : task; + @Override + public boolean apply(Resource arg0) { + return VCloudMediaType.VAPP_XML.equals(arg0.getType()); + } - assert this.taskTester.apply(task.getId()); - } + })) { + + System.out.printf("Capturing VAppTemplate for vApp - %s%n", vApp.getName()); + Task task = client.captureVApp(billingSiteId, vpdcId, vApp.getHref()); + + // make sure there's no error + assert task.getId() != null && task.getError() == null : task; + + assert this.taskTester.apply(task.getId()); + } } - + public void testCloneVApp() throws Exception { - billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), new Predicate() { @@ -236,37 +239,37 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { // the jclouds-wire.log @Override public boolean apply(Resource arg0) { - String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, - arg0.getId()).getDescription(); - return description.indexOf(email) != -1; + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; } }).getId(); - VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); - - String networkTierName = Iterables.get(vpdc.getAvailableNetworks(), 0).getId(); - - for (Resource vApp : Iterables.filter(vpdc.getResourceEntities(), new Predicate() { + VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); - @Override - public boolean apply(Resource arg0) { - return VCloudMediaType.VAPP_XML.equals(arg0.getType()); - } + String networkTierName = Iterables.get(vpdc.getAvailableNetworks(), 0).getId(); - })) { - - System.out.printf("Cloning VApp - %s%n", vApp.getName()); - - Task task = client.cloneVApp(vApp.getHref(), "clonedvm", networkTierName); - - // make sure there's no error - assert task.getId() != null && task.getError() == null : task; + for (Resource vApp : Iterables.filter(vpdc.getResourceEntities(), new Predicate() { - assert this.taskTester.apply(task.getId()); - } + @Override + public boolean apply(Resource arg0) { + return VCloudMediaType.VAPP_XML.equals(arg0.getType()); + } + + })) { + + System.out.printf("Cloning VApp - %s%n", vApp.getName()); + + Task task = client.cloneVApp(vApp.getHref(), "clonedvm", networkTierName); + + // make sure there's no error + assert task.getId() != null && task.getError() == null : task; + + assert this.taskTester.apply(task.getId()); + } } - + private void conditionallyCheckSSH() { String ip = Iterables.get(vm.getNetworkConnectionSections(), 0).getIpAddress(); assert HostSpecifier.isValid(ip); @@ -296,88 +299,88 @@ public class VMClientLiveTest extends BaseVPDCClientLiveTest { @Test(enabled = false) public void testPowerOffVM() throws Exception { - billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default - vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), - new Predicate() { - - // try to find the first VDC owned by the current user - // check here for what the email property might be, or in - // the jclouds-wire.log - @Override - public boolean apply(Resource arg0) { - String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, - arg0.getId()).getDescription(); - return description.indexOf(email) != -1; - } - - }).getId(); + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), + new Predicate() { + + // try to find the first VDC owned by the current user + // check here for what the email property might be, or in + // the jclouds-wire.log + @Override + public boolean apply(Resource arg0) { + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; + } + + }).getId(); VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); URI vmURI = Iterables.find(vpdc.getResourceEntities(), new Predicate() { - @Override - public boolean apply(Resource arg0) { - if(VCloudMediaType.VAPP_XML.equals(arg0.getType())){ - VM response1 = restContext.getApi().getBrowsingClient().getVM(arg0.getHref(), (GetVMOptions[]) null); - System.out.printf("powering off vm - %s%n", response1.getName()); - if(response1.getStatus().equals(Status.ON)){ - return true; - } - } - return false; - } - - }).getHref(); - + @Override + public boolean apply(Resource arg0) { + if (VCloudMediaType.VAPP_XML.equals(arg0.getType())) { + VM response1 = restContext.getApi().getBrowsingClient().getVM(arg0.getHref(), (GetVMOptions[]) null); + System.out.printf("powering off vm - %s%n", response1.getName()); + if (response1.getStatus().equals(Status.ON)) { + return true; + } + } + return false; + } + + }).getHref(); + Task task = client.powerOffVM(vmURI); - + // make sure there's no error assert task.getId() != null && task.getError() == null : task; assert this.taskTester.apply(task.getId()); } - + @Test(enabled = false) public void testPowerOnVM() throws Exception { - billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default - vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), - new Predicate() { - - // try to find the first VDC owned by the current user - // check here for what the email property might be, or in - // the jclouds-wire.log - @Override - public boolean apply(Resource arg0) { - String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, - arg0.getId()).getDescription(); - return description.indexOf(email) != -1; - } - - }).getId(); + billingSiteId = restContext.getApi().getBrowsingClient().getOrg(null).getId();// default + vpdcId = Iterables.find(restContext.getApi().getBrowsingClient().getOrg(billingSiteId).getVDCs(), + new Predicate() { + + // try to find the first VDC owned by the current user + // check here for what the email property might be, or in + // the jclouds-wire.log + @Override + public boolean apply(Resource arg0) { + String description = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, + arg0.getId()).getDescription(); + return description.indexOf(email) != -1; + } + + }).getId(); VDC vpdc = restContext.getApi().getBrowsingClient().getVDCInOrg(billingSiteId, vpdcId); URI vmURI = Iterables.find(vpdc.getResourceEntities(), new Predicate() { - @Override - public boolean apply(Resource arg0) { - if(VCloudMediaType.VAPP_XML.equals(arg0.getType())){ - VM response1 = restContext.getApi().getBrowsingClient().getVM(arg0.getHref(), (GetVMOptions[]) null); - System.out.printf("powering on vm - %s%n", response1.getName()); - if(response1.getStatus().equals(Status.OFF)){ - return true; - } - } - return false; - } - - }).getHref(); - + @Override + public boolean apply(Resource arg0) { + if (VCloudMediaType.VAPP_XML.equals(arg0.getType())) { + VM response1 = restContext.getApi().getBrowsingClient().getVM(arg0.getHref(), (GetVMOptions[]) null); + System.out.printf("powering on vm - %s%n", response1.getName()); + if (response1.getStatus().equals(Status.OFF)) { + return true; + } + } + return false; + } + + }).getHref(); + Task task = client.powerOnVM(vmURI); - + // make sure there's no error assert task.getId() != null && task.getError() == null : task; assert this.taskTester.apply(task.getId()); } - + @AfterGroups(groups = "live") protected void tearDown() { if (vm != null) { diff --git a/providers/scaleup-storage/pom.xml b/providers/scaleup-storage/pom.xml index c7b8412a4d..e467e2d68b 100644 --- a/providers/scaleup-storage/pom.xml +++ b/providers/scaleup-storage/pom.xml @@ -33,6 +33,7 @@ scaleup-storage jclouds ScaleUp Cloud Storage provider Scality RING (ScalityRS2) implementation targeted to ScaleUp Cloud Storage + bundle org.jclouds.scaleup.storage.blobstore.ScaleUpStorageTestInitializer @@ -146,6 +147,22 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.scaleup.storage.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/providers/serverlove-z1-man/pom.xml b/providers/serverlove-z1-man/pom.xml index 5c7cf8d6e7..5202e05444 100644 --- a/providers/serverlove-z1-man/pom.xml +++ b/providers/serverlove-z1-man/pom.xml @@ -33,6 +33,7 @@ serverlove-z1-man jclouds Serverlove Manchester provider Serverlove implementation targeted to Manchester + bundle https://api.z1-man.serverlove.com @@ -136,6 +137,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.serverlove.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/skalicloud-sdg-my/pom.xml b/providers/skalicloud-sdg-my/pom.xml index a251165220..f164b3f3db 100644 --- a/providers/skalicloud-sdg-my/pom.xml +++ b/providers/skalicloud-sdg-my/pom.xml @@ -33,6 +33,7 @@ skalicloud-sdg-my jclouds SkaliCloud Malaysia provider SkaliCloud implementation targeted to Malaysia + bundle https://api.sdg-my.skalicloud.com @@ -136,6 +137,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.skalicloud.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/slicehost/pom.xml b/providers/slicehost/pom.xml index 8285a30452..eb2b07edb7 100644 --- a/providers/slicehost/pom.xml +++ b/providers/slicehost/pom.xml @@ -32,6 +32,8 @@ slicehost jclouds Slicehost provider ComputeService implementation of Slicehost datacenters + bundle + trmkrun-ccc,test.trmk-924 @@ -127,4 +129,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.slicehost.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + + diff --git a/providers/synaptic-storage/pom.xml b/providers/synaptic-storage/pom.xml index dbf9a2828a..8cacb47f7b 100644 --- a/providers/synaptic-storage/pom.xml +++ b/providers/synaptic-storage/pom.xml @@ -33,6 +33,7 @@ synaptic-storage jclouds Synaptic Storage as a Service provider Atmos implementation targeted to ATT Synaptic Storage as a Service + bundle org.jclouds.synaptic.storage.blobstore.integration.SynapticStorageTestInitializer @@ -139,6 +140,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.synaptic.storage.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/tiscali-storage/pom.xml b/providers/tiscali-storage/pom.xml index 4edfecdc14..aa892c5ba7 100644 --- a/providers/tiscali-storage/pom.xml +++ b/providers/tiscali-storage/pom.xml @@ -33,6 +33,7 @@ tiscali-storage jclouds Tisali Cloud Storage provider Scality RING (ScalityRS2) implementation targeted to Tisali Cloud Storage + bundle org.jclouds.tiscali.storage.blobstore.TiscaliStorageTestInitializer @@ -147,6 +148,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.tiscali.storage.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/trmk-ecloud/pom.xml b/providers/trmk-ecloud/pom.xml index 6bd0b394f8..004c9c2418 100644 --- a/providers/trmk-ecloud/pom.xml +++ b/providers/trmk-ecloud/pom.xml @@ -33,6 +33,7 @@ trmk-ecloud jclouds Terremark Enterprise Cloud provider jclouds Terremark Enterprise Cloud provider + bundle https://services.enterprisecloud.terremark.com/api @@ -151,6 +152,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.vcloud.terremark.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudProviderMetadata.java b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudProviderMetadata.java new file mode 100644 index 0000000000..1b1da29cf3 --- /dev/null +++ b/providers/trmk-ecloud/src/main/java/org/jclouds/vcloud/terremark/TerremarkECloudProviderMetadata.java @@ -0,0 +1,97 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.terremark; + +import java.net.URI; + +import org.jclouds.providers.BaseProviderMetadata; +import org.jclouds.providers.ProviderMetadata; + +/** + * Implementation of {@link org.jclouds.types.ProviderMetadata} for Terremark's Enterprise Cloud. + * + * @author Adrian Cole + */ +public class TerremarkECloudProviderMetadata extends BaseProviderMetadata { + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return "trmk-ecloud"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getType() { + return ProviderMetadata.COMPUTE_TYPE; + } + + /** + * {@inheritDoc} + */ + @Override + public String getName() { + return "Terremark Enterprise Cloud"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentityName() { + return "email"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getCredentialName() { + return "password"; + } + + /** + * {@inheritDoc} + */ + @Override + public URI getHomepage() { + return URI.create("http://www.terremark.com/services/cloudcomputing/theenterprisecloud.aspx"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getConsole() { + return URI.create("https://icenter.digitalops.net"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getApiDocumentation() { + return URI.create("http://support.theenterprisecloud.com/kb/default.asp?id=533&Lang=1&SID="); + } + +} \ No newline at end of file diff --git a/providers/trmk-ecloud/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata b/providers/trmk-ecloud/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata new file mode 100644 index 0000000000..c61780f664 --- /dev/null +++ b/providers/trmk-ecloud/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata @@ -0,0 +1 @@ +org.jclouds.vcloud.terremark.TerremarkECloudProviderMetadata diff --git a/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudProviderTest.java b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudProviderTest.java new file mode 100644 index 0000000000..20e4e82b95 --- /dev/null +++ b/providers/trmk-ecloud/src/test/java/org/jclouds/vcloud/terremark/TerremarkECloudProviderTest.java @@ -0,0 +1,36 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.terremark; + +import org.jclouds.providers.BaseProviderMetadataTest; +import org.jclouds.providers.ProviderMetadata; +import org.testng.annotations.Test; + +/** + * The TerremarkECloudProviderTest tests the org.jclouds.providers.TerremarkECloudProvider class. + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "TerremarkECloudProviderTest") +public class TerremarkECloudProviderTest extends BaseProviderMetadataTest { + + public TerremarkECloudProviderTest() { + super(new TerremarkECloudProviderMetadata(), ProviderMetadata.COMPUTE_TYPE); + } +} \ No newline at end of file diff --git a/providers/trmk-vcloudexpress/pom.xml b/providers/trmk-vcloudexpress/pom.xml index 8313b65baf..a1ab8bcb86 100644 --- a/providers/trmk-vcloudexpress/pom.xml +++ b/providers/trmk-vcloudexpress/pom.xml @@ -33,6 +33,7 @@ trmk-vcloudexpress jclouds Terremark vCloud Express provider jclouds Terremark vCloud Express provider + bundle https://services.vcloudexpress.terremark.com/api @@ -150,6 +151,20 @@ + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.vcloud.terremark.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + - diff --git a/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressProviderMetadata.java b/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressProviderMetadata.java new file mode 100644 index 0000000000..b731643ec1 --- /dev/null +++ b/providers/trmk-vcloudexpress/src/main/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressProviderMetadata.java @@ -0,0 +1,97 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.vcloud.terremark; + +import java.net.URI; + +import org.jclouds.providers.BaseProviderMetadata; +import org.jclouds.providers.ProviderMetadata; + +/** + * Implementation of {@link org.jclouds.types.ProviderMetadata} for Terremark's vCloud Express. + * + * @author Adrian Cole + */ +public class TerremarkVCloudExpressProviderMetadata extends BaseProviderMetadata { + + /** + * {@inheritDoc} + */ + @Override + public String getId() { + return "trmk-vcloudexpress"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getType() { + return ProviderMetadata.COMPUTE_TYPE; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentityName() { + return "email"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getCredentialName() { + return "password"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getName() { + return "Terremark vCloud Express"; + } + + /** + * {@inheritDoc} + */ + @Override + public URI getHomepage() { + return URI.create("https://vcloudexpress.terremark.com/"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getConsole() { + return URI.create("https://my.vcloudexpress.terremark.com"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getApiDocumentation() { + return URI.create("https://community.vcloudexpress.terremark.com/en-us/product_docs/m/vcefiles/2342.aspx"); + } + +} \ No newline at end of file diff --git a/providers/trmk-vcloudexpress/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata b/providers/trmk-vcloudexpress/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata new file mode 100644 index 0000000000..826eb45584 --- /dev/null +++ b/providers/trmk-vcloudexpress/src/main/resources/META-INF/services/org.jclouds.providers.ProviderMetadata @@ -0,0 +1 @@ +org.jclouds.vcloud.terremark.TerremarkVCloudExpressProviderMetadata diff --git a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/ProvidersInPropertiesTest.java b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressProviderTest.java similarity index 58% rename from providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/ProvidersInPropertiesTest.java rename to providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressProviderTest.java index 7208060ea7..9e8a81d09a 100644 --- a/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/ProvidersInPropertiesTest.java +++ b/providers/trmk-vcloudexpress/src/test/java/org/jclouds/vcloud/terremark/TerremarkVCloudExpressProviderTest.java @@ -18,31 +18,20 @@ */ package org.jclouds.vcloud.terremark; -import org.jclouds.compute.util.ComputeServiceUtils; -import org.jclouds.rest.Providers; +import org.jclouds.providers.BaseProviderMetadataTest; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.vcloud.terremark.TerremarkVCloudExpressProviderMetadata; import org.testng.annotations.Test; -import com.google.common.collect.Iterables; - /** + * The TerremarkVCloudExpressProviderTest tests the org.jclouds.providers.TerremarkVCloudExpressProvider class. * * @author Adrian Cole - * */ -@Test(groups = "unit") -public class ProvidersInPropertiesTest { - - @Test - public void testSupportedProviders() { - Iterable providers = Providers.getSupportedProviders(); - assert Iterables.contains(providers, "trmk-vcloudexpress") : providers; +@Test(groups = "unit", testName = "TerremarkVCloudExpressProviderTest") +public class TerremarkVCloudExpressProviderTest extends BaseProviderMetadataTest { + public TerremarkVCloudExpressProviderTest() { + super(new TerremarkVCloudExpressProviderMetadata(), ProviderMetadata.COMPUTE_TYPE); } - - @Test - public void testSupportedComputeServiceProviders() { - Iterable providers = ComputeServiceUtils.getSupportedProviders(); - assert Iterables.contains(providers, "trmk-vcloudexpress") : providers; - } - -} +} \ No newline at end of file diff --git a/sandbox-apis/cloudstack/pom.xml b/sandbox-apis/cloudstack/pom.xml index 6054bd25ae..8f5c415ea4 100644 --- a/sandbox-apis/cloudstack/pom.xml +++ b/sandbox-apis/cloudstack/pom.xml @@ -34,7 +34,8 @@ cloudstack jclouds cloudstack core jclouds components to access cloudstack - + bundle + @@ -148,4 +149,20 @@ + + + + + org.apache.felix + maven-bundle-plugin + + + ${project.artifactId} + org.jclouds.cloudstack.*;version="${project.version}" + org.jclouds.*;version="${project.version}",* + + + + + diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkOffering.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkOffering.java index 6f4581126a..cd70eea1a6 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkOffering.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/domain/NetworkOffering.java @@ -50,6 +50,7 @@ public class NetworkOffering implements Comparable { private boolean isDefault; private boolean supportsVLAN; private TrafficType trafficType; + private GuestIPType guestIPType; private Set tags = ImmutableSet.of(); public Builder id(long id) { @@ -102,6 +103,11 @@ public class NetworkOffering implements Comparable { return this; } + public Builder guestIPType(GuestIPType guestIPType) { + this.guestIPType = guestIPType; + return this; + } + public Builder tags(Set tags) { this.tags = ImmutableSet.copyOf(checkNotNull(tags, "tags")); return this; @@ -109,7 +115,7 @@ public class NetworkOffering implements Comparable { public NetworkOffering build() { return new NetworkOffering(id, name, displayText, created, availability, supportsVLAN, maxConnections, - isDefault, trafficType, networkRate, tags); + isDefault, trafficType, guestIPType, networkRate, tags); } } @@ -127,13 +133,15 @@ public class NetworkOffering implements Comparable { private boolean supportsVLAN; @SerializedName("traffictype") private TrafficType trafficType; + @SerializedName("guestiptype") + private GuestIPType guestIPType; @SerializedName("networkrate") private int networkRate = -1; private String tags; public NetworkOffering(long id, String name, String displayText, @Nullable Date created, String availability, boolean supportsVLAN, @Nullable Integer maxConnections, boolean isDefault, TrafficType trafficType, - int networkRate, Set tags) { + GuestIPType guestIPType, int networkRate, Set tags) { this.id = id; this.name = name; this.displayText = displayText; @@ -143,6 +151,7 @@ public class NetworkOffering implements Comparable { this.maxConnections = maxConnections; this.isDefault = isDefault; this.trafficType = trafficType; + this.guestIPType = guestIPType; this.networkRate = networkRate; this.tags = tags.size() == 0 ? null : Joiner.on(',').join(tags); } @@ -207,7 +216,8 @@ public class NetworkOffering implements Comparable { /** * - * @return the max number of concurrent connection the network offering supports + * @return the max number of concurrent connection the network offering + * supports */ @Nullable public Integer getMaxConnections() { @@ -230,6 +240,14 @@ public class NetworkOffering implements Comparable { return trafficType; } + /** + * + * @return the guest ip type for this network offering + */ + public GuestIPType getGuestIPType() { + return guestIPType; + } + /** * * @return data transfer rate in megabits per second allowed. diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java index 306d2f5c55..df659af9a1 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressAsyncClient.java @@ -73,13 +73,13 @@ public interface AddressAsyncClient { ListenableFuture getPublicIPAddress(@QueryParam("id") long id); /** - * @see AddressClient#associateIPAddress + * @see AddressClient#associateIPAddressInZone */ @GET @QueryParams(keys = "command", values = "associateIpAddress") @Unwrap @Consumes(MediaType.APPLICATION_JSON) - ListenableFuture associateIPAddress(@QueryParam("zoneid") long zoneId, + ListenableFuture associateIPAddressInZone(@QueryParam("zoneid") long zoneId, AssociateIPAddressOptions... options); /** diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java index 91dfdccce8..7f58caeb18 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/AddressClient.java @@ -62,7 +62,7 @@ public interface AddressClient { * the ID of the availability zone you want to acquire an public IP address from * @return IPAddress */ - AsyncCreateResponse associateIPAddress(long zoneId, AssociateIPAddressOptions... options); + AsyncCreateResponse associateIPAddressInZone(long zoneId, AssociateIPAddressOptions... options); /** * Disassociates an ip address from the account. diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkAsyncClient.java index 22bf0b7281..763f3c19ee 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkAsyncClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkAsyncClient.java @@ -27,6 +27,7 @@ import javax.ws.rs.core.MediaType; import org.jclouds.cloudstack.domain.Network; import org.jclouds.cloudstack.filters.QuerySigner; +import org.jclouds.cloudstack.options.CreateNetworkOptions; import org.jclouds.cloudstack.options.ListNetworksOptions; import org.jclouds.rest.annotations.ExceptionParser; import org.jclouds.rest.annotations.QueryParams; @@ -69,4 +70,24 @@ public interface NetworkAsyncClient { @ExceptionParser(ReturnNullOnNotFoundOr404.class) ListenableFuture getNetwork(@QueryParam("id") long id); + /** + * @see NetworkClient#createNetworkInZone + */ + @GET + @QueryParams(keys = "command", values = "createNetwork") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + ListenableFuture createNetworkInZone(@QueryParam("zoneid") long zoneId, + @QueryParam("networkofferingid") long networkOfferingId, @QueryParam("name") String name, + @QueryParam("displaytext") String displayText, CreateNetworkOptions... options); + + /** + * @see NetworkClient#deleteNetwork + */ + @GET + @QueryParams(keys = "command", values = "deleteNetwork") + @Unwrap(depth = 2) + @Consumes(MediaType.APPLICATION_JSON) + @ExceptionParser(ReturnNullOnNotFoundOr404.class) + ListenableFuture deleteNetwork(@QueryParam("id") long id); } diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkClient.java index 8c9cf1441d..1be3093d77 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/NetworkClient.java @@ -22,6 +22,7 @@ import java.util.Set; import java.util.concurrent.TimeUnit; import org.jclouds.cloudstack.domain.Network; +import org.jclouds.cloudstack.options.CreateNetworkOptions; import org.jclouds.cloudstack.options.ListNetworksOptions; import org.jclouds.concurrent.Timeout; @@ -53,4 +54,31 @@ public interface NetworkClient { */ Network getNetwork(long id); + /** + * Creates a network + * + * @param zoneId + * the Zone ID for the Vlan ip range + * @param networkOfferingId + * the network offering id + * @param name + * the name of the network + * @param displayText + * the display text of the network + * @param options + * optional parameters + * @return newly created network + */ + Network createNetworkInZone(long zoneId, long networkOfferingId, String name, String displayText, + CreateNetworkOptions... options); + + /** + * Deletes a network + * + * @param id + * the ID of the network + * @return job id related to destroying the network, or null if resource was not + * found + */ + Long deleteNetwork(long id); } diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java index 6de988d67b..dd48109d36 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClient.java @@ -72,14 +72,14 @@ public interface VirtualMachineAsyncClient { ListenableFuture getVirtualMachine(@QueryParam("id") long id); /** - * @see VirtualMachineClient#deployVirtualMachine + * @see VirtualMachineClient#deployVirtualMachineInZone */ @GET @QueryParams(keys = "command", values = "deployVirtualMachine") @Unwrap @Consumes(MediaType.APPLICATION_JSON) - ListenableFuture deployVirtualMachine(@QueryParam("serviceofferingid") long serviceOfferingId, - @QueryParam("templateid") long templateId, @QueryParam("zoneid") long zoneId, + ListenableFuture deployVirtualMachineInZone( @QueryParam("zoneid") long zoneId, @QueryParam("serviceofferingid") long serviceOfferingId, + @QueryParam("templateid") long templateId, DeployVirtualMachineOptions... options); /** diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java index 8882ff2236..1389309807 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/features/VirtualMachineClient.java @@ -59,15 +59,16 @@ public interface VirtualMachineClient { * Creates and automatically starts a virtual machine based on a service offering, disk offering, * and template. * + * @param zoneId + * availability zone for the virtual machine * @param serviceOfferingId * the ID of the service offering for the virtual machine * @param templateId * the ID of the template for the virtual machine - * @param zoneId - * availability zone for the virtual machine + * * @return virtual machine */ - AsyncCreateResponse deployVirtualMachine(long serviceOfferingId, long templateId, long zoneId, + AsyncCreateResponse deployVirtualMachineInZone(long zoneId, long serviceOfferingId, long templateId, DeployVirtualMachineOptions... options); /** diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ReuseOrAssociateNewPublicIPAddress.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ReuseOrAssociateNewPublicIPAddress.java index 091c4c46c3..3777a47913 100644 --- a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ReuseOrAssociateNewPublicIPAddress.java +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/functions/ReuseOrAssociateNewPublicIPAddress.java @@ -82,7 +82,7 @@ public class ReuseOrAssociateNewPublicIPAddress implements Function jobComplete) { - AsyncCreateResponse job = client.getAddressClient().associateIPAddress(network.getZoneId(), + AsyncCreateResponse job = client.getAddressClient().associateIPAddressInZone(network.getZoneId(), networkId(network.getId())); checkState(jobComplete.apply(job.getJobId()), "job %d failed to complete", job.getJobId()); PublicIPAddress ip = client.getAsyncJobClient(). getAsyncJob(job.getJobId()).getResult(); diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateNetworkOptions.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateNetworkOptions.java new file mode 100644 index 0000000000..1897a0cf04 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/options/CreateNetworkOptions.java @@ -0,0 +1,202 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.options; + +import com.google.common.collect.ImmutableSet; + +/** + * Options used to control what networks information is returned + * + * @see + * @author Adrian Cole + */ +public class CreateNetworkOptions extends AccountInDomainOptions { + + public static final CreateNetworkOptions NONE = new CreateNetworkOptions(); + + /** + * @param isDefault + * true if network is default, false otherwise + */ + public CreateNetworkOptions isDefault(boolean isDefault) { + this.queryParameters.replaceValues("isdefault", ImmutableSet.of(isDefault + "")); + return this; + } + + /** + * @param isShared + * true if network is shared, false otherwise + */ + public CreateNetworkOptions isShared(boolean isShared) { + this.queryParameters.replaceValues("isshared", ImmutableSet.of(isShared + "")); + return this; + } + + /** + * @param startIP + * the beginning IP address in the VLAN IP range + */ + public CreateNetworkOptions startIP(String startIP) { + this.queryParameters.replaceValues("startip", ImmutableSet.of(startIP)); + return this; + } + + /** + * @param endIP + * the ending IP address in the VLAN IP range + */ + public CreateNetworkOptions endIP(String endIP) { + this.queryParameters.replaceValues("endip", ImmutableSet.of(endIP)); + return this; + } + + /** + * @param gateway + * the gateway of the VLAN IP range + */ + public CreateNetworkOptions gateway(String gateway) { + this.queryParameters.replaceValues("gateway", ImmutableSet.of(gateway)); + return this; + } + + /** + * @param netmask + * the netmask of the VLAN IP range + */ + public CreateNetworkOptions netmask(String netmask) { + this.queryParameters.replaceValues("netmask", ImmutableSet.of(netmask)); + return this; + } + + /** + * @param networkDomain + * network domain + */ + public CreateNetworkOptions networkDomain(String networkDomain) { + this.queryParameters.replaceValues("networkdomain", ImmutableSet.of(networkDomain)); + return this; + } + + /** + * @param vlan + * the ID or VID of the VLAN. Default is an "untagged" VLAN. + */ + public CreateNetworkOptions vlan(String vlan) { + this.queryParameters.replaceValues("vlan", ImmutableSet.of(vlan)); + return this; + } + + public static class Builder { + /** + * @see CreateNetworkOptions#isDefault + */ + public static CreateNetworkOptions isDefault(boolean isDefault) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.isDefault(isDefault); + } + + /** + * @see CreateNetworkOptions#isShared + */ + public static CreateNetworkOptions isShared(boolean isShared) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.isShared(isShared); + } + + /** + * @see CreateNetworkOptions#startIP(String) + */ + public static CreateNetworkOptions startIP(String startIP) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.startIP(startIP); + } + + /** + * @see CreateNetworkOptions#endIP(String) + */ + public static CreateNetworkOptions endIP(String endIP) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.endIP(endIP); + } + + /** + * @see CreateNetworkOptions#gateway(String) + */ + public static CreateNetworkOptions gateway(String gateway) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.gateway(gateway); + } + + /** + * @see CreateNetworkOptions#netmask(String) + */ + public static CreateNetworkOptions netmask(String netmask) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.netmask(netmask); + } + + /** + * @see CreateNetworkOptions#networkDomain(String) + */ + public static CreateNetworkOptions networkDomain(String networkDomain) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.networkDomain(networkDomain); + } + + /** + * @see CreateNetworkOptions#vlan(String) + */ + public static CreateNetworkOptions vlan(String vlan) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.vlan(vlan); + } + + /** + * @see CreateNetworkOptions#accountInDomain + */ + public static CreateNetworkOptions accountInDomain(String account, long domain) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.accountInDomain(account, domain); + } + + /** + * @see CreateNetworkOptions#domainId + */ + public static CreateNetworkOptions domainId(long domainId) { + CreateNetworkOptions options = new CreateNetworkOptions(); + return options.domainId(domainId); + } + } + + /** + * {@inheritDoc} + */ + @Override + public CreateNetworkOptions accountInDomain(String account, long domain) { + return CreateNetworkOptions.class.cast(super.accountInDomain(account, domain)); + } + + /** + * {@inheritDoc} + */ + @Override + public CreateNetworkOptions domainId(long domainId) { + return CreateNetworkOptions.class.cast(super.domainId(domainId)); + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/NetworkOfferingPredicates.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/NetworkOfferingPredicates.java new file mode 100644 index 0000000000..9b9b5100f6 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/NetworkOfferingPredicates.java @@ -0,0 +1,61 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.predicates; + +import static com.google.common.base.Predicates.alwaysTrue; + +import org.jclouds.cloudstack.domain.GuestIPType; +import org.jclouds.cloudstack.domain.NetworkOffering; +import org.jclouds.cloudstack.domain.TrafficType; + +import com.google.common.base.Predicate; + +/** + * + * @author Adrian Cole + */ +public class NetworkOfferingPredicates { + + /** + * + * @return true, if the offering supports creation of GuestVirtual Networks + */ + public static Predicate supportsGuestVirtualNetworks() { + return new Predicate() { + + @Override + public boolean apply(NetworkOffering arg0) { + return arg0.getTrafficType() == TrafficType.GUEST && arg0.getGuestIPType() == GuestIPType.VIRTUAL; + } + + @Override + public String toString() { + return "supportsGuestVirtualNetworks()"; + } + }; + } + + /** + * + * @return always returns true. + */ + public static Predicate any() { + return alwaysTrue(); + } +} diff --git a/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/ZonePredicates.java b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/ZonePredicates.java new file mode 100644 index 0000000000..90afa1c682 --- /dev/null +++ b/sandbox-apis/cloudstack/src/main/java/org/jclouds/cloudstack/predicates/ZonePredicates.java @@ -0,0 +1,89 @@ +/** + * + * Copyright (C) 2011 Cloud Conscious, LLC. + * + * ==================================================================== + * 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.cloudstack.predicates; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Predicates.alwaysTrue; +import static com.google.common.base.Predicates.and; +import static com.google.common.base.Predicates.not; + +import org.jclouds.cloudstack.domain.NetworkType; +import org.jclouds.cloudstack.domain.Zone; + +import com.google.common.base.Predicate; + +/** + * + * @author Adrian Cole + */ +public class ZonePredicates { + /** + * + * @return true, if the zone supports {@link NetworkType.ADVANCED} + */ + public static Predicate supportsAdvancedNetworks() { + return new Predicate() { + + @Override + public boolean apply(Zone input) { + return NetworkType.ADVANCED.equals(checkNotNull(input, "zone").getNetworkType()); + } + + @Override + public String toString() { + return "supportsAvancedNetworks()"; + } + }; + } + + /** + * + * @return true, if the zone supports security groups + */ + public static Predicate supportsSecurityGroups() { + return new Predicate() { + + @Override + public boolean apply(Zone input) { + return input.isSecurityGroupsEnabled(); + } + + @Override + public String toString() { + return "supportsSecurityGroups()"; + } + }; + } + + /** + * + * @return true, if the zone supports creation of GuestVirtual Networks + */ + public static Predicate supportsGuestVirtualNetworks() { + return and(supportsAdvancedNetworks(), not(supportsSecurityGroups())); + } + + /** + * + * @return always returns true. + */ + public static Predicate any() { + return alwaysTrue(); + } +} diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AccountClientLiveTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AccountClientLiveTest.java index 5a41e1fd2d..3c4526fba4 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AccountClientLiveTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AccountClientLiveTest.java @@ -75,7 +75,8 @@ public class AccountClientLiveTest extends BaseCloudStackClientLiveTest { assert account.getVMLimit() == null || account.getVMLimit() >= 0 : account; assert account.getVMsRunning() >= 0 : account; assert account.getVMsStopped() >= 0 : account; - assert account.getVMs() >= 0 : account; + // TODO update to 2.2.4 as this is a bug in 2.2.3 + // assert account.getVMs() >= 0 : account; assert account.getVolumesAvailable() == null || account.getVolumesAvailable() >= 0 : account; assert account.getVolumeLimit() == null || account.getVolumeLimit() >= 0 : account; assert account.getVolumes() >= 0 : account; diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AddressAsyncClientTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AddressAsyncClientTest.java index 4129a18482..88e90f03f1 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AddressAsyncClientTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/AddressAsyncClientTest.java @@ -100,8 +100,8 @@ public class AddressAsyncClientTest extends BaseCloudStackAsyncClientTest getAsyncJob(job.getJobId()).getResult(); diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkAsyncClientTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkAsyncClientTest.java index 4f312b094e..ad19cbb479 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkAsyncClientTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkAsyncClientTest.java @@ -22,10 +22,12 @@ import java.io.IOException; import java.lang.reflect.Method; import org.jclouds.cloudstack.domain.NetworkType; +import org.jclouds.cloudstack.options.CreateNetworkOptions; import org.jclouds.cloudstack.options.ListNetworksOptions; import org.jclouds.http.HttpRequest; import org.jclouds.http.functions.UnwrapOnlyNestedJsonValue; import org.jclouds.http.functions.UnwrapOnlyNestedJsonValueInSet; +import org.jclouds.rest.functions.MapHttp4xxCodesToExceptions; import org.jclouds.rest.functions.ReturnEmptySetOnNotFoundOr404; import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404; import org.jclouds.rest.internal.RestAnnotationProcessor; @@ -46,7 +48,7 @@ public class NetworkAsyncClientTest extends BaseCloudStackAsyncClientTest> createTypeLiteral() { return new TypeLiteral>() { diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkClientLiveTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkClientLiveTest.java index 02294df405..2f83ad3a48 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkClientLiveTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/NetworkClientLiveTest.java @@ -18,14 +18,22 @@ */ package org.jclouds.cloudstack.features; +import static com.google.common.collect.Iterables.find; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; +import java.util.NoSuchElementException; import java.util.Set; import org.jclouds.cloudstack.domain.GuestIPType; import org.jclouds.cloudstack.domain.Network; +import org.jclouds.cloudstack.domain.NetworkOffering; +import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.options.ListNetworksOptions; +import org.jclouds.cloudstack.predicates.NetworkOfferingPredicates; +import org.jclouds.cloudstack.predicates.ZonePredicates; +import org.testng.annotations.AfterGroups; +import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; import com.google.common.collect.Iterables; @@ -38,7 +46,46 @@ import com.google.common.collect.Iterables; @Test(groups = "live", singleThreaded = true, testName = "NetworkClientLiveTest") public class NetworkClientLiveTest extends BaseCloudStackClientLiveTest { + private boolean networksSupported; + + private Zone zone; + private NetworkOffering offering; + + private Network network; + + @BeforeGroups(groups = "live") + public void setupClient() { + super.setupClient(); + + try { + // you can create guest direct network by Admin user, but since we are + // not admin, let's try to create a guest virtual one + zone = find(client.getZoneClient().listZones(), ZonePredicates.supportsGuestVirtualNetworks()); + offering = Iterables.find(client.getOfferingClient().listNetworkOfferings(), + NetworkOfferingPredicates.supportsGuestVirtualNetworks()); + networksSupported = true; + } catch (NoSuchElementException e) { + } + } + + public void testCreateNetwork() throws Exception { + if (!networksSupported) + return; + network = client.getNetworkClient().createNetworkInZone(zone.getId(), offering.getId(), prefix, prefix); + checkNetwork(network); + } + + @AfterGroups(groups = "live") + protected void tearDown() { + if (network != null) { + jobComplete.apply(client.getNetworkClient().deleteNetwork(network.getId())); + } + super.tearDown(); + } + public void testListNetworks() throws Exception { + if (!networksSupported) + return; Set response = client.getNetworkClient().listNetworks(); assert null != response; long networkCount = response.size(); @@ -48,43 +95,47 @@ public class NetworkClientLiveTest extends BaseCloudStackClientLiveTest { ListNetworksOptions.Builder.id(network.getId()))); assertEquals(network, newDetails); assertEquals(network, client.getNetworkClient().getNetwork(network.getId())); - assert network.getId() > 0 : network; - assert network.getName() != null : network; - assert network.getDNS().size() != 0 : network; - assert network.getGuestIPType() != null && network.getGuestIPType() != GuestIPType.UNRECOGNIZED : network; - assert network.getAccount() != null : network; - assert network.getBroadcastDomainType() != null : network; - assert network.getDisplayText() != null : network; - assert network.getNetworkDomain() != null : network; - assert network.getNetworkOfferingAvailability() != null : network; - assert network.getNetworkOfferingDisplayText() != null : network; - assert network.getNetworkOfferingId() > 0 : network; - assert network.getNetworkOfferingName() != null : network; - assert network.getRelated() > 0 : network; - assert network.getServices().size() != 0 : network; - assert network.getState() != null : network; - assert network.getTrafficType() != null : network; - assert network.getZoneId() > 0 : network; - assert network.getDomain() != null : network; - assert network.getDomainId() > 0 : network; - switch (network.getGuestIPType()) { - case VIRTUAL: - assert network.getNetmask() == null : network; - assert network.getGateway() == null : network; - assert network.getVLAN() == null : network; - assert network.getStartIP() == null : network; - assert network.getEndIP() == null : network; - break; - case DIRECT: - assert network.getNetmask() != null : network; - assert network.getGateway() != null : network; - assert network.getVLAN() != null : network; - assertEquals(network.getBroadcastURI(), "vlan://" + network.getVLAN()); - assert network.getStartIP() != null : network; - assert network.getEndIP() != null : network; - break; - } + checkNetwork(network); } } + + private void checkNetwork(Network network) { + assert network.getId() > 0 : network; + assert network.getName() != null : network; + assert network.getDNS().size() != 0 : network; + assert network.getGuestIPType() != null && network.getGuestIPType() != GuestIPType.UNRECOGNIZED : network; + assert network.getAccount() != null : network; + assert network.getBroadcastDomainType() != null : network; + assert network.getDisplayText() != null : network; + assert network.getNetworkDomain() != null : network; + assert network.getNetworkOfferingAvailability() != null : network; + assert network.getNetworkOfferingDisplayText() != null : network; + assert network.getNetworkOfferingId() > 0 : network; + assert network.getNetworkOfferingName() != null : network; + assert network.getRelated() > 0 : network; + assert network.getServices().size() != 0 : network; + assert network.getState() != null : network; + assert network.getTrafficType() != null : network; + assert network.getZoneId() > 0 : network; + assert network.getDomain() != null : network; + assert network.getDomainId() > 0 : network; + switch (network.getGuestIPType()) { + case VIRTUAL: + assert network.getNetmask() == null : network; + assert network.getGateway() == null : network; + assert network.getVLAN() == null : network; + assert network.getStartIP() == null : network; + assert network.getEndIP() == null : network; + break; + case DIRECT: + assert network.getNetmask() != null : network; + assert network.getGateway() != null : network; + assert network.getVLAN() != null : network; + assertEquals(network.getBroadcastURI(), "vlan://" + network.getVLAN()); + assert network.getStartIP() != null : network; + assert network.getEndIP() != null : network; + break; + } + } } diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java index c75571f997..9ff540d7bd 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/SecurityGroupClientLiveTest.java @@ -31,7 +31,6 @@ import org.jclouds.cloudstack.domain.VirtualMachine; import org.jclouds.cloudstack.domain.Zone; import org.jclouds.cloudstack.options.AccountInDomainOptions; import org.jclouds.cloudstack.options.ListSecurityGroupsOptions; -import org.jclouds.cloudstack.options.ListVirtualMachinesOptions; import org.jclouds.net.IPSocket; import org.jclouds.util.Strings2; import org.testng.annotations.AfterGroups; @@ -170,9 +169,6 @@ public class SecurityGroupClientLiveTest extends BaseCloudStackClientLiveTest { public void testCreateVMInSecurityGroup() throws Exception { if (!securityGroupsSupported) return; - for (VirtualMachine vm : client.getVirtualMachineClient().listVirtualMachines( - ListVirtualMachinesOptions.Builder.zoneId(zone.getId()))) { - } vm = VirtualMachineClientLiveTest.createVirtualMachineWithSecurityGroupInZone(zone.getId(), group.getId(), client, jobComplete, virtualMachineRunning); if (vm.getPassword() != null) diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java index 3ae7068003..1263c8a1e9 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineAsyncClientTest.java @@ -98,14 +98,14 @@ public class VirtualMachineAsyncClientTest extends BaseCloudStackAsyncClientTest } - public void testDeployVirtualMachine() throws SecurityException, NoSuchMethodException, IOException { - Method method = VirtualMachineAsyncClient.class.getMethod("deployVirtualMachine", long.class, long.class, + public void testDeployVirtualMachineInZone() throws SecurityException, NoSuchMethodException, IOException { + Method method = VirtualMachineAsyncClient.class.getMethod("deployVirtualMachineInZone", long.class, long.class, long.class, DeployVirtualMachineOptions[].class); - HttpRequest httpRequest = processor.createRequest(method, 4, 5, 6); + HttpRequest httpRequest = processor.createRequest(method, 6, 4, 5); assertRequestLineEquals( httpRequest, - "GET http://localhost:8080/client/api?response=json&command=deployVirtualMachine&serviceofferingid=4&zoneid=6&templateid=5 HTTP/1.1"); + "GET http://localhost:8080/client/api?response=json&command=deployVirtualMachine&zoneid=6&templateid=5&serviceofferingid=4 HTTP/1.1"); assertNonPayloadHeadersEqual(httpRequest, "Accept: application/json\n"); assertPayloadEquals(httpRequest, null, null, false); diff --git a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java index 7958071edb..22b5a2c953 100644 --- a/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java +++ b/sandbox-apis/cloudstack/src/test/java/org/jclouds/cloudstack/features/VirtualMachineClientLiveTest.java @@ -72,39 +72,39 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { static final Ordering DEFAULT_SIZE_ORDERING = new Ordering() { public int compare(ServiceOffering left, ServiceOffering right) { - return ComparisonChain.start().compare(left.getCpuNumber(), right.getCpuNumber()).compare(left.getMemory(), - right.getMemory()).result(); + return ComparisonChain.start().compare(left.getCpuNumber(), right.getCpuNumber()) + .compare(left.getMemory(), right.getMemory()).result(); } }; public static VirtualMachine createVirtualMachine(CloudStackClient client, RetryablePredicate jobComplete, - RetryablePredicate virtualMachineRunning) { + RetryablePredicate virtualMachineRunning) { Set networks = client.getNetworkClient().listNetworks(); if (networks.size() > 0) { return createVirtualMachineInNetwork(get(networks, 0), client, jobComplete, virtualMachineRunning); } else { - return createVirtualMachineWithSecurityGroupInZone(find(client.getZoneClient().listZones(), - new Predicate() { + return createVirtualMachineWithSecurityGroupInZone( + find(client.getZoneClient().listZones(), new Predicate() { - @Override - public boolean apply(Zone arg0) { - return arg0.isSecurityGroupsEnabled(); - } + @Override + public boolean apply(Zone arg0) { + return arg0.isSecurityGroupsEnabled(); + } - }).getId(), get(client.getSecurityGroupClient().listSecurityGroups(), 0).getId(), client, - jobComplete, virtualMachineRunning); + }).getId(), get(client.getSecurityGroupClient().listSecurityGroups(), 0).getId(), client, jobComplete, + virtualMachineRunning); } } public static VirtualMachine createVirtualMachineWithSecurityGroupInZone(long zoneId, long groupId, - CloudStackClient client, RetryablePredicate jobComplete, - RetryablePredicate virtualMachineRunning) { + CloudStackClient client, RetryablePredicate jobComplete, + RetryablePredicate virtualMachineRunning) { return createVirtualMachineWithOptionsInZone(new DeployVirtualMachineOptions().securityGroupId(groupId), zoneId, - client, jobComplete, virtualMachineRunning); + client, jobComplete, virtualMachineRunning); } public static VirtualMachine createVirtualMachineInNetwork(Network network, CloudStackClient client, - RetryablePredicate jobComplete, RetryablePredicate virtualMachineRunning) { + RetryablePredicate jobComplete, RetryablePredicate virtualMachineRunning) { DeployVirtualMachineOptions options = new DeployVirtualMachineOptions(); long zoneId = network.getZoneId(); options.networkId(network.getId()); @@ -112,8 +112,8 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { } public static VirtualMachine createVirtualMachineWithOptionsInZone(DeployVirtualMachineOptions options, - final long zoneId, CloudStackClient client, RetryablePredicate jobComplete, - RetryablePredicate virtualMachineRunning) { + final long zoneId, CloudStackClient client, RetryablePredicate jobComplete, + RetryablePredicate virtualMachineRunning) { // TODO enum, as this is way too easy to mess up. Set acceptableCategories = ImmutableSet.of("Ubuntu", "CentOS"); @@ -121,9 +121,9 @@ public class VirtualMachineClientLiveTest extends BaseCloudStackClientLiveTest { final Predicate