From 55975af60de95bf415bfee6fe370b3d93ef31d4f Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Sun, 29 Jan 2012 20:29:33 +0800 Subject: [PATCH] Issue 820:Move off PropertiesBuilder for rocoto --- .../CloudSigmaPropertiesBuilder.java | 8 - .../CloudSigmaComputeServiceAdapter.java | 2 + .../ElasticStackPropertiesBuilder.java | 9 - .../ElasticStackComputeServiceAdapter.java | 2 + .../org/jclouds/s3/S3PropertiesBuilder.java | 18 +- .../vcloud/VCloudPropertiesBuilder.java | 23 +-- .../AzureStoragePropertiesBuilder.java | 57 ------ .../TerremarkVCloudPropertiesBuilder.java | 48 +---- core/pom.xml | 5 + .../java/org/jclouds/PropertiesBuilder.java | 3 + .../FilterStringsBoundToInjectorByName.java | 95 ++++++++++ ...Iso3166CodesByLocationIdViaProperties.java | 55 +++--- .../ProvideRegionToURIViaProperties.java | 11 +- .../org/jclouds/rest/RestContextBuilder.java | 173 +++++++++++------- .../org/jclouds/rest/annotations/Api.java | 3 +- .../jclouds/rest/annotations/ApiVersion.java | 3 +- .../rest/annotations/BuildVersion.java | 3 +- .../jclouds/rest/annotations/Credential.java | 3 +- .../jclouds/rest/annotations/Identity.java | 3 +- .../rest/internal/AsyncRestClientProxy.java | 3 +- .../rest/internal/SeedAnnotationCache.java | 22 +-- core/src/main/resources/rest.properties | 3 +- ...ilterStringsBoundToInjectorByNameTest.java | 104 +++++++++++ ...166CodesByLocationIdViaPropertiesTest.java | 94 ++++++++++ .../jclouds/aws/ec2/AWSEC2ContextBuilder.java | 34 +++- .../aws/ec2/AWSEC2PropertiesBuilder.java | 24 --- ...est.java => AWSEC2ContextBuilderTest.java} | 10 +- providers/azureblob/pom.xml | 2 +- .../azureblob/AzureBlobPropertiesBuilder.java | 6 +- sandbox-providers/azurequeue/pom.xml | 2 +- 30 files changed, 511 insertions(+), 317 deletions(-) delete mode 100644 common/azure/src/main/java/org/jclouds/azure/storage/AzureStoragePropertiesBuilder.java create mode 100644 core/src/main/java/org/jclouds/internal/FilterStringsBoundToInjectorByName.java create mode 100644 core/src/test/java/org/jclouds/internal/FilterStringsBoundToInjectorByNameTest.java create mode 100644 core/src/test/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaPropertiesTest.java rename providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/{AWSEC2PropertiesBuilderTest.java => AWSEC2ContextBuilderTest.java} (87%) diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaPropertiesBuilder.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaPropertiesBuilder.java index bdcb5128ba..bf13f88b68 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaPropertiesBuilder.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/CloudSigmaPropertiesBuilder.java @@ -18,7 +18,6 @@ */ package org.jclouds.cloudsigma; -import static com.google.common.base.Preconditions.checkArgument; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.cloudsigma.reference.CloudSigmaConstants.PROPERTY_VNC_PASSWORD; @@ -48,11 +47,4 @@ public class CloudSigmaPropertiesBuilder extends PropertiesBuilder { super(properties); } - @Override - public Properties build() { - Properties props = super.build(); - checkArgument(props.getProperty(PROPERTY_VNC_PASSWORD).length() <= 8, - "vnc passwords should be less that 8 characters!"); - return props; - } } diff --git a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java index 6886561e46..8eb2b6742a 100644 --- a/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java +++ b/apis/cloudsigma/src/main/java/org/jclouds/cloudsigma/compute/CloudSigmaComputeServiceAdapter.java @@ -18,6 +18,7 @@ */ package org.jclouds.cloudsigma.compute; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.filter; import static org.jclouds.concurrent.FutureIterables.transformParallel; @@ -104,6 +105,7 @@ public class CloudSigmaComputeServiceAdapter implements this.driveNotClaimed = checkNotNull(driveNotClaimed, "driveNotClaimed"); this.locationSupplier = checkNotNull(locationSupplier, "locationSupplier"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); + checkArgument(defaultVncPassword.length() <= 8, "vnc passwords should be less that 8 characters!"); this.cache = checkNotNull(cache, "cache"); this.executor = checkNotNull(executor, "executor"); } diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackPropertiesBuilder.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackPropertiesBuilder.java index d96200cf89..20395769c4 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackPropertiesBuilder.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/ElasticStackPropertiesBuilder.java @@ -18,7 +18,6 @@ */ package org.jclouds.elasticstack; -import static com.google.common.base.Preconditions.checkArgument; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.elasticstack.reference.ElasticStackConstants.PROPERTY_VNC_PASSWORD; @@ -44,14 +43,6 @@ public class ElasticStackPropertiesBuilder extends PropertiesBuilder { return properties; } - @Override - public Properties build() { - Properties props = super.build(); - checkArgument(props.getProperty(PROPERTY_VNC_PASSWORD).length() <= 8, - "vnc passwords should be less that 8 characters!"); - return props; - } - public ElasticStackPropertiesBuilder(Properties properties) { super(properties); } diff --git a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java index 3bfd57a83c..d2904595ad 100644 --- a/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java +++ b/apis/elasticstack/src/main/java/org/jclouds/elasticstack/compute/ElasticStackComputeServiceAdapter.java @@ -18,6 +18,7 @@ */ package org.jclouds.elasticstack.compute; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Predicates.notNull; import static com.google.common.collect.Iterables.filter; @@ -100,6 +101,7 @@ public class ElasticStackComputeServiceAdapter implements this.preinstalledImages = checkNotNull(preinstalledImages, "preinstalledImages"); this.cache = checkNotNull(cache, "cache"); this.defaultVncPassword = checkNotNull(defaultVncPassword, "defaultVncPassword"); + checkArgument(defaultVncPassword.length() <= 8, "vnc passwords should be less that 8 characters!"); this.executor = checkNotNull(executor, "executor"); } diff --git a/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java b/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java index 7e00122ae4..e2158f769d 100644 --- a/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java +++ b/apis/s3/src/main/java/org/jclouds/s3/S3PropertiesBuilder.java @@ -49,6 +49,7 @@ public class S3PropertiesBuilder extends PropertiesBuilder { properties.setProperty(PROPERTY_S3_VIRTUAL_HOST_BUCKETS, "true"); properties.setProperty(PROPERTY_RELAX_HOSTNAME, "true"); properties.setProperty(PROPERTY_BLOBSTORE_DIRECTORY_SUFFIX, DIRECTORY_SUFFIX_FOLDER); + properties.setProperty(PROPERTY_USER_METADATA_PREFIX, String.format("x-${%s}-meta-", PROPERTY_HEADER_TAG)); return properties; } @@ -60,21 +61,4 @@ public class S3PropertiesBuilder extends PropertiesBuilder { super(); } - protected S3PropertiesBuilder withMetaPrefix(String prefix) { - properties.setProperty(PROPERTY_USER_METADATA_PREFIX, prefix); - return this; - } - - protected void setMetaPrefix() { - if (properties.getProperty(PROPERTY_USER_METADATA_PREFIX) == null) { - properties.setProperty(PROPERTY_USER_METADATA_PREFIX, String.format("x-%s-meta-", properties - .getProperty(PROPERTY_HEADER_TAG))); - } - } - - @Override - public Properties build() { - setMetaPrefix(); - return super.build(); - } } diff --git a/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudPropertiesBuilder.java b/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudPropertiesBuilder.java index c24533e0b5..d5522c343b 100644 --- a/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudPropertiesBuilder.java +++ b/apis/vcloud/src/main/java/org/jclouds/vcloud/VCloudPropertiesBuilder.java @@ -42,6 +42,8 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_API_VERSION, "1.0"); properties.setProperty(PROPERTY_VCLOUD_VERSION_SCHEMA, "1"); + properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE, + String.format("http://www.vmware.com/vcloud/v${%s}", PROPERTY_VCLOUD_VERSION_SCHEMA)); properties.setProperty(PROPERTY_SESSION_INTERVAL, 8 * 60 + ""); properties.setProperty(PROPERTY_VCLOUD_XML_SCHEMA, "http://vcloud.safesecureweb.com/ns/vcloud.xsd"); properties.setProperty("jclouds.dns_name_length_min", "1"); @@ -58,25 +60,4 @@ public class VCloudPropertiesBuilder extends PropertiesBuilder { super(properties); } - protected void setNs() { - if (properties.getProperty(PROPERTY_VCLOUD_XML_NAMESPACE) == null) - properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE, "http://www.vmware.com/vcloud/v" - + properties.getProperty(PROPERTY_VCLOUD_VERSION_SCHEMA)); - } - - public VCloudPropertiesBuilder withApiVersion(String version) { - properties.setProperty(PROPERTY_API_VERSION, "1.0"); - return this; - } - - public VCloudPropertiesBuilder withSchemaVersion(String version) { - properties.setProperty(PROPERTY_VCLOUD_VERSION_SCHEMA, "1.0"); - return this; - } - - @Override - public Properties build() { - setNs(); - return super.build(); - } } diff --git a/common/azure/src/main/java/org/jclouds/azure/storage/AzureStoragePropertiesBuilder.java b/common/azure/src/main/java/org/jclouds/azure/storage/AzureStoragePropertiesBuilder.java deleted file mode 100644 index 0a21864c12..0000000000 --- a/common/azure/src/main/java/org/jclouds/azure/storage/AzureStoragePropertiesBuilder.java +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Licensed to jclouds, Inc. (jclouds) under one or more - * contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. jclouds licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.jclouds.azure.storage; - -import static org.jclouds.Constants.PROPERTY_ENDPOINT; -import static org.jclouds.Constants.PROPERTY_IDENTITY; - -import java.util.Properties; -import java.util.regex.Pattern; - -import org.jclouds.PropertiesBuilder; -import org.jclouds.util.Strings2; - -/** - * Builds properties used in Azure Connections - * - * @author Adrian Cole - */ -public class AzureStoragePropertiesBuilder extends PropertiesBuilder { - - public AzureStoragePropertiesBuilder() { - this(new Properties()); - } - - public AzureStoragePropertiesBuilder(Properties properties) { - super(properties); - } - - public static final Pattern IDENTITY_PATTERN = Pattern.compile("\\{identity\\}"); - - @Override - public Properties build() { - String endpoint = properties.getProperty(PROPERTY_ENDPOINT); - String identity = properties.getProperty(PROPERTY_IDENTITY); - - properties.setProperty(PROPERTY_ENDPOINT, Strings2.replaceAll(endpoint, IDENTITY_PATTERN, - identity)); - return super.build(); - } - -} diff --git a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/TerremarkVCloudPropertiesBuilder.java b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/TerremarkVCloudPropertiesBuilder.java index a3081f88fb..c294ec643b 100644 --- a/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/TerremarkVCloudPropertiesBuilder.java +++ b/common/trmk/src/main/java/org/jclouds/trmk/vcloud_0_8/TerremarkVCloudPropertiesBuilder.java @@ -33,7 +33,6 @@ import java.util.Properties; import java.util.concurrent.TimeUnit; import org.jclouds.PropertiesBuilder; -import org.jclouds.trmk.vcloud_0_8.domain.FenceMode; /** * Builds properties used in Terremark VCloud Clients @@ -48,10 +47,16 @@ public class TerremarkVCloudPropertiesBuilder extends PropertiesBuilder { properties.setProperty(PROPERTY_VCLOUD_VERSION_SCHEMA, "0.8"); properties.setProperty(PROPERTY_SESSION_INTERVAL, 8 * 60 + ""); properties.setProperty(PROPERTY_VCLOUD_XML_SCHEMA, "http://vcloud.safesecureweb.com/ns/vcloud.xsd"); + properties.setProperty(PROPERTY_VCLOUD_DEFAULT_FENCEMODE, "allowInOut"); + properties.setProperty(PROPERTY_TERREMARK_EXTENSION_NS, String.format("urn:tmrk:${%s}-${%s}", + PROPERTY_TERREMARK_EXTENSION_NAME, PROPERTY_TERREMARK_EXTENSION_VERSION)); + properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE, + String.format("http://www.vmware.com/vcloud/v${%s}", PROPERTY_VCLOUD_VERSION_SCHEMA)); properties.setProperty("jclouds.dns_name_length_min", "1"); properties.setProperty("jclouds.dns_name_length_max", "15"); // terremark can sometimes block extremely long times properties.setProperty(PROPERTY_VCLOUD_TIMEOUT_TASK_COMPLETED, TimeUnit.MINUTES.toMillis(20) + ""); + return properties; } @@ -59,45 +64,4 @@ public class TerremarkVCloudPropertiesBuilder extends PropertiesBuilder { super(properties); } - void setExtensions() { - if (properties.getProperty(PROPERTY_TERREMARK_EXTENSION_NS) == null) { - properties.setProperty( - PROPERTY_TERREMARK_EXTENSION_NS, - String.format("urn:tmrk:%s-%s", properties.getProperty(PROPERTY_TERREMARK_EXTENSION_NAME), - properties.getProperty(PROPERTY_TERREMARK_EXTENSION_VERSION))); - } - } - - protected void setNs() { - if (properties.getProperty(PROPERTY_VCLOUD_XML_NAMESPACE) == null) - properties.setProperty(PROPERTY_VCLOUD_XML_NAMESPACE, - "http://www.vmware.com/vcloud/v" + properties.getProperty(PROPERTY_VCLOUD_VERSION_SCHEMA)); - } - - protected void setFenceMode() { - if (properties.getProperty(PROPERTY_VCLOUD_DEFAULT_FENCEMODE) == null) { - if (properties.getProperty(PROPERTY_VCLOUD_VERSION_SCHEMA).startsWith("0.8")) - properties.setProperty(PROPERTY_VCLOUD_DEFAULT_FENCEMODE, "allowInOut"); - else - properties.setProperty(PROPERTY_VCLOUD_DEFAULT_FENCEMODE, FenceMode.ALLOW_IN_OUT.toString()); - } - } - - public TerremarkVCloudPropertiesBuilder withApiVersion(String version) { - properties.setProperty(PROPERTY_API_VERSION, "0.8"); - return this; - } - - public TerremarkVCloudPropertiesBuilder withSchemaVersion(String version) { - properties.setProperty(PROPERTY_VCLOUD_VERSION_SCHEMA, "0.8"); - return this; - } - - @Override - public Properties build() { - setNs(); - setFenceMode(); - setExtensions(); - return super.build(); - } } diff --git a/core/pom.xml b/core/pom.xml index 67ff4ec4b5..b3f3122c09 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -71,6 +71,11 @@ guice 3.0 + + org.99soft.guice + rocoto + 6.0 + javax.inject javax.inject diff --git a/core/src/main/java/org/jclouds/PropertiesBuilder.java b/core/src/main/java/org/jclouds/PropertiesBuilder.java index 0fb4e3b7f9..cd39355e3e 100644 --- a/core/src/main/java/org/jclouds/PropertiesBuilder.java +++ b/core/src/main/java/org/jclouds/PropertiesBuilder.java @@ -18,6 +18,7 @@ */ package org.jclouds; +import static org.jclouds.Constants.PROPERTY_API; import static org.jclouds.Constants.PROPERTY_API_VERSION; import static org.jclouds.Constants.PROPERTY_BUILD_VERSION; import static org.jclouds.Constants.PROPERTY_CONNECTION_TIMEOUT; @@ -219,6 +220,8 @@ public class PropertiesBuilder { props.setProperty(PROPERTY_CONNECTION_TIMEOUT, 60000 + ""); props.setProperty(PROPERTY_IO_WORKER_THREADS, 20 + ""); props.setProperty(PROPERTY_USER_THREADS, 0 + ""); + props.setProperty(PROPERTY_API, ""); + props.setProperty(PROPERTY_API_VERSION, ""); props.setProperty(PROPERTY_BUILD_VERSION, ""); props.setProperty(PROPERTY_MAX_CONNECTION_REUSE, 75 + ""); props.setProperty(PROPERTY_MAX_SESSION_FAILURES, 2 + ""); diff --git a/core/src/main/java/org/jclouds/internal/FilterStringsBoundToInjectorByName.java b/core/src/main/java/org/jclouds/internal/FilterStringsBoundToInjectorByName.java new file mode 100644 index 0000000000..4fb90ef567 --- /dev/null +++ b/core/src/main/java/org/jclouds/internal/FilterStringsBoundToInjectorByName.java @@ -0,0 +1,95 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.internal; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.lang.annotation.Annotation; +import java.util.List; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.inject.Binding; +import com.google.inject.Injector; +import com.google.inject.TypeLiteral; + +/** + * finds all the named string bindings who's name annotation matches the filter. + * for convenience, the bindings are returned as a map. + * + * @author Adrian Cole + */ +@Singleton +public class FilterStringsBoundToInjectorByName implements Function, Map> { + + private final Injector injector; + + @Inject + public FilterStringsBoundToInjectorByName(Injector injector) { + this.injector = checkNotNull(injector, "injector"); + } + + @Override + public Map apply(Predicate filter) { + List> stringBindings = injector.findBindingsByType(new TypeLiteral() { + }); + Iterable> annotatedWithName = Iterables.filter(stringBindings, new Predicate>() { + + @Override + public boolean apply(Binding input) { + Annotation annotation = input.getKey().getAnnotation(); + if (annotation == null) + return false; + return (annotation instanceof javax.inject.Named) || (annotation instanceof com.google.inject.name.Named); + } + + }); + + Map> bindingsByName = Maps.uniqueIndex(annotatedWithName, + new Function, String>() { + + @Override + public String apply(Binding input) { + Annotation annotation = input.getKey().getAnnotation(); + return ((annotation instanceof javax.inject.Named) ? javax.inject.Named.class.cast(annotation) + .value() : com.google.inject.name.Named.class.cast(annotation).value()); + } + + }); + + Map> filteredBindingsByName = Maps.filterKeys(bindingsByName, filter); + + Map stringBoundByName = Maps.transformValues(filteredBindingsByName, + new Function, String>() { + + @Override + public String apply(Binding input) { + return input.getProvider().get(); + } + }); + return stringBoundByName; + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaProperties.java b/core/src/main/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaProperties.java index e048c4d1fe..84a051dca3 100644 --- a/core/src/main/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaProperties.java +++ b/core/src/main/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaProperties.java @@ -19,7 +19,6 @@ package org.jclouds.location.config; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.inject.name.Names.named; import static org.jclouds.location.reference.LocationConstants.ISO3166_CODES; import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGION; import static org.jclouds.location.reference.LocationConstants.PROPERTY_ZONE; @@ -32,54 +31,54 @@ import javax.inject.Singleton; import org.jclouds.location.Iso3166; +import com.google.common.base.Function; +import com.google.common.base.Predicate; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableMap.Builder; -import com.google.inject.ConfigurationException; -import com.google.inject.Injector; -import com.google.inject.Key; +import com.google.common.collect.ImmutableSet; /** * - * looks for properties bound to the naming conventions jclouds.region.{@code regionId} - * .iso3166-codes and jclouds.zone.{@code zoneId}.iso3166-codes + * looks for properties bound to the naming conventions jclouds.region. + * {@code regionId} .iso3166-codes and jclouds.zone.{@code zoneId}.iso3166-codes * * @author Adrian Cole */ @Singleton public class ProvideIso3166CodesByLocationIdViaProperties implements javax.inject.Provider>> { - private final Injector injector; + private final Function, Map> filterStringsBoundByName; @Inject - ProvideIso3166CodesByLocationIdViaProperties(Injector injector) { - this.injector = checkNotNull(injector, "injector"); + ProvideIso3166CodesByLocationIdViaProperties( + Function, Map> filterStringsBoundByName) { + this.filterStringsBoundByName = checkNotNull(filterStringsBoundByName, "filterStringsBoundByName"); } @Singleton @Iso3166 @Override public Map> get() { - Builder> codes = ImmutableMap.> builder(); - for (String key : ImmutableSet.of(PROPERTY_REGION, PROPERTY_ZONE)) - try { - String regionString = injector.getInstance(Key.get(String.class, named(key + "s"))); - for (String region : Splitter.on(',').split(regionString)) { - try { - codes.put(region, ImmutableSet.copyOf(Splitter.on(',') - .split( - injector.getInstance(Key.get(String.class, named(key + "." + region + "." - + ISO3166_CODES)))))); - } catch (ConfigurationException e) { - // this happens if regions property isn't set - // services not run by AWS may not have regions, so this is ok. - } - } - } catch (ConfigurationException e) { - // this happens if regions property isn't set - // services not run by AWS may not have regions, so this is ok. + Map stringsBoundWithRegionOrZonePrefix = filterStringsBoundByName.apply(new Predicate() { + + @Override + public boolean apply(String input) { + return input.startsWith(PROPERTY_REGION) || input.startsWith(PROPERTY_ZONE); } + + }); + Builder> codes = ImmutableMap.> builder(); + for (String key : ImmutableSet.of(PROPERTY_REGION, PROPERTY_ZONE)) { + String regionOrZoneString = stringsBoundWithRegionOrZonePrefix.get(key + "s"); + if (regionOrZoneString == null) + continue; + for (String region : Splitter.on(',').split(regionOrZoneString)) { + String isoCodes = stringsBoundWithRegionOrZonePrefix.get(key + "." + region + "." + ISO3166_CODES); + if (isoCodes != null) + codes.put(region, ImmutableSet.copyOf(Splitter.on(',').split(isoCodes))); + } + } return codes.build(); } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java b/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java index cbe7f07052..93cd5a6ede 100644 --- a/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java +++ b/core/src/main/java/org/jclouds/location/config/ProvideRegionToURIViaProperties.java @@ -24,11 +24,9 @@ import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS; import java.net.URI; import java.util.Map; -import java.util.Map.Entry; import javax.annotation.Resource; import javax.inject.Inject; -import javax.inject.Named; import javax.inject.Singleton; import org.jclouds.location.Region; @@ -36,7 +34,6 @@ import org.jclouds.logging.Logger; import com.google.common.base.Splitter; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Multimap; import com.google.common.collect.ImmutableMap.Builder; import com.google.inject.ConfigurationException; import com.google.inject.Injector; @@ -53,15 +50,13 @@ import com.google.inject.name.Names; public class ProvideRegionToURIViaProperties implements javax.inject.Provider> { private final Injector injector; - private final Multimap constants; @Resource protected Logger logger = Logger.NULL; @Inject - protected ProvideRegionToURIViaProperties(Injector injector, @Named("CONSTANTS") Multimap constants) { + protected ProvideRegionToURIViaProperties(Injector injector) { this.injector = injector; - this.constants = constants; } @Singleton @@ -74,10 +69,6 @@ public class ProvideRegionToURIViaProperties implements javax.inject.Provider entry : constants.entries()) { - regionUri = regionUri.replace(new StringBuilder().append('{').append(entry.getKey()).append('}').toString(), entry - .getValue()); - } regions.put(region, URI.create(regionUri)); } return regions.build(); diff --git a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java index e60d9bd1c0..3afaf919b0 100644 --- a/core/src/main/java/org/jclouds/rest/RestContextBuilder.java +++ b/core/src/main/java/org/jclouds/rest/RestContextBuilder.java @@ -27,7 +27,6 @@ import static com.google.common.collect.Iterables.addAll; import static com.google.common.collect.Iterables.any; import static com.google.common.collect.Iterables.filter; import static com.google.inject.Scopes.SINGLETON; -import static com.google.inject.name.Names.bindProperties; import static com.google.inject.util.Types.newParameterizedType; import static org.jclouds.Constants.PROPERTY_API; import static org.jclouds.Constants.PROPERTY_API_VERSION; @@ -45,7 +44,6 @@ import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; -import java.util.Map.Entry; import javax.inject.Inject; import javax.inject.Named; @@ -55,9 +53,12 @@ import org.jclouds.concurrent.MoreExecutors; import org.jclouds.concurrent.SingleThreaded; import org.jclouds.concurrent.config.ConfiguresExecutorService; import org.jclouds.concurrent.config.ExecutorServiceModule; +import org.jclouds.config.ValueOfConfigurationKeyOrNull; import org.jclouds.http.RequiresHttp; import org.jclouds.http.config.ConfiguresHttpCommandExecutorService; import org.jclouds.http.config.JavaUrlHttpCommandExecutorServiceModule; +import org.jclouds.internal.FilterStringsBoundToInjectorByName; +import org.jclouds.javax.annotation.Nullable; import org.jclouds.lifecycle.config.LifeCycleModule; import org.jclouds.location.Iso3166; import org.jclouds.location.Provider; @@ -73,14 +74,15 @@ import org.jclouds.rest.config.CredentialStoreModule; import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestModule; import org.jclouds.rest.internal.RestContextImpl; +import org.jclouds.util.Maps2; +import org.nnsoft.guice.rocoto.Rocoto; +import org.nnsoft.guice.rocoto.configuration.ConfigurationModule; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; import com.google.common.base.Predicate; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.LinkedHashMultimap; -import com.google.common.collect.Multimap; +import com.google.common.collect.Maps; import com.google.common.util.concurrent.ExecutionList; import com.google.inject.AbstractModule; import com.google.inject.Guice; @@ -106,69 +108,105 @@ import com.google.inject.TypeLiteral; */ public class RestContextBuilder { - static class BindPropertiesAndPrincipalContext extends AbstractModule { - protected Properties properties; - - protected BindPropertiesAndPrincipalContext(Properties properties) { - this.properties = checkNotNull(properties, "properties"); - } - - @Provides - @Singleton - @Named("CONSTANTS") - protected Multimap constants() { - ImmutableMultimap.Builder builder = ImmutableMultimap. builder(); - for (Entry entry : properties.entrySet()) - if (entry.getValue() != null) - builder.put(entry.getKey().toString(), entry.getValue().toString()); - return LinkedHashMultimap.create(builder.build()); - } + static class BindPropertiesToAnnotations extends ConfigurationModule { @Provides @Singleton @Named("TIMEOUTS") - protected Map timeouts() { - final ImmutableMap.Builder builder = ImmutableMap. builder(); - for (final Entry entry : properties.entrySet()) { - final String key = String.valueOf(entry.getKey()); - if (key.startsWith(PROPERTY_TIMEOUTS_PREFIX) && entry.getValue() != null) { - try { - final Long val = Long.valueOf(String.valueOf(entry.getValue())); - builder.put(key.replaceFirst(PROPERTY_TIMEOUTS_PREFIX, ""), val); - } catch (final Throwable t) {} + protected Map timeouts(Function, Map> filterStringsBoundByName) { + Map stringBoundWithTimeoutPrefix = filterStringsBoundByName.apply(new Predicate() { + + @Override + public boolean apply(String input) { + return input.startsWith(PROPERTY_TIMEOUTS_PREFIX); } - } - return builder.build(); + + }); + + Map longsByName = Maps.transformValues(stringBoundWithTimeoutPrefix, new Function() { + + @Override + public Long apply(String input) { + return Long.valueOf(String.valueOf(input)); + } + + }); + return Maps2.transformKeys(longsByName, new Function() { + + @Override + public String apply(String input) { + return input.replaceFirst(PROPERTY_TIMEOUTS_PREFIX, ""); + } + + }); + } + @Provides + @Singleton + @Provider + protected String bindProvider(@Named(PROPERTY_PROVIDER) String in){ + return in; + } + + @Provides + @Singleton + @Provider + protected URI bindProviderEndpoint(@Named(PROPERTY_ENDPOINT) String in){ + return URI.create(in); + } + + @Provides + @Singleton + @Iso3166 + protected Set bindIsoCodes(@Named(PROPERTY_ISO3166_CODES) String in){ + return ImmutableSet.copyOf(filter(on(',').split( in), + not(equalTo("")))); + } + + @Provides + @Singleton + @Api + protected String bindApi(@Named(PROPERTY_API) String in){ + return in; + } + + @Provides + @Singleton + @ApiVersion + protected String bindApiVersion(@Named(PROPERTY_API_VERSION) String in){ + return in; + } + + @Provides + @Singleton + @BuildVersion + protected String bindBuildVersion(@Named(PROPERTY_BUILD_VERSION) String in){ + return in; + } + + @Provides + @Singleton + @Identity + protected String bindIdentity(@Named(PROPERTY_IDENTITY) String in){ + return in; + } + + @Provides + @Singleton + @Credential + @Nullable + protected String bindCredential(ValueOfConfigurationKeyOrNull config){ + return config.apply(PROPERTY_CREDENTIAL); + } + + @Override - protected void configure() { - Properties toBind = new Properties(); - toBind.putAll(checkNotNull(properties, "properties")); - toBind.putAll(System.getProperties()); - bindProperties(binder(), toBind); - bind(String.class).annotatedWith(Provider.class).toInstance( - checkNotNull(toBind.getProperty(PROPERTY_PROVIDER), PROPERTY_PROVIDER)); - bind(URI.class).annotatedWith(Provider.class).toInstance( - URI.create(checkNotNull(toBind.getProperty(PROPERTY_ENDPOINT), PROPERTY_ENDPOINT))); - bind(new TypeLiteral>() { - }).annotatedWith(Iso3166.class).toInstance( - ImmutableSet.copyOf(filter(on(',').split( - checkNotNull(toBind.getProperty(PROPERTY_ISO3166_CODES), PROPERTY_ISO3166_CODES)), - not(equalTo(""))))); + protected void bindConfigurations() { + bind(new TypeLiteral, Map>>() { + }).to(FilterStringsBoundToInjectorByName.class); bind(new TypeLiteral>>() { }).annotatedWith(Iso3166.class).toProvider(ProvideIso3166CodesByLocationIdViaProperties.class); - if (toBind.containsKey(PROPERTY_API)) - bind(String.class).annotatedWith(Api.class).toInstance(toBind.getProperty(PROPERTY_API)); - if (toBind.containsKey(PROPERTY_API_VERSION)) - bind(String.class).annotatedWith(ApiVersion.class).toInstance(toBind.getProperty(PROPERTY_API_VERSION)); - if (toBind.containsKey(PROPERTY_BUILD_VERSION)) - bind(String.class).annotatedWith(BuildVersion.class).toInstance(toBind.getProperty(PROPERTY_BUILD_VERSION)); - if (toBind.containsKey(PROPERTY_IDENTITY)) - bind(String.class).annotatedWith(Identity.class).toInstance( - checkNotNull(toBind.getProperty(PROPERTY_IDENTITY), PROPERTY_IDENTITY)); - if (toBind.containsKey(PROPERTY_CREDENTIAL)) - bind(String.class).annotatedWith(Credential.class).toInstance(toBind.getProperty(PROPERTY_CREDENTIAL)); } } @@ -190,6 +228,17 @@ public class RestContextBuilder { } public Injector buildInjector() { + modules.add(Rocoto.expandVariables(new ConfigurationModule(){ + + @Override + protected void bindConfigurations() { + Properties toBind = new Properties(); + toBind.putAll(checkNotNull(properties, "properties")); + toBind.putAll(System.getProperties()); + bindProperties(toBind); + } + + })); addContextModule(modules); addClientModuleIfNotPresent(modules); addLoggingModuleIfNotPresent(modules); @@ -198,7 +247,7 @@ public class RestContextBuilder { addExecutorServiceIfNotPresent(modules); addCredentialStoreIfNotPresent(modules); modules.add(new LifeCycleModule()); - modules.add(new BindPropertiesAndPrincipalContext(properties)); + modules.add(new BindPropertiesToAnnotations()); Injector returnVal = Guice.createInjector(Stage.PRODUCTION, modules); returnVal.getInstance(ExecutionList.class).execute(); return returnVal; @@ -334,8 +383,8 @@ public class RestContextBuilder { } } - @VisibleForTesting - public Properties getProperties() { + @VisibleForTesting + protected Properties getProperties() { return properties; } diff --git a/core/src/main/java/org/jclouds/rest/annotations/Api.java b/core/src/main/java/org/jclouds/rest/annotations/Api.java index 574b7d9aaa..4c28ea55af 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/Api.java +++ b/core/src/main/java/org/jclouds/rest/annotations/Api.java @@ -20,6 +20,7 @@ package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -33,7 +34,7 @@ import javax.inject.Qualifier; * * @author Adrian Cole */ -@Target( { ANNOTATION_TYPE, FIELD, PARAMETER }) +@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER }) @Retention(RUNTIME) @Qualifier public @interface Api { diff --git a/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java b/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java index 210a598133..7a8c80d77a 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java +++ b/core/src/main/java/org/jclouds/rest/annotations/ApiVersion.java @@ -20,6 +20,7 @@ package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -36,7 +37,7 @@ import org.jclouds.Constants; * @author Adrian Cole * @see Constants#PROPERTY_API_VERSION */ -@Target( { ANNOTATION_TYPE, FIELD, PARAMETER }) +@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER }) @Retention(RUNTIME) @Qualifier public @interface ApiVersion { diff --git a/core/src/main/java/org/jclouds/rest/annotations/BuildVersion.java b/core/src/main/java/org/jclouds/rest/annotations/BuildVersion.java index 3586a3c681..d37c3dc5dc 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/BuildVersion.java +++ b/core/src/main/java/org/jclouds/rest/annotations/BuildVersion.java @@ -20,6 +20,7 @@ package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -36,7 +37,7 @@ import org.jclouds.Constants; * @author Adrian Cole * @see Constants#PROPERTY_BUILD_VERSION */ -@Target( { ANNOTATION_TYPE, FIELD, PARAMETER }) +@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER }) @Retention(RUNTIME) @Qualifier public @interface BuildVersion { diff --git a/core/src/main/java/org/jclouds/rest/annotations/Credential.java b/core/src/main/java/org/jclouds/rest/annotations/Credential.java index 3e58645d03..64bac143ba 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/Credential.java +++ b/core/src/main/java/org/jclouds/rest/annotations/Credential.java @@ -20,6 +20,7 @@ package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -33,7 +34,7 @@ import javax.inject.Qualifier; * * @author Adrian Cole */ -@Target( { ANNOTATION_TYPE, FIELD, PARAMETER }) +@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER }) @Retention(RUNTIME) @Qualifier public @interface Credential { diff --git a/core/src/main/java/org/jclouds/rest/annotations/Identity.java b/core/src/main/java/org/jclouds/rest/annotations/Identity.java index 0d23d95c52..ef20f5e554 100644 --- a/core/src/main/java/org/jclouds/rest/annotations/Identity.java +++ b/core/src/main/java/org/jclouds/rest/annotations/Identity.java @@ -20,6 +20,7 @@ package org.jclouds.rest.annotations; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; @@ -33,7 +34,7 @@ import javax.inject.Qualifier; * * @author Adrian Cole */ -@Target( { ANNOTATION_TYPE, FIELD, PARAMETER }) +@Target( { ANNOTATION_TYPE, FIELD, METHOD, PARAMETER }) @Retention(RUNTIME) @Qualifier public @interface Identity { diff --git a/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java b/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java index 29a91aa673..a07e668da9 100644 --- a/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java +++ b/core/src/main/java/org/jclouds/rest/internal/AsyncRestClientProxy.java @@ -29,6 +29,7 @@ import javax.annotation.Resource; import javax.inject.Named; import javax.inject.Qualifier; import javax.inject.Singleton; +import javax.ws.rs.Path; import org.jclouds.Constants; import org.jclouds.concurrent.ExceptionParsingListenableFuture; @@ -132,7 +133,7 @@ public class AsyncRestClientProxy implements InvocationHandler { } else if (isRestCall(method)) { return createListenableFutureForHttpRequestMappedToMethodAndArgs(method, args); } else { - throw new RuntimeException("method is intended solely to set constants: " + method); + throw new RuntimeException(String.format("Method is not annotated as either http or provider method: %s", method)); } } diff --git a/core/src/main/java/org/jclouds/rest/internal/SeedAnnotationCache.java b/core/src/main/java/org/jclouds/rest/internal/SeedAnnotationCache.java index c1f1501de4..486bf6f988 100644 --- a/core/src/main/java/org/jclouds/rest/internal/SeedAnnotationCache.java +++ b/core/src/main/java/org/jclouds/rest/internal/SeedAnnotationCache.java @@ -39,22 +39,19 @@ import java.lang.reflect.Method; import java.util.concurrent.ExecutionException; import javax.annotation.Resource; -import javax.inject.Named; import javax.inject.Singleton; import javax.ws.rs.Path; -import javax.ws.rs.PathParam; import org.jclouds.http.HttpRequest; import org.jclouds.logging.Logger; +import org.jclouds.rest.RestContext; import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.internal.RestAnnotationProcessor.MethodKey; import com.google.common.cache.CacheLoader; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Multimap; import com.google.inject.Inject; import com.google.inject.Injector; -import com.google.inject.Key; import com.google.inject.Provides; /** @@ -70,19 +67,11 @@ public class SeedAnnotationCache extends CacheLoader, Boolean> { @Resource protected Logger logger = Logger.NULL; - protected final Multimap constants; protected final Injector injector; @Inject - public SeedAnnotationCache(Injector injector, @Named("CONSTANTS") Multimap constants) { + public SeedAnnotationCache(Injector injector) { this.injector = injector; - this.constants = constants; - } - - public void bindConstant(Method method) { - String key = method.getAnnotation(PathParam.class).value(); - String value = injector.getInstance(Key.get(String.class, method.getAnnotation(Named.class))); - constants.put(key, value); } @Override @@ -106,14 +95,12 @@ public class SeedAnnotationCache extends CacheLoader, Boolean> { methodToIndexesOfOptions.get(method); } delegationMap.put(new MethodKey(method), method); - } else if (isConstantDeclaration(method)) { - bindConstant(method); } else if (!method.getDeclaringClass().equals(declaring)) { logger.trace("skipping potentially overridden method %s", method); } else if (method.isAnnotationPresent(Provides.class)) { logger.trace("skipping provider method %s", method); } else { - logger.trace("Method is not annotated as either http or constant: %s", method); + logger.trace("Method is not annotated as either http or provider method: %s", method); } } return true; @@ -124,7 +111,4 @@ public class SeedAnnotationCache extends CacheLoader, Boolean> { || ImmutableSet.copyOf(method.getParameterTypes()).contains(HttpRequest.class); } - public static boolean isConstantDeclaration(Method method) { - return method.isAnnotationPresent(PathParam.class) && method.isAnnotationPresent(Named.class); - } } \ No newline at end of file diff --git a/core/src/main/resources/rest.properties b/core/src/main/resources/rest.properties index 892fead643..f7aa2439bc 100644 --- a/core/src/main/resources/rest.properties +++ b/core/src/main/resources/rest.properties @@ -5,8 +5,7 @@ azurequeue.contextbuilder=org.jclouds.azure.storage.AzureStorageContextBuilder azurequeue.sync=org.jclouds.azurequeue.AzureQueueClient azurequeue.async=org.jclouds.azurequeue.AzureQueueAsyncClient azurequeue.api-version=2009-09-19 -azurequeue.propertiesbuilder=org.jclouds.azure.storage.AzureStoragePropertiesBuilder -azurequeue.endpoint=https://{identity}.queue.core.windows.net +azurequeue.endpoint=https://${jclouds.identity}.queue.core.windows.net azureblob.contextbuilder=org.jclouds.azureblob.AzureBlobContextBuilder azureblob.propertiesbuilder=org.jclouds.azureblob.AzureBlobPropertiesBuilder diff --git a/core/src/test/java/org/jclouds/internal/FilterStringsBoundToInjectorByNameTest.java b/core/src/test/java/org/jclouds/internal/FilterStringsBoundToInjectorByNameTest.java new file mode 100644 index 0000000000..480669ea2a --- /dev/null +++ b/core/src/test/java/org/jclouds/internal/FilterStringsBoundToInjectorByNameTest.java @@ -0,0 +1,104 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.internal; + +import static org.testng.Assert.assertEquals; + +import javax.inject.Named; + +import org.testng.annotations.Test; + +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableMap; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Provides; +import com.google.inject.name.Names; + +/** + * + * @author Adrian Cole + */ +@Test(testName = "FilterStringsBoundToInjectorByNameTest") +public class FilterStringsBoundToInjectorByNameTest { + + public void testEmptyWhenNoStringsBound() { + FilterStringsBoundToInjectorByName fn = Guice.createInjector().getInstance(FilterStringsBoundToInjectorByName.class); + assertEquals(fn.apply(Predicates. alwaysTrue()), ImmutableMap. of()); + } + + public void testEmptyWhenNotStringsBound() { + FilterStringsBoundToInjectorByName fn = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + bindConstant().annotatedWith(Names.named("foo")).to(1l); + } + + }).getInstance(FilterStringsBoundToInjectorByName.class); + + assertEquals(fn.apply(Predicates. alwaysTrue()), ImmutableMap. of()); + } + + public void testReturnsGuiceNamedString() { + FilterStringsBoundToInjectorByName fn = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + bindConstant().annotatedWith(Names.named("foo")).to("bar"); + } + + }).getInstance(FilterStringsBoundToInjectorByName.class); + + assertEquals(fn.apply(Predicates. alwaysTrue()), ImmutableMap. of("foo", "bar")); + } + + public void testReturnsJavaNamedString() { + FilterStringsBoundToInjectorByName fn = Guice.createInjector(new AbstractModule() { + @SuppressWarnings("unused") + @Named("foo") + @Provides + String provideFoo() { + return "bar"; + } + + @Override + protected void configure() { + } + + }).getInstance(FilterStringsBoundToInjectorByName.class); + + assertEquals(fn.apply(Predicates. alwaysTrue()), ImmutableMap. of("foo", "bar")); + } + + public void testFilterWorks() { + FilterStringsBoundToInjectorByName fn = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + bindConstant().annotatedWith(Names.named("foo")).to("bar"); + bindConstant().annotatedWith(Names.named("bing")).to("bong"); + } + + }).getInstance(FilterStringsBoundToInjectorByName.class); + + assertEquals(fn.apply(Predicates. equalTo("bing")), ImmutableMap. of("bing", "bong")); + } + +} diff --git a/core/src/test/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaPropertiesTest.java b/core/src/test/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaPropertiesTest.java new file mode 100644 index 0000000000..30cf08e40f --- /dev/null +++ b/core/src/test/java/org/jclouds/location/config/ProvideIso3166CodesByLocationIdViaPropertiesTest.java @@ -0,0 +1,94 @@ +/** + * Licensed to jclouds, Inc. (jclouds) under one or more + * contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. jclouds licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.jclouds.location.config; + +import static org.testng.Assert.assertEquals; + +import java.util.Map; +import java.util.Set; + +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Provides; + +/** + * + * @author Adrian Cole + */ +@Test(testName = "ProvideIso3166CodesByLocationIdViaPropertiesTest") +public class ProvideIso3166CodesByLocationIdViaPropertiesTest { + + public void testEmptyWhenNoLocationsBound() { + ProvideIso3166CodesByLocationIdViaProperties fn = createWithValue(ImmutableMap. of()); + + assertEquals(fn.get(), ImmutableMap.> of()); + } + + public void testEmptyWhenRegionsAndZonesBoundButNoIsoCodes() { + + ProvideIso3166CodesByLocationIdViaProperties fn = createWithValue(ImmutableMap. of( + "jclouds.regions", "us-east", "jclouds.zones", "us-easta")); + + assertEquals(fn.get(), ImmutableMap.> of()); + } + + public void testIsoCodesWhenRegionsAndZonesBoundWithIsoCodes() { + + ProvideIso3166CodesByLocationIdViaProperties fn = createWithValue(ImmutableMap. of( + "jclouds.regions", "us-east", "jclouds.region.us-east.iso3166-codes", "US", "jclouds.zones", "us-easta", + "jclouds.zone.us-easta.iso3166-codes", "US-CA")); + + assertEquals( + fn.get(), + ImmutableMap.> of("us-east", ImmutableSet.of("US"), "us-easta", + ImmutableSet.of("US-CA"))); + } + + // + + private ProvideIso3166CodesByLocationIdViaProperties createWithValue(final ImmutableMap value) { + ProvideIso3166CodesByLocationIdViaProperties fn = Guice.createInjector(new AbstractModule() { + @SuppressWarnings("unused") + @Provides + Function, Map> provide() { + return new Function, Map>() { + + @Override + public Map apply(Predicate input) { + return Maps.filterKeys(value, input); + }; + }; + } + + @Override + protected void configure() { + } + + }).getInstance(ProvideIso3166CodesByLocationIdViaProperties.class); + return fn; + } + +} diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java index c0a044210c..63bfd9e320 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2ContextBuilder.java @@ -18,13 +18,18 @@ */ package org.jclouds.aws.ec2; +import static org.jclouds.aws.ec2.reference.AWSEC2Constants.PROPERTY_EC2_AMI_QUERY; +import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; + import java.util.List; import java.util.Properties; +import java.util.logging.Logger; import org.jclouds.aws.ec2.compute.config.AWSEC2ComputeServiceContextModule; import org.jclouds.aws.ec2.config.AWSEC2RestClientModule; import org.jclouds.ec2.EC2ContextBuilder; +import com.google.common.annotations.VisibleForTesting; import com.google.inject.Module; /** @@ -34,9 +39,34 @@ import com.google.inject.Module; public class AWSEC2ContextBuilder extends EC2ContextBuilder { public AWSEC2ContextBuilder(Properties props) { - super(props); + super(warnAndReplaceIfUsingOldImageKey(props)); } - + + @VisibleForTesting + @Override + public Properties getProperties(){ + return properties; + } + + //TODO: determine how to do conditional manipulation w/rocoto + static Properties warnAndReplaceIfUsingOldImageKey(Properties props) { + if (props.containsKey(PROPERTY_EC2_AMI_OWNERS)) { + StringBuilder query = new StringBuilder(); + String owners = props.remove(PROPERTY_EC2_AMI_OWNERS).toString(); + if ("*".equals(owners)) + query.append("state=available;image-type=machine"); + else if (!"".equals(owners)) + query.append("owner-id=").append(owners).append(";state=available;image-type=machine"); + else if ("".equals(owners)) + query = new StringBuilder(); + props.setProperty(PROPERTY_EC2_AMI_QUERY, query.toString()); + Logger.getAnonymousLogger().warning( + String.format("Property %s is deprecated, please use new syntax: %s=%s", PROPERTY_EC2_AMI_OWNERS, + PROPERTY_EC2_AMI_QUERY, query.toString())); + } + return props; + } + @Override protected void addClientModule(List modules) { modules.add(new AWSEC2RestClientModule()); diff --git a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java index 9afdbf2d71..e4f2f7234d 100644 --- a/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java +++ b/providers/aws-ec2/src/main/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilder.java @@ -27,7 +27,6 @@ import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIM import static org.jclouds.ec2.reference.EC2Constants.PROPERTY_EC2_AMI_OWNERS; import java.util.Properties; -import java.util.logging.Logger; import org.jclouds.aws.domain.Region; @@ -72,28 +71,5 @@ public class AWSEC2PropertiesBuilder extends org.jclouds.ec2.EC2PropertiesBuilde super(properties); } - @Override - public Properties build() { - Properties props = super.build(); - warnAndReplaceIfUsingOldImageKey(props); - return props; - } - - protected void warnAndReplaceIfUsingOldImageKey(Properties props) { - if (props.containsKey(PROPERTY_EC2_AMI_OWNERS)) { - StringBuilder query = new StringBuilder(); - String owners = properties.remove(PROPERTY_EC2_AMI_OWNERS).toString(); - if ("*".equals(owners)) - query.append("state=available;image-type=machine"); - else if (!"".equals(owners)) - query.append("owner-id=").append(owners).append(";state=available;image-type=machine"); - else if ("".equals(owners)) - query = new StringBuilder(); - props.setProperty(PROPERTY_EC2_AMI_QUERY, query.toString()); - Logger.getAnonymousLogger().warning( - String.format("Property %s is deprecated, please use new syntax: %s=%s", PROPERTY_EC2_AMI_OWNERS, - PROPERTY_EC2_AMI_QUERY, query.toString())); - } - } } diff --git a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilderTest.java b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2ContextBuilderTest.java similarity index 87% rename from providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilderTest.java rename to providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2ContextBuilderTest.java index 9d318a5af6..06c18c59d1 100644 --- a/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2PropertiesBuilderTest.java +++ b/providers/aws-ec2/src/test/java/org/jclouds/aws/ec2/AWSEC2ContextBuilderTest.java @@ -29,13 +29,13 @@ import org.testng.annotations.Test; /** * @author Adrian Cole */ -@Test(groups = "unit", testName = "AWSEC2PropertiesBuilderTest") -public class AWSEC2PropertiesBuilderTest { +@Test(groups = "unit", testName = "AWSEC2ContextBuilderTest") +public class AWSEC2ContextBuilderTest { public void testConvertImageSyntax() { Properties input = new Properties(); input.setProperty(PROPERTY_EC2_AMI_OWNERS, "137112412989,063491364108,099720109477,411009282317"); - Properties props = new AWSEC2PropertiesBuilder(input).build(); + Properties props = new AWSEC2ContextBuilder(input).getProperties(); assertEquals(props.getProperty(PROPERTY_EC2_AMI_OWNERS), null); assertEquals(props.getProperty(PROPERTY_EC2_AMI_QUERY), "owner-id=137112412989,063491364108,099720109477,411009282317;state=available;image-type=machine"); @@ -44,7 +44,7 @@ public class AWSEC2PropertiesBuilderTest { public void testConvertImageSyntaxWhenStar() { Properties input = new Properties(); input.setProperty(PROPERTY_EC2_AMI_OWNERS, "*"); - Properties props = new AWSEC2PropertiesBuilder(input).build(); + Properties props = new AWSEC2ContextBuilder(input).getProperties(); assertEquals(props.getProperty(PROPERTY_EC2_AMI_OWNERS), null); assertEquals(props.getProperty(PROPERTY_EC2_AMI_QUERY), "state=available;image-type=machine"); } @@ -52,7 +52,7 @@ public class AWSEC2PropertiesBuilderTest { public void testConvertImageSyntaxWhenBlank() { Properties input = new Properties(); input.setProperty(PROPERTY_EC2_AMI_OWNERS, ""); - Properties props = new AWSEC2PropertiesBuilder(input).build(); + Properties props = new AWSEC2ContextBuilder(input).getProperties(); assertEquals(props.getProperty(PROPERTY_EC2_AMI_OWNERS), null); assertEquals(props.getProperty(PROPERTY_EC2_AMI_QUERY), ""); } diff --git a/providers/azureblob/pom.xml b/providers/azureblob/pom.xml index cb59ddbcab..51ca74b271 100644 --- a/providers/azureblob/pom.xml +++ b/providers/azureblob/pom.xml @@ -35,7 +35,7 @@ org.jclouds.azureblob.blobstore.integration.AzureBlobTestInitializer - https://{identity}.blob.core.windows.net + https://${jclouds.identity}.blob.core.windows.net 2009-09-19 ${test.azure.identity} diff --git a/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java b/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java index d294af72b5..5fae25ea68 100644 --- a/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java +++ b/providers/azureblob/src/main/java/org/jclouds/azureblob/AzureBlobPropertiesBuilder.java @@ -25,20 +25,20 @@ import static org.jclouds.blobstore.reference.BlobStoreConstants.PROPERTY_USER_M import java.util.Properties; -import org.jclouds.azure.storage.AzureStoragePropertiesBuilder; +import org.jclouds.PropertiesBuilder; /** * Builds properties used in AzureBlob Connections * * @author Adrian Cole */ -public class AzureBlobPropertiesBuilder extends AzureStoragePropertiesBuilder { +public class AzureBlobPropertiesBuilder extends PropertiesBuilder { @Override protected Properties defaultProperties() { Properties properties = super.defaultProperties(); properties.setProperty(PROPERTY_USER_METADATA_PREFIX, "x-ms-meta-"); properties.setProperty(PROPERTY_API_VERSION, "2009-09-19"); - properties.setProperty(PROPERTY_ENDPOINT, "https://{identity}.blob.core.windows.net"); + properties.setProperty(PROPERTY_ENDPOINT, "https://${jclouds.identity}.blob.core.windows.net"); properties.setProperty(PROPERTY_ISO3166_CODES, "US-TX,US-IL,IE-D,SG,NL-NH,HK"); return properties; } diff --git a/sandbox-providers/azurequeue/pom.xml b/sandbox-providers/azurequeue/pom.xml index e471a2e57b..48141a8fcf 100644 --- a/sandbox-providers/azurequeue/pom.xml +++ b/sandbox-providers/azurequeue/pom.xml @@ -34,7 +34,7 @@ bundle - https://{identity}.queue.core.windows.net + https://${jclouds.identity}.queue.core.windows.net 2009-09-19 ${test.azure.identity}