From 9946ee9fd4904627539bb855070f723186c265b3 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 19 Mar 2012 01:00:21 -0700 Subject: [PATCH] changes to facilitate services that do not have regions --- .../jclouds/openstack/domain/Resource.java | 11 ++- .../config/KeystoneAuthenticationModule.java | 78 ++++++++++++--- ...RIFromAccessForTypeAndVersionSupplier.java | 95 +++++++++++++++++++ ...RIFromAccessForTypeAndVersionSupplier.java | 55 +---------- ...RIFromAccessForTypeAndVersionSupplier.java | 50 ++++++++++ .../keystone/v2_0/parse/ParseAccessTest.java | 4 +- ...omAccessForTypeAndVersionSupplierTest.java | 4 +- ...omAccessForTypeAndVersionSupplierTest.java | 71 ++++++++++++++ .../test/resources/keystoneAuthResponse.json | 4 +- .../suppliers/ZoneIdToURISupplier.java | 15 ++- .../ZoneToRegionToProviderOrJustProvider.java | 3 +- .../derived/ZoneIdsFromZoneIdToURIKeySet.java | 50 ++++++++++ 12 files changed, 363 insertions(+), 77 deletions(-) create mode 100644 common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionSupplier.java create mode 100644 common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplier.java create mode 100644 common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplierTest.java create mode 100644 core/src/main/java/org/jclouds/location/suppliers/derived/ZoneIdsFromZoneIdToURIKeySet.java diff --git a/common/openstack/src/main/java/org/jclouds/openstack/domain/Resource.java b/common/openstack/src/main/java/org/jclouds/openstack/domain/Resource.java index 80168be3a0..c0d511a60c 100644 --- a/common/openstack/src/main/java/org/jclouds/openstack/domain/Resource.java +++ b/common/openstack/src/main/java/org/jclouds/openstack/domain/Resource.java @@ -25,6 +25,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.Set; +import org.jclouds.javax.annotation.Nullable; + import com.google.common.base.Objects; import com.google.common.collect.ImmutableSet; @@ -62,8 +64,8 @@ public class Resource implements Comparable { /** * @see Resource#getName() */ - public Builder name(String name) { - this.name = checkNotNull(name, "name"); + public Builder name(@Nullable String name) { + this.name = name; return this; } @@ -95,9 +97,9 @@ public class Resource implements Comparable { protected final String name; protected final Set links; - public Resource(String id, String name, Set links) { + public Resource(String id,@Nullable String name, Set links) { this.id = checkNotNull(id, "id"); - this.name = checkNotNull(name, "name"); + this.name = name; this.links = ImmutableSet.copyOf(checkNotNull(links, "links")); } @@ -114,6 +116,7 @@ public class Resource implements Comparable { /** * @return the name of the resource */ + @Nullable public String getName() { return name; } diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java index 94e2aae4d5..82ee0bd94c 100644 --- a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/config/KeystoneAuthenticationModule.java @@ -36,7 +36,10 @@ import org.jclouds.http.annotation.ClientError; import org.jclouds.location.Provider; import org.jclouds.location.suppliers.RegionIdToURISupplier; import org.jclouds.location.suppliers.RegionIdsSupplier; +import org.jclouds.location.suppliers.ZoneIdToURISupplier; +import org.jclouds.location.suppliers.ZoneIdsSupplier; import org.jclouds.location.suppliers.derived.RegionIdsFromRegionIdToURIKeySet; +import org.jclouds.location.suppliers.derived.ZoneIdsFromZoneIdToURIKeySet; import org.jclouds.openstack.Authentication; import org.jclouds.openstack.keystone.v2_0.ServiceAsyncClient; import org.jclouds.openstack.keystone.v2_0.ServiceClient; @@ -45,6 +48,7 @@ import org.jclouds.openstack.keystone.v2_0.functions.AuthenticateApiAccessKeyCre import org.jclouds.openstack.keystone.v2_0.functions.AuthenticatePasswordCredentials; import org.jclouds.openstack.keystone.v2_0.handlers.RetryOnRenew; import org.jclouds.openstack.keystone.v2_0.suppliers.RegionIdToURIFromAccessForTypeAndVersionSupplier; +import org.jclouds.openstack.keystone.v2_0.suppliers.ZoneIdToURIFromAccessForTypeAndVersionSupplier; import org.jclouds.rest.annotations.ApiVersion; import com.google.common.base.Function; @@ -54,6 +58,7 @@ import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import com.google.inject.AbstractModule; import com.google.inject.Inject; +import com.google.inject.Module; import com.google.inject.Provides; import com.google.inject.assistedinject.FactoryModuleBuilder; @@ -63,6 +68,65 @@ import com.google.inject.assistedinject.FactoryModuleBuilder; */ @RequiresHttp public class KeystoneAuthenticationModule extends AbstractModule { + private final Module locationModule; + + public KeystoneAuthenticationModule() { + this(new RegionModule()); + } + + protected KeystoneAuthenticationModule(Module locationModule) { + this.locationModule = locationModule; + } + + public static Module forRegions() { + return new KeystoneAuthenticationModule(new RegionModule()); + } + + public static class RegionModule extends AbstractModule { + @Override + protected void configure() { + install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class, + RegionIdToURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToURISupplier.Factory.class)); + // dynamically build the region list as opposed to from properties + bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class); + } + + // supply the region to id map from keystone, based on the servicetype and api version in + // config + @Provides + @Singleton + protected RegionIdToURISupplier provideRegionIdToURISupplierForApiVersion( + @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion, + RegionIdToURISupplier.Factory factory) { + return factory.createForApiTypeAndVersion(serviceType, apiVersion); + } + + } + + public static class ZoneModule extends AbstractModule { + @Override + protected void configure() { + install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class, + ZoneIdToURIFromAccessForTypeAndVersionSupplier.class).build(ZoneIdToURISupplier.Factory.class)); + // dynamically build the zone list as opposed to from properties + bind(ZoneIdsSupplier.class).to(ZoneIdsFromZoneIdToURIKeySet.class); + } + + // supply the zone to id map from keystone, based on the servicetype and api version in + // config + @Provides + @Singleton + protected ZoneIdToURISupplier provideZoneIdToURISupplierForApiVersion( + @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion, + ZoneIdToURISupplier.Factory factory) { + return factory.createForApiTypeAndVersion(serviceType, apiVersion); + } + + } + + public static Module forZones() { + return new KeystoneAuthenticationModule(new ZoneModule()); + } @Override protected void configure() { @@ -71,19 +135,7 @@ public class KeystoneAuthenticationModule extends AbstractModule { // ServiceClient is used directly for filters and retry handlers, so let's bind it // explicitly bindClientAndAsyncClient(binder(), ServiceClient.class, ServiceAsyncClient.class); - install(new FactoryModuleBuilder().implement(RegionIdToURISupplier.class, - RegionIdToURIFromAccessForTypeAndVersionSupplier.class).build(RegionIdToURISupplier.Factory.class)); - // dynamically build the region list as opposed to from properties - bind(RegionIdsSupplier.class).to(RegionIdsFromRegionIdToURIKeySet.class); - } - - // supply the region to id map from keystone, based on the servicetype and api version in config - @Provides - @Singleton - protected RegionIdToURISupplier provideRegionIdToURISupplierForApiVersion( - @Named(KeystoneProperties.SERVICE_TYPE) String serviceType, @ApiVersion String apiVersion, - RegionIdToURISupplier.Factory factory) { - return factory.createForApiTypeAndVersion(serviceType, apiVersion); + install(locationModule); } /** diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionSupplier.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionSupplier.java new file mode 100644 index 0000000000..0b73cb8c46 --- /dev/null +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/LocationIdToURIFromAccessForTypeAndVersionSupplier.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.openstack.keystone.v2_0.suppliers; + +import java.net.URI; +import java.util.Map; +import java.util.NoSuchElementException; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.openstack.keystone.v2_0.domain.Access; +import org.jclouds.openstack.keystone.v2_0.domain.Endpoint; +import org.jclouds.openstack.keystone.v2_0.domain.Service; +import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierURI; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Supplier; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.inject.assistedinject.Assisted; + +@Singleton +public class LocationIdToURIFromAccessForTypeAndVersionSupplier implements Supplier>> { + protected final Supplier access; + protected final EndpointToSupplierURI endpointToSupplierURI; + protected final Function endpointToLocationId; + protected final String apiType; + protected final String apiVersion; + + @Inject + public LocationIdToURIFromAccessForTypeAndVersionSupplier(Supplier access, + EndpointToSupplierURI endpointToSupplierURI, Function endpointToLocationId, + @Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) { + this.access = access; + this.endpointToSupplierURI = endpointToSupplierURI; + this.endpointToLocationId = endpointToLocationId; + this.apiType = apiType; + this.apiVersion = apiVersion; + } + + @Override + public Map> get() { + Access accessResponse = access.get(); + Service service = null; + try { + service = Iterables.find(accessResponse.getServiceCatalog(), new Predicate() { + + @Override + public boolean apply(Service input) { + return input.getType().equals(apiType); + } + + }); + } catch (NoSuchElementException e) { + throw new NoSuchElementException(String.format("apiType %s not found in catalog %s", apiType, + accessResponse.getServiceCatalog())); + } + Map locationIdToEndpoint = Maps.uniqueIndex(Iterables.filter(service.getEndpoints(), + new Predicate() { + + @Override + public boolean apply(Endpoint input) { + if (input.getVersionId() == null) { + return true; + } + return input.getVersionId().equals(apiVersion); + } + + }), endpointToLocationId); + return Maps.transformValues(locationIdToEndpoint, endpointToSupplierURI); + } + + @Override + public String toString() { + return "locationIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")"; + } +} \ No newline at end of file diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplier.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplier.java index 08c041a2e4..ce4e17a8e8 100644 --- a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplier.java +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplier.java @@ -18,75 +18,26 @@ */ package org.jclouds.openstack.keystone.v2_0.suppliers; -import java.net.URI; -import java.util.Map; -import java.util.NoSuchElementException; - import javax.inject.Inject; import javax.inject.Singleton; import org.jclouds.location.suppliers.RegionIdToURISupplier; import org.jclouds.openstack.keystone.v2_0.domain.Access; -import org.jclouds.openstack.keystone.v2_0.domain.Endpoint; -import org.jclouds.openstack.keystone.v2_0.domain.Service; import org.jclouds.openstack.keystone.v2_0.functions.EndpointToRegion; import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierURI; -import com.google.common.base.Predicate; import com.google.common.base.Supplier; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import com.google.inject.assistedinject.Assisted; @Singleton -public class RegionIdToURIFromAccessForTypeAndVersionSupplier implements RegionIdToURISupplier { - private final Supplier access; - private final EndpointToSupplierURI endpointToSupplierURI; - private final EndpointToRegion endpointToRegion; - private final String apiType; - private final String apiVersion; +public class RegionIdToURIFromAccessForTypeAndVersionSupplier extends + LocationIdToURIFromAccessForTypeAndVersionSupplier implements RegionIdToURISupplier { @Inject public RegionIdToURIFromAccessForTypeAndVersionSupplier(Supplier access, EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToRegion, @Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) { - this.access = access; - this.endpointToSupplierURI = endpointToSupplierURI; - this.endpointToRegion = endpointToRegion; - this.apiType = apiType; - this.apiVersion = apiVersion; - } - - @Override - public Map> get() { - Access accessResponse = access.get(); - Service service = null; - try { - service = Iterables.find(accessResponse.getServiceCatalog(), new Predicate() { - - @Override - public boolean apply(Service input) { - return input.getType().equals(apiType); - } - - }); - } catch (NoSuchElementException e) { - throw new NoSuchElementException(String.format("apiType %s not found in catalog %s", apiType, - accessResponse.getServiceCatalog())); - } - Map regionIdToEndpoint = Maps.uniqueIndex(Iterables.filter(service.getEndpoints(), - new Predicate() { - - @Override - public boolean apply(Endpoint input) { - if (input.getVersionId() == null) { - return true; - } - return input.getVersionId().equals(apiVersion); - } - - }), endpointToRegion); - return Maps.transformValues(regionIdToEndpoint, endpointToSupplierURI); + super(access, endpointToSupplierURI, endpointToRegion, apiType, apiVersion); } @Override diff --git a/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplier.java b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplier.java new file mode 100644 index 0000000000..36ceb3c82d --- /dev/null +++ b/common/openstack/src/main/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplier.java @@ -0,0 +1,50 @@ +/** + * 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.openstack.keystone.v2_0.suppliers; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.location.suppliers.ZoneIdToURISupplier; +import org.jclouds.openstack.keystone.v2_0.domain.Access; +import org.jclouds.openstack.keystone.v2_0.functions.EndpointToRegion; +import org.jclouds.openstack.keystone.v2_0.functions.EndpointToSupplierURI; + +import com.google.common.base.Supplier; +import com.google.inject.assistedinject.Assisted; + +@Singleton +public class ZoneIdToURIFromAccessForTypeAndVersionSupplier extends LocationIdToURIFromAccessForTypeAndVersionSupplier + implements ZoneIdToURISupplier { + + @Inject + public ZoneIdToURIFromAccessForTypeAndVersionSupplier( + Supplier access, + // NOTE that in some services, the region is in fact the zone. temporarily, we need + // to use the region field, in this case. + EndpointToSupplierURI endpointToSupplierURI, EndpointToRegion endpointToZone, + @Assisted("apiType") String apiType, @Assisted("apiVersion") String apiVersion) { + super(access, endpointToSupplierURI, endpointToZone, apiType, apiVersion); + } + + @Override + public String toString() { + return "zoneIdToURIFromAccessForTypeAndVersion(" + apiType + ", " + apiVersion + ")"; + } +} \ No newline at end of file diff --git a/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/parse/ParseAccessTest.java b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/parse/ParseAccessTest.java index 0d8c9d2bc9..bf7492dcf6 100644 --- a/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/parse/ParseAccessTest.java +++ b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/parse/ParseAccessTest.java @@ -80,10 +80,10 @@ public class ParseAccessTest extends BaseItemParserTest { Service.builder().name("Cloud Servers").type("compute").endpoints( Endpoint.builder().tenantId("1").publicURL(URI.create("https://compute.north.host/v1/1234")) - .internalURL(URI.create("https://compute.north.host/v1/1234")).region("North") + .internalURL(URI.create("https://compute.north.host/v1/1234")).region("az-1.region-a.geo-1") .versionId("1.0").build(), Endpoint.builder().tenantId("2").publicURL(URI.create("https://compute.north.host/v1.1/3456")) - .internalURL(URI.create("https://compute.north.host/v1.1/3456")).region("North") + .internalURL(URI.create("https://compute.north.host/v1.1/3456")).region("az-1.region-a.geo-1") .versionId("1.1").build()).build()).build(); } diff --git a/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplierTest.java b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplierTest.java index 40085778ed..6965e710fb 100644 --- a/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplierTest.java +++ b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/RegionIdToURIFromAccessForTypeAndVersionSupplierTest.java @@ -61,9 +61,9 @@ public class RegionIdToURIFromAccessForTypeAndVersionSupplierTest { public void testRegionMatches() { assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers - . supplierFunction()), ImmutableMap.of("North", URI.create("https://compute.north.host/v1/1234"))); + . supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI.create("https://compute.north.host/v1/1234"))); assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.1").get(), Suppliers - . supplierFunction()), ImmutableMap.of("North", URI.create("https://compute.north.host/v1.1/3456"))); + . supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI.create("https://compute.north.host/v1.1/3456"))); } } diff --git a/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplierTest.java b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplierTest.java new file mode 100644 index 0000000000..037b71104a --- /dev/null +++ b/common/openstack/src/test/java/org/jclouds/openstack/keystone/v2_0/suppliers/ZoneIdToURIFromAccessForTypeAndVersionSupplierTest.java @@ -0,0 +1,71 @@ +/** + * 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.openstack.keystone.v2_0.suppliers; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; + +import javax.inject.Singleton; + +import org.jclouds.location.suppliers.ZoneIdToURISupplier; +import org.jclouds.openstack.keystone.v2_0.domain.Access; +import org.jclouds.openstack.keystone.v2_0.parse.ParseAccessTest; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; +import com.google.inject.AbstractModule; +import com.google.inject.Guice; +import com.google.inject.Provides; +import com.google.inject.assistedinject.FactoryModuleBuilder; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ZoneIdToURIFromAccessForTypeAndVersionSupplierTest") +public class ZoneIdToURIFromAccessForTypeAndVersionSupplierTest { + private final ZoneIdToURISupplier.Factory factory = Guice.createInjector(new AbstractModule() { + + @Override + protected void configure() { + install(new FactoryModuleBuilder().implement(ZoneIdToURISupplier.class, + ZoneIdToURIFromAccessForTypeAndVersionSupplier.class).build(ZoneIdToURISupplier.Factory.class)); + } + + @SuppressWarnings("unused") + @Provides + @Singleton + public Supplier provide() { + return Suppliers.ofInstance(new ParseAccessTest().expected()); + } + }).getInstance(ZoneIdToURISupplier.Factory.class); + + public void testZoneMatches() { + assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.0").get(), Suppliers + . supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI + .create("https://compute.north.host/v1/1234"))); + assertEquals(Maps.transformValues(factory.createForApiTypeAndVersion("compute", "1.1").get(), Suppliers + . supplierFunction()), ImmutableMap.of("az-1.region-a.geo-1", URI + .create("https://compute.north.host/v1.1/3456"))); + } + +} diff --git a/common/openstack/src/test/resources/keystoneAuthResponse.json b/common/openstack/src/test/resources/keystoneAuthResponse.json index d0af4ae91a..4d872152f8 100644 --- a/common/openstack/src/test/resources/keystoneAuthResponse.json +++ b/common/openstack/src/test/resources/keystoneAuthResponse.json @@ -82,7 +82,7 @@ "tenantId":"1", "publicURL":"https://compute.north.host/v1/1234", "internalURL":"https://compute.north.host/v1/1234", - "region":"North", + "region":"az-1.region-a.geo-1", "versionId":"1.0", "versionInfo":"https://compute.north.host/v1.0/", "versionList":"https://compute.north.host/" @@ -91,7 +91,7 @@ "tenantId":"2", "publicURL":"https://compute.north.host/v1.1/3456", "internalURL":"https://compute.north.host/v1.1/3456", - "region":"North", + "region":"az-1.region-a.geo-1", "versionId":"1.1", "versionInfo":"https://compute.north.host/v1.1/", "versionList":"https://compute.north.host/" diff --git a/core/src/main/java/org/jclouds/location/suppliers/ZoneIdToURISupplier.java b/core/src/main/java/org/jclouds/location/suppliers/ZoneIdToURISupplier.java index 4b8e31235e..e95baf75d4 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/ZoneIdToURISupplier.java +++ b/core/src/main/java/org/jclouds/location/suppliers/ZoneIdToURISupplier.java @@ -25,6 +25,7 @@ import org.jclouds.location.suppliers.fromconfig.ZoneIdToURIFromConfigurationOrD import com.google.common.base.Supplier; import com.google.inject.ImplementedBy; +import com.google.inject.assistedinject.Assisted; /** * @@ -33,5 +34,17 @@ import com.google.inject.ImplementedBy; */ @ImplementedBy(ZoneIdToURIFromConfigurationOrDefaultToProvider.class) public interface ZoneIdToURISupplier extends Supplier>> { - + static interface Factory { + /** + * + * @param apiType + * type of the api, according to the provider. ex. {@code compute} {@code + * object-store} + * @param apiVersion + * version of the api + * @return regions mapped to default uri + */ + ZoneIdToURISupplier createForApiTypeAndVersion(@Assisted("apiType") String apiType, + @Assisted("apiVersion") String apiVersion); + } } \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/all/ZoneToRegionToProviderOrJustProvider.java b/core/src/main/java/org/jclouds/location/suppliers/all/ZoneToRegionToProviderOrJustProvider.java index 83d3d27e77..e3df0f1757 100644 --- a/core/src/main/java/org/jclouds/location/suppliers/all/ZoneToRegionToProviderOrJustProvider.java +++ b/core/src/main/java/org/jclouds/location/suppliers/all/ZoneToRegionToProviderOrJustProvider.java @@ -82,7 +82,8 @@ public class ZoneToRegionToProviderOrJustProvider implements LocationsSupplier { Map>> isoCodesById = isoCodesByIdSupplier.get(); Builder locations = ImmutableSet.builder(); - locations.addAll(regionsOrJustProvider); + if (!Iterables.all(regionsOrJustProvider, LocationPredicates.isProvider())) + locations.addAll(regionsOrJustProvider); for (String zoneId : zoneIdToParent.keySet()) { Location parent = zoneIdToParent.get(zoneId); LocationBuilder builder = new LocationBuilder().scope(LocationScope.ZONE).id(zoneId).description(zoneId) diff --git a/core/src/main/java/org/jclouds/location/suppliers/derived/ZoneIdsFromZoneIdToURIKeySet.java b/core/src/main/java/org/jclouds/location/suppliers/derived/ZoneIdsFromZoneIdToURIKeySet.java new file mode 100644 index 0000000000..b8a213514c --- /dev/null +++ b/core/src/main/java/org/jclouds/location/suppliers/derived/ZoneIdsFromZoneIdToURIKeySet.java @@ -0,0 +1,50 @@ +/** + * 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.suppliers.derived; + +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import javax.inject.Singleton; + +import org.jclouds.location.Zone; +import org.jclouds.location.suppliers.ZoneIdsSupplier; + +import com.google.common.base.Supplier; +import com.google.inject.Inject; + +/** + * as opposed to via properties, lets look up zones via api, as they are more likely to change + */ +@Singleton +public class ZoneIdsFromZoneIdToURIKeySet implements ZoneIdsSupplier { + + private final Supplier>> zoneIdToURISupplier; + + @Inject + protected ZoneIdsFromZoneIdToURIKeySet(@Zone Supplier>> zoneIdToURISupplier) { + this.zoneIdToURISupplier = zoneIdToURISupplier; + } + + @Override + public Set get() { + return zoneIdToURISupplier.get().keySet(); + } +} \ No newline at end of file