Repository: jclouds Updated Branches: refs/heads/master 98ea91747 -> 36cb2a1c7
JCLOUDS-1227: Allow to configure regions with the same URI Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/36cb2a1c Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/36cb2a1c Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/36cb2a1c Branch: refs/heads/master Commit: 36cb2a1c72076b4e7200599911ab18c1078867bd Parents: 98ea917 Author: Ignasi Barrera <[email protected]> Authored: Tue Jan 17 22:41:09 2017 +0100 Committer: Ignasi Barrera <[email protected]> Committed: Wed Jan 18 10:05:30 2017 +0100 ---------------------------------------------------------------------- .../suppliers/SupplyKeyMatchingValueOrNull.java | 35 ++++++++-- .../SupplyKeyMatchingValueOrNullTest.java | 67 ++++++++++++++++++++ 2 files changed, 95 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds/blob/36cb2a1c/core/src/main/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNull.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNull.java b/core/src/main/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNull.java index 2cbdb85..1ddf6c1 100644 --- a/core/src/main/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNull.java +++ b/core/src/main/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNull.java @@ -16,17 +16,20 @@ */ package org.jclouds.suppliers; +import java.util.Collection; import java.util.Map; import javax.annotation.Resource; import org.jclouds.logging.Logger; +import com.google.common.base.Function; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; -import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; /** * Allows you to lazy discover a key by value. This is useful for example in service discovery, @@ -49,12 +52,30 @@ public class SupplyKeyMatchingValueOrNull<K, V> implements Supplier<K> { public K get() { V uri = valueSupplier.get(); // eagerly get all the values, so we can see which is default - Map<K, V> map = Maps.transformValues(supplier.get(), Suppliers.<V> supplierFunction()); - K region = ImmutableBiMap.copyOf(map).inverse().get(uri); - if (region == null && !map.isEmpty()) { - region = Iterables.get(map.keySet(), 0); - logger.warn("failed to find key for value %s in %s; choosing first: %s", uri, map, region); + final Map<K, V> map = Maps.transformValues(supplier.get(), Suppliers.<V> supplierFunction()); + + // There can be keys with the same value so we need a multimap here + Multimap<V, K> inverted = Multimaps.index(map.keySet(), new Function<K, V>() { + @Override public V apply(K input) { + return map.get(input); + } + }); + + Collection<K> keys = inverted.get(uri); + K key = null; + + if (keys == null || keys.isEmpty()) { + if (!map.isEmpty()) { + key = Iterables.get(map.keySet(), 0); + logger.warn("failed to find key for value %s in %s; choosing first: %s", uri, map, key); + } + } else { + key = Iterables.get(keys, 0); + if (keys.size() > 1) { + logger.debug("found %s keys for value %s. choosing first: %s", keys.size(), uri, key); + } } - return region; + + return key; } } http://git-wip-us.apache.org/repos/asf/jclouds/blob/36cb2a1c/core/src/test/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNullTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNullTest.java b/core/src/test/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNullTest.java new file mode 100644 index 0000000..5c7b88a --- /dev/null +++ b/core/src/test/java/org/jclouds/suppliers/SupplyKeyMatchingValueOrNullTest.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.suppliers; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.util.Map; + +import org.testng.annotations.Test; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableMap; + +@Test(groups = "unit", testName = "SupplyKeyMatchingValueOrNullTest") +public class SupplyKeyMatchingValueOrNullTest { + + private static final Supplier<String> valueSupplier = Suppliers.ofInstance("v3"); + + public void testValueFound() { + SupplyKeyMatchingValueOrNull<String, String> supplier = supplier("k1", "v1", "k2", "v2", "k3", "v3"); + assertEquals(supplier.get(), "k3"); + } + + public void testFirstKeyIsReturnedIfValueNotFound() { + SupplyKeyMatchingValueOrNull<String, String> supplier = supplier("k1", "v1", "k2", "v2", "k4", "v4"); + assertEquals(supplier.get(), "k1"); + } + + public void testFirstKeyIsReturnedIfMultipleValuesFound() { + SupplyKeyMatchingValueOrNull<String, String> supplier = supplier("k1", "v1", "k2", "v3", "k3", "v3"); + assertEquals(supplier.get(), "k2"); + } + + public void testReturnsNullIfEmptyMap() { + SupplyKeyMatchingValueOrNull<String, String> supplier = new SupplyKeyMatchingValueOrNull<String, String>( + Suppliers.<Map<String, Supplier<String>>> ofInstance(ImmutableMap.<String, Supplier<String>> of()), + valueSupplier); + assertNull(supplier.get()); + } + + private static SupplyKeyMatchingValueOrNull<String, String> supplier(String k1, String v1, String k2, String v2, + String k3, String v3) { + return new SupplyKeyMatchingValueOrNull<String, String>(map(k1, v1, k2, v2, k3, v3), valueSupplier); + } + + private static Supplier<Map<String, Supplier<String>>> map(String k1, String v1, String k2, String v2, String k3, + String v3) { + return Suppliers.<Map<String, Supplier<String>>> ofInstance(ImmutableMap.of(k1, Suppliers.ofInstance(v1), k2, + Suppliers.ofInstance(v2), k3, Suppliers.ofInstance(v3))); + } +}
