下面列出了怎么用io.grpc.Metadata.Key的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void dupBinHeadersWithComma() {
Key<byte[]> key = Key.of("bytes-bin", BINARY_BYTE_MARSHALLER);
Http2Headers http2Headers = new GrpcHttp2RequestHeaders(2);
http2Headers.add(AsciiString.of("bytes-bin"), AsciiString.of("BaS,e6,,4+,padding=="));
http2Headers.add(AsciiString.of("bytes-bin"), AsciiString.of("more"));
http2Headers.add(AsciiString.of("bytes-bin"), AsciiString.of(""));
Metadata recoveredHeaders = Utils.convertHeaders(http2Headers);
byte[][] values = Iterables.toArray(recoveredHeaders.getAll(key), byte[].class);
assertTrue(Arrays.deepEquals(
new byte[][] {
BaseEncoding.base64().decode("BaS"),
BaseEncoding.base64().decode("e6"),
BaseEncoding.base64().decode(""),
BaseEncoding.base64().decode("4+"),
BaseEncoding.base64().decode("padding"),
BaseEncoding.base64().decode("more"),
BaseEncoding.base64().decode("")},
values));
}
private static ClientInterceptor metadataInterceptor(Map<String, Object> metaDataMap) {
return new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
final MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, final Channel next) {
return new CheckedForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
@Override
protected void checkedStart(Listener<RespT> responseListener, Metadata headers) {
metaDataMap.forEach((k, v) -> {
Key<String> mKey = Key.of(k, ASCII_STRING_MARSHALLER);
headers.put(mKey, String.valueOf(v));
});
delegate().start(responseListener, headers);
}
};
}
};
}
private static ClientInterceptor metadataInterceptor(Map<String, Object> metaDataMap) {
return new ClientInterceptor() {
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
final MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, final Channel next) {
return new CheckedForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
@Override
protected void checkedStart(Listener<RespT> responseListener, Metadata headers) {
metaDataMap.forEach((k, v) -> {
Key<String> mKey = Key.of(k, ASCII_STRING_MARSHALLER);
headers.put(mKey, String.valueOf(v));
});
delegate().start(responseListener, headers);
}
};
}
};
}
@Test
public void dupBinHeadersWithComma() {
Key<byte[]> key = Key.of("bytes-bin", BINARY_BYTE_MARSHALLER);
Http2Headers http2Headers = new GrpcHttp2RequestHeaders(2);
http2Headers.add(AsciiString.of("bytes-bin"), AsciiString.of("BaS,e6,,4+,padding=="));
http2Headers.add(AsciiString.of("bytes-bin"), AsciiString.of("more"));
http2Headers.add(AsciiString.of("bytes-bin"), AsciiString.of(""));
Metadata recoveredHeaders = Utils.convertHeaders(http2Headers);
byte[][] values = Iterables.toArray(recoveredHeaders.getAll(key), byte[].class);
assertTrue(Arrays.deepEquals(
new byte[][] {
BaseEncoding.base64().decode("BaS"),
BaseEncoding.base64().decode("e6"),
BaseEncoding.base64().decode(""),
BaseEncoding.base64().decode("4+"),
BaseEncoding.base64().decode("padding"),
BaseEncoding.base64().decode("more"),
BaseEncoding.base64().decode("")},
values));
}
@Test
public void noPseudoHeaders() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Invalid character");
Metadata.Key.of(":test-bin", FISH_MARSHALLER);
}
@Test
public void invalidSuffixBinaryKeyName() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Binary header is named");
Metadata.Key.of("nonbinary", FISH_MARSHALLER);
}
@Test
public void verifyToString() {
Metadata h = new Metadata();
h.put(KEY, new Fish("binary"));
h.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test-bin=YmluYXJ5,test=ascii)", h.toString());
Metadata t = new Metadata();
t.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test=ascii)", t.toString());
t = new Metadata("test".getBytes(US_ASCII), "ascii".getBytes(US_ASCII),
"test-bin".getBytes(US_ASCII), "binary".getBytes(US_ASCII));
assertEquals("Metadata(test=ascii,test-bin=YmluYXJ5)", t.toString());
}
@Test
public void verifyToString_usingBinary() {
Metadata h = new Metadata();
h.put(KEY, new Fish("binary"));
h.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test-bin=YmluYXJ5,test=ascii)", h.toString());
Metadata t = new Metadata();
t.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test=ascii)", t.toString());
}
@Test
public void testKeyCaseHandling() {
Locale originalLocale = Locale.getDefault();
Locale.setDefault(new Locale("tr", "TR"));
try {
// In Turkish, both I and i (which are in ASCII) change into non-ASCII characters when their
// case is changed as ı and İ, respectively.
assertEquals("İ", "i".toUpperCase());
assertEquals("ı", "I".toLowerCase());
Metadata.Key<String> keyTitleCase
= Metadata.Key.of("If-Modified-Since", Metadata.ASCII_STRING_MARSHALLER);
Metadata.Key<String> keyLowerCase
= Metadata.Key.of("if-modified-since", Metadata.ASCII_STRING_MARSHALLER);
Metadata.Key<String> keyUpperCase
= Metadata.Key.of("IF-MODIFIED-SINCE", Metadata.ASCII_STRING_MARSHALLER);
Metadata metadata = new Metadata();
metadata.put(keyTitleCase, "plain string");
assertEquals("plain string", metadata.get(keyTitleCase));
assertEquals("plain string", metadata.get(keyLowerCase));
assertEquals("plain string", metadata.get(keyUpperCase));
byte[][] bytes = metadata.serialize();
assertEquals(2, bytes.length);
assertArrayEquals("if-modified-since".getBytes(US_ASCII), bytes[0]);
assertArrayEquals("plain string".getBytes(US_ASCII), bytes[1]);
} finally {
Locale.setDefault(originalLocale);
}
}
@Test
public void removeIgnoresMissingValue() {
Metadata m = new Metadata();
// Any key will work.
Key<String> key = GrpcUtil.USER_AGENT_KEY;
boolean success = m.remove(key, "agent");
assertFalse(success);
}
@Test
public void removeAllIgnoresMissingValue() {
Metadata m = new Metadata();
// Any key will work.
Key<String> key = GrpcUtil.USER_AGENT_KEY;
Iterable<String> removed = m.removeAll(key);
assertNull(removed);
}
@Test
public void keyEqualsHashNameWorks() {
Key<?> k1 = Key.of("case", Metadata.ASCII_STRING_MARSHALLER);
Key<?> k2 = Key.of("CASE", Metadata.ASCII_STRING_MARSHALLER);
assertEquals(k1, k1);
assertNotEquals(k1, null);
assertNotEquals(k1, new Object(){});
assertEquals(k1, k2);
assertEquals(k1.hashCode(), k2.hashCode());
// Check that the casing is preserved.
assertEquals("CASE", k2.originalName());
assertEquals("case", k2.name());
}
@Test
public void invalidKeyName() {
try {
Key.of("io.grpc/key1", Metadata.ASCII_STRING_MARSHALLER);
fail("Should have thrown");
} catch (IllegalArgumentException e) {
assertEquals("Invalid character '/' in key name 'io.grpc/key1'", e.getMessage());
}
}
@Test
public void noStickinessEnabled_withStickyHeader() {
loadBalancer.handleResolvedAddressGroups(servers, Attributes.EMPTY);
for (Subchannel subchannel : subchannels.values()) {
loadBalancer.handleSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
}
verify(mockHelper, times(4))
.updateBalancingState(any(ConnectivityState.class), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
Key<String> stickinessKey = Key.of("my-sticky-key", Metadata.ASCII_STRING_MARSHALLER);
Metadata headerWithStickinessValue = new Metadata();
headerWithStickinessValue.put(stickinessKey, "my-sticky-value");
doReturn(headerWithStickinessValue).when(mockArgs).getHeaders();
List<Subchannel> allSubchannels = getList(picker);
Subchannel sc1 = picker.pickSubchannel(mockArgs).getSubchannel();
Subchannel sc2 = picker.pickSubchannel(mockArgs).getSubchannel();
Subchannel sc3 = picker.pickSubchannel(mockArgs).getSubchannel();
Subchannel sc4 = picker.pickSubchannel(mockArgs).getSubchannel();
assertEquals(nextSubchannel(sc1, allSubchannels), sc2);
assertEquals(nextSubchannel(sc2, allSubchannels), sc3);
assertEquals(nextSubchannel(sc3, allSubchannels), sc1);
assertEquals(sc4, sc1);
assertNull(loadBalancer.getStickinessMapForTest());
}
@Test
public void stickinessEnabled_withStickyHeader() {
Map<String, Object> serviceConfig = new HashMap<String, Object>();
serviceConfig.put("stickinessMetadataKey", "my-sticky-key");
Attributes attributes = Attributes.newBuilder()
.set(GrpcAttributes.NAME_RESOLVER_SERVICE_CONFIG, serviceConfig).build();
loadBalancer.handleResolvedAddressGroups(servers, attributes);
for (Subchannel subchannel : subchannels.values()) {
loadBalancer.handleSubchannelState(subchannel, ConnectivityStateInfo.forNonError(READY));
}
verify(mockHelper, times(4))
.updateBalancingState(stateCaptor.capture(), pickerCaptor.capture());
SubchannelPicker picker = pickerCaptor.getValue();
Key<String> stickinessKey = Key.of("my-sticky-key", Metadata.ASCII_STRING_MARSHALLER);
Metadata headerWithStickinessValue = new Metadata();
headerWithStickinessValue.put(stickinessKey, "my-sticky-value");
doReturn(headerWithStickinessValue).when(mockArgs).getHeaders();
Subchannel sc1 = picker.pickSubchannel(mockArgs).getSubchannel();
assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());
assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());
assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());
assertEquals(sc1, picker.pickSubchannel(mockArgs).getSubchannel());
verify(mockArgs, atLeast(4)).getHeaders();
assertNotNull(loadBalancer.getStickinessMapForTest());
assertThat(loadBalancer.getStickinessMapForTest()).hasSize(1);
}
@Override
public void onHeaders(Metadata metadata) {
super.onHeaders(metadata);
ImmutableMap.Builder<String, String> headerBuilder = ImmutableMap.builder();
for (String key : metadata.keys()) {
// Ignore binary headers
if (!key.endsWith(Metadata.BINARY_HEADER_SUFFIX)) {
Key<String> stringKey = Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
if (metadata.containsKey(stringKey)) {
headerBuilder.put(key, metadata.get(stringKey));
}
}
}
headerMap = headerBuilder.build();
}
public static Key<String> getKey(String key) {
Key<String> headKey = keyMap.get(key);
if (headKey == null) {
headKey = Key.of(key, Metadata.ASCII_STRING_MARSHALLER);
Key<String> old = keyMap.putIfAbsent(key, headKey);
if (old != null) {
headKey = old;
}
}
return headKey;
}
@Override
public void applyRequestMetadata(RequestInfo requestInfo, Executor appExecutor, MetadataApplier metadataApplier) {
appExecutor.execute(() -> {
try {
var headers = new Metadata();
var passwordKey = Key.of(PASSWORD_KEY, ASCII_STRING_MARSHALLER);
headers.put(passwordKey, passwordValue);
metadataApplier.apply(headers);
} catch (Throwable ex) {
metadataApplier.fail(UNAUTHENTICATED.withCause(ex));
}
});
}
@Test
public void noPseudoHeaders() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Invalid character");
Metadata.Key.of(":test-bin", FISH_MARSHALLER);
}
@Test
public void invalidSuffixBinaryKeyName() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Binary header is named");
Metadata.Key.of("nonbinary", FISH_MARSHALLER);
}
@Test
public void verifyToString() {
Metadata h = new Metadata();
h.put(KEY, new Fish("binary"));
h.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test-bin=YmluYXJ5,test=ascii)", h.toString());
Metadata t = new Metadata();
t.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test=ascii)", t.toString());
t = new Metadata("test".getBytes(US_ASCII), "ascii".getBytes(US_ASCII),
"test-bin".getBytes(US_ASCII), "binary".getBytes(US_ASCII));
assertEquals("Metadata(test=ascii,test-bin=YmluYXJ5)", t.toString());
}
@Test
public void verifyToString_usingBinary() {
Metadata h = new Metadata();
h.put(KEY, new Fish("binary"));
h.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test-bin=YmluYXJ5,test=ascii)", h.toString());
Metadata t = new Metadata();
t.put(Metadata.Key.of("test", Metadata.ASCII_STRING_MARSHALLER), "ascii");
assertEquals("Metadata(test=ascii)", t.toString());
}
@Test
public void testKeyCaseHandling() {
Locale originalLocale = Locale.getDefault();
Locale.setDefault(new Locale("tr", "TR"));
try {
// In Turkish, both I and i (which are in ASCII) change into non-ASCII characters when their
// case is changed as ı and İ, respectively.
assertEquals("İ", "i".toUpperCase());
assertEquals("ı", "I".toLowerCase());
Metadata.Key<String> keyTitleCase
= Metadata.Key.of("If-Modified-Since", Metadata.ASCII_STRING_MARSHALLER);
Metadata.Key<String> keyLowerCase
= Metadata.Key.of("if-modified-since", Metadata.ASCII_STRING_MARSHALLER);
Metadata.Key<String> keyUpperCase
= Metadata.Key.of("IF-MODIFIED-SINCE", Metadata.ASCII_STRING_MARSHALLER);
Metadata metadata = new Metadata();
metadata.put(keyTitleCase, "plain string");
assertEquals("plain string", metadata.get(keyTitleCase));
assertEquals("plain string", metadata.get(keyLowerCase));
assertEquals("plain string", metadata.get(keyUpperCase));
byte[][] bytes = metadata.serialize();
assertEquals(2, bytes.length);
assertArrayEquals("if-modified-since".getBytes(US_ASCII), bytes[0]);
assertArrayEquals("plain string".getBytes(US_ASCII), bytes[1]);
} finally {
Locale.setDefault(originalLocale);
}
}
@Test
public void removeIgnoresMissingValue() {
Metadata m = new Metadata();
// Any key will work.
Key<String> key = GrpcUtil.USER_AGENT_KEY;
boolean success = m.remove(key, "agent");
assertFalse(success);
}
@Test
public void removeAllIgnoresMissingValue() {
Metadata m = new Metadata();
// Any key will work.
Key<String> key = GrpcUtil.USER_AGENT_KEY;
Iterable<String> removed = m.removeAll(key);
assertNull(removed);
}
@Test
public void keyEqualsHashNameWorks() {
Key<?> k1 = Key.of("case", Metadata.ASCII_STRING_MARSHALLER);
Key<?> k2 = Key.of("CASE", Metadata.ASCII_STRING_MARSHALLER);
assertEquals(k1, k1);
assertNotEquals(k1, null);
assertNotEquals(k1, new Object(){});
assertEquals(k1, k2);
assertEquals(k1.hashCode(), k2.hashCode());
// Check that the casing is preserved.
assertEquals("CASE", k2.originalName());
assertEquals("case", k2.name());
}
@Test
public void invalidKeyName() {
try {
Key.of("io.grpc/key1", Metadata.ASCII_STRING_MARSHALLER);
fail("Should have thrown");
} catch (IllegalArgumentException e) {
assertEquals("Invalid character '/' in key name 'io.grpc/key1'", e.getMessage());
}
}
GrpcClientRequest(Map<String, Key<String>> nameToKey, MethodDescriptor<?, ?> methodDescriptor,
CallOptions callOptions, ClientCall<?, ?> call, Metadata headers) {
if (nameToKey == null) throw new NullPointerException("nameToKey == null");
if (methodDescriptor == null) throw new NullPointerException("methodDescriptor == null");
if (callOptions == null) throw new NullPointerException("callOptions == null");
if (call == null) throw new NullPointerException("call == null");
if (headers == null) throw new NullPointerException("headers == null");
this.nameToKey = nameToKey;
this.methodDescriptor = methodDescriptor;
this.callOptions = callOptions;
this.call = call;
this.headers = headers;
}
GrpcServerRequest(Map<String, Key<String>> nameToKey, ServerCall<?, ?> call, Metadata headers) {
if (nameToKey == null) throw new NullPointerException("nameToKey == null");
if (call == null) throw new NullPointerException("call == null");
if (headers == null) throw new NullPointerException("headers == null");
this.nameToKey = nameToKey;
this.call = call;
this.headers = headers;
}
Channel clientWithB3SingleHeader(TraceContext parent) {
return ClientInterceptors.intercept(client, new ClientInterceptor() {
@Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
return new SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) {
@Override public void start(Listener<RespT> responseListener, Metadata headers) {
headers.put(Key.of("b3", ASCII_STRING_MARSHALLER),
B3SingleFormat.writeB3SingleFormat(parent));
super.start(responseListener, headers);
}
};
}
});
}