diff --git a/core/src/main/java/org/jclouds/providers/ProviderPredicates.java b/core/src/main/java/org/jclouds/providers/ProviderPredicates.java index b3563f60a4..dc8ad7e3a7 100644 --- a/core/src/main/java/org/jclouds/providers/ProviderPredicates.java +++ b/core/src/main/java/org/jclouds/providers/ProviderPredicates.java @@ -109,31 +109,84 @@ public class ProviderPredicates { Preconditions.checkNotNull(iso3166Code, "iso3166Code must not be null"); return new Predicate() { - /** - * {@inheritDoc} - */ - @Override - public boolean apply(ProviderMetadata providerMetadata) { - for (String availCode : providerMetadata.getIso3166Codes()) { - if(iso3166Code.indexOf('-') == -1) { - if (availCode.startsWith(iso3166Code + "-")) { - return true; - } - } else if (availCode.equals(iso3166Code)) { - return true; - } - } + /** + * {@inheritDoc} + */ + @Override + public boolean apply(ProviderMetadata providerMetadata) { + return providerContainsIso3166Code(providerMetadata, iso3166Code); + } - return false; - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "iso3166Code(" + iso3166Code + ")"; - } + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "inIso3166Code(" + iso3166Code + ")"; + } }; } + + /** + * Return all providers that have at least one ISO 3166 code in common with the given provider metadata. + * + * @param refProviderMetadata + * the provider metadata to use to filter providers by + * + * @return the providers that have at least one ISO 3166 code in common + */ + public static Predicate intersectingIso3166Code(final ProviderMetadata refProviderMetadata) { + Preconditions.checkNotNull(refProviderMetadata, "refProviderMetadata must not be null"); + + return new Predicate() { + /** + * {@inheritDoc} + */ + @Override + public boolean apply(ProviderMetadata providerMetadata) { + for (String refIso3166Code : refProviderMetadata.getIso3166Codes()) { + // Return only if the potential provider contains the same ISO 3166 code and the provider and + // reference provider are not the same. + if (providerContainsIso3166Code(providerMetadata, refIso3166Code) && + !refProviderMetadata.equals(providerMetadata)) { + return true; + } + } + return false; + } + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return "intersectingIso3166Code(" + refProviderMetadata + ")"; + } + }; + } + + /** + * Returns whether or not the provided provider contains the ISO 3166 code provider or is within the same + * "global" region, like "US" would contain "US-*". + * + * @param providerMetadata + * the provider metadata to search + * @param iso3166Code + * the ISO 3166 code to search the provider metadata for + * + * @return the result + */ + private static boolean providerContainsIso3166Code(ProviderMetadata providerMetadata, String iso3166Code) { + for (String availCode : providerMetadata.getIso3166Codes()) { + if(iso3166Code.indexOf('-') == -1) { + if (availCode.startsWith(iso3166Code + "-")) { + return true; + } + } else if (availCode.equals(iso3166Code)) { + return true; + } + } + + return false; + } } \ 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 ab63e06c94..e429a65329 100644 --- a/core/src/main/java/org/jclouds/providers/Providers.java +++ b/core/src/main/java/org/jclouds/providers/Providers.java @@ -135,6 +135,19 @@ public class Providers { * @return the providers with the given ISO 3166 code */ public static Iterable withIso3166Code(String iso3166Code) { - return filter(all(), ProviderPredicates.inIso3166Code(iso3166Code)); + return filter(all(), ProviderPredicates.inIso3166Code(iso3166Code)); + } + + /** + * Returns the providers that have at least one common ISO 3166 code in common + * regardless of type. + * + * @param providerMetadata + * the provider metadata to use to filter providers by + * + * @return the providers that share at least one common ISO 3166 code + */ + public static Iterable collocatedWith(ProviderMetadata providerMetadata) { + return filter(all(), ProviderPredicates.intersectingIso3166Code(providerMetadata)); } } diff --git a/core/src/test/java/org/jclouds/providers/JcloudsTestYetAnotherComputeProviderMetadata.java b/core/src/test/java/org/jclouds/providers/JcloudsTestYetAnotherComputeProviderMetadata.java new file mode 100644 index 0000000000..ffa0758638 --- /dev/null +++ b/core/src/test/java/org/jclouds/providers/JcloudsTestYetAnotherComputeProviderMetadata.java @@ -0,0 +1,105 @@ +/** + * + * 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 com.google.common.collect.ImmutableSet; + +import java.net.URI; +import java.util.Set; + +/** + * Implementation of @ link org.jclouds.types.ProviderMetadata} for testing. + * + * @author Jeremy Whitlock + */ +public class JcloudsTestYetAnotherComputeProviderMetadata extends BaseProviderMetadata { + + /** + * {@ see org.jclouds.types.ProviderMetadata#getId()} + */ + @Override + public String getId() { + return "test-yet-another-compute-provider"; + } + + /** + * {@ see org.jclouds.types.ProviderMetadata#getType()} + */ + @Override + public String getType() { + return ProviderMetadata.COMPUTE_TYPE; + } + + /** + * {@ see org.jclouds.types.ProviderMetadata#getName()} + */ + @Override + public String getName() { + return "Test Yet Another Compute Provider"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getCredentialName() { + return "user"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getIdentityName() { + return "password"; + } + + /** + * {@ see org.jclouds.types.ProviderMetadata#getHomepage()} + */ + @Override + public URI getHomepage() { + return URI.create("http://jclouds.org"); + } + + /** + * {@ see org.jclouds.types.ProviderMetadata#getConsole()} + */ + @Override + public URI getConsole() { + return URI.create("http://jclouds.org/console"); + } + + /** + * {@inheritDoc} + */ + @Override + public URI getApiDocumentation() { + return URI.create("http://jclouds.org/documentation"); + } + + /** + * {@inheritDoc} + */ + @Override + public Set getIso3166Codes() { + return ImmutableSet.of("JP-13"); + } + +} \ 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 383ab32ed1..a1cc5fa7f5 100644 --- a/core/src/test/java/org/jclouds/providers/ProvidersTest.java +++ b/core/src/test/java/org/jclouds/providers/ProvidersTest.java @@ -37,6 +37,7 @@ public class ProvidersTest { private final ProviderMetadata testBlobstoreProvider = new JcloudsTestBlobStoreProviderMetadata(); private final ProviderMetadata testComputeProvider = new JcloudsTestComputeProviderMetadata(); + private final ProviderMetadata testYetAnotherComputeProvider = new JcloudsTestYetAnotherComputeProviderMetadata(); @Test public void testWithId() { @@ -66,7 +67,11 @@ public class ProvidersTest { providersMetadata = Providers.ofType(ProviderMetadata.COMPUTE_TYPE); for (ProviderMetadata providerMetadata : providersMetadata) { - assertEquals(testComputeProvider, providerMetadata); + if (providerMetadata.getName().equals(testComputeProvider.getName())) { + assertEquals(testComputeProvider, providerMetadata); + } else { + assertEquals(testYetAnotherComputeProvider, providerMetadata); + } } providersMetadata = Providers.ofType("fake-type"); @@ -79,10 +84,12 @@ public class ProvidersTest { Iterable providersMetadata = Providers.all(); for (ProviderMetadata providerMetadata : providersMetadata) { - if (providerMetadata.getName().equals("Test Blobstore Provider")) { + if (providerMetadata.getName().equals(testBlobstoreProvider.getName())) { assertEquals(testBlobstoreProvider, providerMetadata); - } else { + } else if (providerMetadata.getName().equals(testComputeProvider.getName())){ assertEquals(testComputeProvider, providerMetadata); + } else { + assertEquals(testYetAnotherComputeProvider, providerMetadata); } } } @@ -94,6 +101,8 @@ public class ProvidersTest { put("US-CA", 2); put("US-FL", 1); put("US", 2); + put("JP-13", 1); + put("JP", 1); put("SOME-FAKE-CODE", 0); }}; @@ -111,4 +120,26 @@ public class ProvidersTest { } } + @Test + public void testIntersectingIso3166Code() { + @SuppressWarnings("serial") + Map expectedResults = new HashMap() {{ + put(testBlobstoreProvider, 1); + put(testComputeProvider, 1); + put(testYetAnotherComputeProvider, 0); + }}; + + for (Map.Entry result : expectedResults.entrySet()) { + Iterable providersMetadata = Providers.collocatedWith(result.getKey()); + int providersFound = 0; + + for (ProviderMetadata providerMetadata : providersMetadata) { + if (providerMetadata != null) { + providersFound++; + } + } + + assertEquals(providersFound, result.getValue().intValue()); + } + } } diff --git a/core/src/test/resources/META-INF/services/org.jclouds.providers.ProviderMetadata b/core/src/test/resources/META-INF/services/org.jclouds.providers.ProviderMetadata index 5bcd1ef273..6e9898bedd 100644 --- a/core/src/test/resources/META-INF/services/org.jclouds.providers.ProviderMetadata +++ b/core/src/test/resources/META-INF/services/org.jclouds.providers.ProviderMetadata @@ -1,2 +1,3 @@ org.jclouds.providers.JcloudsTestBlobStoreProviderMetadata org.jclouds.providers.JcloudsTestComputeProviderMetadata +org.jclouds.providers.JcloudsTestYetAnotherComputeProviderMetadata