Add Key#of and Key#keys, use key object as map key, add tests

This commit is contained in:
Lukasz Strzalkowski 2016-03-02 15:15:19 +01:00 committed by Eric Anderson
parent 12dfecba62
commit b37ebd6482
4 changed files with 97 additions and 12 deletions

View File

@ -33,7 +33,9 @@ package io.grpc;
import com.google.common.base.Preconditions;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@ -45,7 +47,7 @@ import javax.annotation.concurrent.Immutable;
@Immutable
public final class Attributes {
private final HashMap<String, Object> data = new HashMap<String, Object>();
private final HashMap<Key<?>, Object> data = new HashMap<Key<?>, Object>();
public static final Attributes EMPTY = new Attributes();
@ -58,7 +60,16 @@ public final class Attributes {
@SuppressWarnings("unchecked")
@Nullable
public <T> T get(Key<T> key) {
return (T) data.get(key.name);
return (T) data.get(key);
}
/**
* Returns set of keys stored in container.
*
* @return Set of Key objects.
*/
public Set<Key<?>> keys() {
return Collections.unmodifiableSet(data.keySet());
}
/**
@ -71,13 +82,7 @@ public final class Attributes {
public static final class Key<T> {
private final String name;
/**
* Construct the key.
*
* @param name the name, which should be namespaced like com.foo.BarAttribute to avoid
* collision.
*/
public Key(String name) {
private Key(String name) {
this.name = name;
}
@ -85,6 +90,18 @@ public final class Attributes {
public String toString() {
return name;
}
/**
* Factory method for creating instances of {@link Key}.
*
* @param name the name of Key, which should be namespaced like com.foo.BarAttribute to avoid
* collision. Name collision, won't cause key collision.
* @param <T> Key type
* @return Key object
*/
public static <T> Key<T> of(String name) {
return new Key<T>(name);
}
}
@Override
@ -100,7 +117,7 @@ public final class Attributes {
}
public <T> Builder set(Key<T> key, T value) {
product.data.put(key.name, value);
product.data.put(key, value);
return this;
}

View File

@ -74,7 +74,7 @@ public abstract class NameResolver {
* port number.
*/
public static final Attributes.Key<Integer> PARAMS_DEFAULT_PORT =
new Attributes.Key<Integer>("io.grpc.NameResolverDefaultPort");
Attributes.Key.of("io.grpc.NameResolverDefaultPort");
/**
* Creates a {@link NameResolver} for the given target URI, or {@code null} if the given URI

View File

@ -0,0 +1,68 @@
/*
* Copyright 2016, Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package io.grpc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link Attributes}. */
@RunWith(JUnit4.class)
public class AttributesTest {
private static Attributes.Key<String> YOLO_KEY = Attributes.Key.of("yolo");
@Test
public void buildAttributes() {
Attributes attrs = Attributes.newBuilder().set(YOLO_KEY, "To be, or not to be?").build();
assertSame("To be, or not to be?", attrs.get(YOLO_KEY));
assertEquals(1, attrs.keys().size());
}
@Test
public void duplicates() {
Attributes attrs = Attributes.newBuilder()
.set(YOLO_KEY, "To be?")
.set(YOLO_KEY, "Or not to be?")
.set(Attributes.Key.of("yolo"), "I'm not a duplicate")
.build();
assertSame("Or not to be?", attrs.get(YOLO_KEY));
assertEquals(2, attrs.keys().size());
}
@Test
public void empty() {
assertEquals(0, Attributes.EMPTY.keys().size());
}
}

View File

@ -53,7 +53,7 @@ import java.util.concurrent.TimeUnit;
public class CallOptionsTest {
private String sampleAuthority = "authority";
private Long sampleDeadlineNanoTime = 1L;
private Key<String> sampleKey = new Attributes.Key<String>("sample");
private Key<String> sampleKey = Attributes.Key.of("sample");
private Attributes sampleAffinity = Attributes.newBuilder().set(sampleKey, "blah").build();
private CallOptions allSet = CallOptions.DEFAULT
.withAuthority(sampleAuthority)