From ef9a69e7c39440db6c5502b2f73d2bf5bac18cad Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Mon, 2 Jul 2012 15:22:10 -0700 Subject: [PATCH] added strict suppliers of scoped locations --- .../suppliers/all/RegionToProvider.java | 77 +++++++++++++++++ .../suppliers/all/ZoneToProvider.java | 84 +++++++++++++++++++ .../suppliers/implicit/FirstRegion.java | 65 ++++++++++++++ .../suppliers/implicit/FirstZone.java | 65 ++++++++++++++ .../suppliers/all/RegionToProviderTest.java | 72 ++++++++++++++++ .../suppliers/all/ZoneToProviderTest.java | 72 ++++++++++++++++ .../suppliers/implicit/FirstRegionTest.java | 70 ++++++++++++++++ .../suppliers/implicit/FirstZoneTest.java | 70 ++++++++++++++++ 8 files changed, 575 insertions(+) create mode 100644 core/src/main/java/org/jclouds/location/suppliers/all/RegionToProvider.java create mode 100644 core/src/main/java/org/jclouds/location/suppliers/all/ZoneToProvider.java create mode 100644 core/src/main/java/org/jclouds/location/suppliers/implicit/FirstRegion.java create mode 100644 core/src/main/java/org/jclouds/location/suppliers/implicit/FirstZone.java create mode 100644 core/src/test/java/org/jclouds/location/suppliers/all/RegionToProviderTest.java create mode 100644 core/src/test/java/org/jclouds/location/suppliers/all/ZoneToProviderTest.java create mode 100644 core/src/test/java/org/jclouds/location/suppliers/implicit/FirstRegionTest.java create mode 100644 core/src/test/java/org/jclouds/location/suppliers/implicit/FirstZoneTest.java diff --git a/core/src/main/java/org/jclouds/location/suppliers/all/RegionToProvider.java b/core/src/main/java/org/jclouds/location/suppliers/all/RegionToProvider.java new file mode 100644 index 0000000000..1a90178b7e --- /dev/null +++ b/core/src/main/java/org/jclouds/location/suppliers/all/RegionToProvider.java @@ -0,0 +1,77 @@ +/** + * 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.all; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.Map; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.location.Iso3166; +import org.jclouds.location.Region; +import org.jclouds.location.suppliers.LocationsSupplier; + +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class RegionToProvider implements LocationsSupplier { + private final JustProvider justProvider; + private final Supplier> regionsSupplier; + private final Supplier>>> isoCodesByIdSupplier; + + @Inject + public RegionToProvider(JustProvider justProvider, @Region Supplier> regionsSupplier, + @Iso3166 Supplier>>> isoCodesByIdSupplier) { + this.justProvider = checkNotNull(justProvider, "justProvider"); + this.regionsSupplier = checkNotNull(regionsSupplier, "regionsSupplier"); + this.isoCodesByIdSupplier = checkNotNull(isoCodesByIdSupplier, "isoCodesByIdSupplier"); + } + + @Override + public Set get() { + Builder locations = ImmutableSet.builder(); + Location provider = Iterables.getOnlyElement(justProvider.get()); + Set regions = regionsSupplier.get(); + checkState(regions.size() > 0, "no regions found for provider %s, using supplier %s", provider, regionsSupplier); + Map>> isoCodesById = isoCodesByIdSupplier.get(); + for (String region : regions) { + LocationBuilder builder = new LocationBuilder().scope(LocationScope.REGION).id(region).description(region) + .parent(provider); + if (isoCodesById.containsKey(region)) + builder.iso3166Codes(isoCodesById.get(region).get()); + locations.add(builder.build()); + } + return locations.build(); + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/all/ZoneToProvider.java b/core/src/main/java/org/jclouds/location/suppliers/all/ZoneToProvider.java new file mode 100644 index 0000000000..627d5727aa --- /dev/null +++ b/core/src/main/java/org/jclouds/location/suppliers/all/ZoneToProvider.java @@ -0,0 +1,84 @@ +/** + * 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.all; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.Map; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.location.Iso3166; +import org.jclouds.location.Zone; +import org.jclouds.location.suppliers.LocationsSupplier; +import org.jclouds.logging.Logger; + +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSet.Builder; +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class ZoneToProvider implements LocationsSupplier { + + @Resource + protected Logger logger = Logger.NULL; + + private final JustProvider justProvider; + private final Supplier> zoneIdsSupplier; + private final Supplier>>> isoCodesByIdSupplier; + + @Inject + ZoneToProvider(JustProvider justProvider, @Zone Supplier> zoneIdsSupplier, + @Iso3166 Supplier>>> isoCodesByIdSupplier) { + this.justProvider = checkNotNull(justProvider, "justProvider"); + this.zoneIdsSupplier = checkNotNull(zoneIdsSupplier, "zoneIdsSupplier"); + this.isoCodesByIdSupplier = checkNotNull(isoCodesByIdSupplier, "isoCodesByIdSupplier"); + } + + @Override + public Set get() { + Location provider = Iterables.getOnlyElement(justProvider.get()); + Set zoneIds = zoneIdsSupplier.get(); + checkState(zoneIds.size() > 0, "no zones found for provider %s, using supplier %s", provider, zoneIdsSupplier); + Map>> isoCodesById = isoCodesByIdSupplier.get(); + + Builder locations = ImmutableSet.builder(); + for (String zoneId : zoneIds) { + LocationBuilder builder = new LocationBuilder().scope(LocationScope.ZONE).id(zoneId).description(zoneId) + .parent(provider); + if (isoCodesById.containsKey(zoneId)) + builder.iso3166Codes(isoCodesById.get(zoneId).get()); + locations.add(builder.build()); + } + return locations.build(); + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/implicit/FirstRegion.java b/core/src/main/java/org/jclouds/location/suppliers/implicit/FirstRegion.java new file mode 100644 index 0000000000..e0e8febe39 --- /dev/null +++ b/core/src/main/java/org/jclouds/location/suppliers/implicit/FirstRegion.java @@ -0,0 +1,65 @@ +/** + * 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.implicit; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.find; +import static com.google.common.collect.Iterables.transform; +import static org.jclouds.location.predicates.LocationPredicates.isRegion; + +import java.util.NoSuchElementException; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.collect.Memoized; +import org.jclouds.domain.Location; +import org.jclouds.location.functions.ToIdAndScope; +import org.jclouds.location.suppliers.ImplicitLocationSupplier; + +import com.google.common.base.Supplier; + +/** + * + * @author Adrian Cole + * + */ +@Singleton +public class FirstRegion implements ImplicitLocationSupplier { + + private final Supplier> locationsSupplier; + + @Inject + FirstRegion(@Memoized Supplier> locationsSupplier) { + this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplierSupplier"); + } + + @Override + public Location get() { + Set locations = locationsSupplier.get(); + try { + return find(locations, isRegion()); + } catch (NoSuchElementException e) { + throw new NoSuchElementException("none to of the locations are scope REGION: " + + transform(locations, ToIdAndScope.INSTANCE)); + } + } + +} \ No newline at end of file diff --git a/core/src/main/java/org/jclouds/location/suppliers/implicit/FirstZone.java b/core/src/main/java/org/jclouds/location/suppliers/implicit/FirstZone.java new file mode 100644 index 0000000000..94b48ee180 --- /dev/null +++ b/core/src/main/java/org/jclouds/location/suppliers/implicit/FirstZone.java @@ -0,0 +1,65 @@ +/** + * 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.implicit; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Iterables.find; +import static com.google.common.collect.Iterables.transform; +import static org.jclouds.location.predicates.LocationPredicates.isZone; + +import java.util.NoSuchElementException; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.collect.Memoized; +import org.jclouds.domain.Location; +import org.jclouds.location.functions.ToIdAndScope; +import org.jclouds.location.suppliers.ImplicitLocationSupplier; + +import com.google.common.base.Supplier; + +/** + * + * @author Adrian Cole + * + */ +@Singleton +public class FirstZone implements ImplicitLocationSupplier { + + private final Supplier> locationsSupplier; + + @Inject + FirstZone(@Memoized Supplier> locationsSupplier) { + this.locationsSupplier = checkNotNull(locationsSupplier, "locationsSupplierSupplier"); + } + + @Override + public Location get() { + Set locations = locationsSupplier.get(); + try { + return find(locations, isZone()); + } catch (NoSuchElementException e) { + throw new NoSuchElementException("none to of the locations are scope ZONE: " + + transform(locations, ToIdAndScope.INSTANCE)); + } + } + +} \ No newline at end of file diff --git a/core/src/test/java/org/jclouds/location/suppliers/all/RegionToProviderTest.java b/core/src/test/java/org/jclouds/location/suppliers/all/RegionToProviderTest.java new file mode 100644 index 0000000000..af08109979 --- /dev/null +++ b/core/src/test/java/org/jclouds/location/suppliers/all/RegionToProviderTest.java @@ -0,0 +1,72 @@ +/** + * 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.all; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +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.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "RegionToProviderTest") +public class RegionToProviderTest { + Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("servo").description("http://servo") + .iso3166Codes(ImmutableSet.of("US")).build(); + JustProvider justProvider = new JustProvider("servo", Suppliers.ofInstance(URI.create("http://servo")), ImmutableSet.of("US")); + + @Test + public void test() { + Supplier> regionIdsSupplier = Suppliers.>ofInstance(ImmutableSet.of("region1", "region2")); + Supplier>>> locationToIsoCodes = Suppliers.>>>ofInstance( + ImmutableMap.of( + "servo", Suppliers.>ofInstance(ImmutableSet.of("US")), + "region1", Suppliers.>ofInstance(ImmutableSet.of("US-CA")), + "region2", Suppliers.>ofInstance(ImmutableSet.of("US-VA")) + )); + RegionToProvider fn = new RegionToProvider(justProvider, regionIdsSupplier, locationToIsoCodes); + + assertEquals(fn.get(), ImmutableSet.of( + new LocationBuilder().scope(LocationScope.REGION).id("region1").description("region1").iso3166Codes(ImmutableSet.of("US-CA")).parent(provider).build(), + new LocationBuilder().scope(LocationScope.REGION).id("region2").description("region2").iso3166Codes(ImmutableSet.of("US-VA")).parent(provider).build() + )); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testWhenNoRegions() { + Supplier> regionIdsSupplier = Suppliers.>ofInstance(ImmutableSet.of()); + Supplier>>> locationToIsoCodes = Suppliers.>>>ofInstance( + ImmutableMap.>>of()); + RegionToProvider fn = new RegionToProvider(justProvider, regionIdsSupplier, locationToIsoCodes); + fn.get(); + } +} diff --git a/core/src/test/java/org/jclouds/location/suppliers/all/ZoneToProviderTest.java b/core/src/test/java/org/jclouds/location/suppliers/all/ZoneToProviderTest.java new file mode 100644 index 0000000000..fa80aa3f21 --- /dev/null +++ b/core/src/test/java/org/jclouds/location/suppliers/all/ZoneToProviderTest.java @@ -0,0 +1,72 @@ +/** + * 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.all; + +import static org.testng.Assert.assertEquals; + +import java.net.URI; +import java.util.Map; +import java.util.Set; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +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.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ZoneToProviderTest") +public class ZoneToProviderTest { + Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("servo").description("http://servo") + .iso3166Codes(ImmutableSet.of("US")).build(); + JustProvider justProvider = new JustProvider("servo", Suppliers.ofInstance(URI.create("http://servo")), ImmutableSet.of("US")); + + @Test + public void test() { + Supplier> zoneIdsSupplier = Suppliers.>ofInstance(ImmutableSet.of("zone1", "zone2")); + Supplier>>> locationToIsoCodes = Suppliers.>>>ofInstance( + ImmutableMap.of( + "servo", Suppliers.>ofInstance(ImmutableSet.of("US")), + "zone1", Suppliers.>ofInstance(ImmutableSet.of("US-CA")), + "zone2", Suppliers.>ofInstance(ImmutableSet.of("US-VA")) + )); + ZoneToProvider fn = new ZoneToProvider(justProvider, zoneIdsSupplier, locationToIsoCodes); + + assertEquals(fn.get(), ImmutableSet.of( + new LocationBuilder().scope(LocationScope.ZONE).id("zone1").description("zone1").iso3166Codes(ImmutableSet.of("US-CA")).parent(provider).build(), + new LocationBuilder().scope(LocationScope.ZONE).id("zone2").description("zone2").iso3166Codes(ImmutableSet.of("US-VA")).parent(provider).build() + )); + } + + @Test(expectedExceptions = IllegalStateException.class) + public void testWhenNoZones() { + Supplier> zoneIdsSupplier = Suppliers.>ofInstance(ImmutableSet.of()); + Supplier>>> locationToIsoCodes = Suppliers.>>>ofInstance( + ImmutableMap.>>of()); + ZoneToProvider fn = new ZoneToProvider(justProvider, zoneIdsSupplier, locationToIsoCodes); + fn.get(); + } +} diff --git a/core/src/test/java/org/jclouds/location/suppliers/implicit/FirstRegionTest.java b/core/src/test/java/org/jclouds/location/suppliers/implicit/FirstRegionTest.java new file mode 100644 index 0000000000..6a37593013 --- /dev/null +++ b/core/src/test/java/org/jclouds/location/suppliers/implicit/FirstRegionTest.java @@ -0,0 +1,70 @@ +/** + * 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.implicit; + +import static org.testng.Assert.assertEquals; + +import java.util.NoSuchElementException; +import java.util.Set; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code FirstRegion} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "FirstRegionTest") +public class FirstRegionTest { + Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("servo").description("http://servo") + .build(); + Location region = new LocationBuilder().scope(LocationScope.REGION).id("servo-r").description("http://r.servo") + .parent(provider).build(); + Location zone = new LocationBuilder().scope(LocationScope.ZONE).id("servo-z").description("http://z.r.servo") + .parent(region).build(); + + @Test + public void testDidntFindRegionThrowsNSEEWithReasonableMessage() { + Supplier> supplier = Suppliers.> ofInstance(ImmutableSet + . of(provider, zone)); + FirstRegion fn = new FirstRegion(supplier); + + try { + fn.get(); + assert false; + } catch (NoSuchElementException e) { + assertEquals(e.getMessage(), "none to of the locations are scope REGION: [servo:PROVIDER, servo-z:ZONE]"); + } + } + + @Test + public void testFirstRegion() { + Supplier> supplier = Suppliers.> ofInstance(ImmutableSet + . of(provider, region, zone)); + FirstRegion fn = new FirstRegion(supplier); + assertEquals(fn.get(), region); + } +} diff --git a/core/src/test/java/org/jclouds/location/suppliers/implicit/FirstZoneTest.java b/core/src/test/java/org/jclouds/location/suppliers/implicit/FirstZoneTest.java new file mode 100644 index 0000000000..d9f523d8fc --- /dev/null +++ b/core/src/test/java/org/jclouds/location/suppliers/implicit/FirstZoneTest.java @@ -0,0 +1,70 @@ +/** + * 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.implicit; + +import static org.testng.Assert.assertEquals; + +import java.util.NoSuchElementException; +import java.util.Set; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableSet; + +/** + * Tests behavior of {@code FirstZone} + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "FirstZoneTest") +public class FirstZoneTest { + Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("servo").description("http://servo") + .build(); + Location region = new LocationBuilder().scope(LocationScope.REGION).id("servo-r").description("http://r.servo") + .parent(provider).build(); + Location zone = new LocationBuilder().scope(LocationScope.ZONE).id("servo-z").description("http://z.r.servo") + .parent(region).build(); + + @Test + public void testDidntFindZoneThrowsNSEEWithReasonableMessage() { + Supplier> supplier = Suppliers.> ofInstance(ImmutableSet + . of(provider, region)); + FirstZone fn = new FirstZone(supplier); + + try { + fn.get(); + assert false; + } catch (NoSuchElementException e) { + assertEquals(e.getMessage(), "none to of the locations are scope ZONE: [servo:PROVIDER, servo-r:REGION]"); + } + } + + @Test + public void testFirstZone() { + Supplier> supplier = Suppliers.> ofInstance(ImmutableSet + . of(provider, region, zone)); + FirstZone fn = new FirstZone(supplier); + assertEquals(fn.get(), zone); + } +}