From ea3b009a963325d23312e6ba193e118d6ad92d13 Mon Sep 17 00:00:00 2001 From: Terry Wilson Date: Wed, 29 Sep 2021 13:50:37 -0700 Subject: [PATCH] Revert "Revert "core/auth: Remove CallCredentials2 (#8464)"" This reverts commit a91cc85dfd2f1f8cb749f6e8b5984a61da294902. --- .../main/java/io/grpc/CallCredentials2.java | 73 ---- .../GoogleAuthLibraryCallCredentials.java | 6 +- .../CallCredentials2ApplyingTest.java | 351 ------------------ .../internal/CallCredentialsApplyingTest.java | 45 +++ 4 files changed, 47 insertions(+), 428 deletions(-) delete mode 100644 api/src/main/java/io/grpc/CallCredentials2.java delete mode 100644 core/src/test/java/io/grpc/internal/CallCredentials2ApplyingTest.java diff --git a/api/src/main/java/io/grpc/CallCredentials2.java b/api/src/main/java/io/grpc/CallCredentials2.java deleted file mode 100644 index fdb7f51070a..00000000000 --- a/api/src/main/java/io/grpc/CallCredentials2.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2016 The gRPC Authors - * - * 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 io.grpc; - -import java.util.concurrent.Executor; - -/** - * The new interface for {@link CallCredentials}. - * - *

THIS CLASS NAME IS TEMPORARY and is part of a migration. This class will BE DELETED as it - * replaces {@link CallCredentials} in short-term. THIS CLASS IS ONLY REFERENCED BY IMPLEMENTIONS. - * All consumers should be always referencing {@link CallCredentials}. - * - * @deprecated the new interface has been promoted into {@link CallCredentials}. Implementations - * should switch back to "{@code extends CallCredentials}". - */ -@Deprecated -@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4901") -public abstract class CallCredentials2 extends CallCredentials { - /** - * Pass the credential data to the given {@link MetadataApplier}, which will propagate it to the - * request metadata. - * - *

It is called for each individual RPC, within the {@link Context} of the call, before the - * stream is about to be created on a transport. Implementations should not block in this - * method. If metadata is not immediately available, e.g., needs to be fetched from network, the - * implementation may give the {@code applier} to an asynchronous task which will eventually call - * the {@code applier}. The RPC proceeds only after the {@code applier} is called. - * - * @param requestInfo request-related information - * @param appExecutor The application thread-pool. It is provided to the implementation in case it - * needs to perform blocking operations. - * @param applier The outlet of the produced headers. It can be called either before or after this - * method returns. - */ - @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914") - public abstract void applyRequestMetadata( - RequestInfo requestInfo, Executor appExecutor, MetadataApplier applier); - - @Override - public final void applyRequestMetadata( - RequestInfo requestInfo, Executor appExecutor, - final CallCredentials.MetadataApplier applier) { - applyRequestMetadata(requestInfo, appExecutor, new MetadataApplier() { - @Override - public void apply(Metadata headers) { - applier.apply(headers); - } - - @Override - public void fail(Status status) { - applier.fail(status); - } - }); - } - - @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914") - public abstract static class MetadataApplier extends CallCredentials.MetadataApplier {} -} diff --git a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java index 852fba73b20..4b95a6c7f4d 100644 --- a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java +++ b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java @@ -42,11 +42,9 @@ import javax.annotation.Nullable; /** - * Wraps {@link Credentials} as a {@link CallCredentials}. + * Wraps {@link Credentials} as a {@link io.grpc.CallCredentials}. */ -// TODO(zhangkun83): remove the suppression after we change the base class to CallCredential -@SuppressWarnings("deprecation") -final class GoogleAuthLibraryCallCredentials extends io.grpc.CallCredentials2 { +final class GoogleAuthLibraryCallCredentials extends io.grpc.CallCredentials { private static final Logger log = Logger.getLogger(GoogleAuthLibraryCallCredentials.class.getName()); private static final JwtHelper jwtHelper diff --git a/core/src/test/java/io/grpc/internal/CallCredentials2ApplyingTest.java b/core/src/test/java/io/grpc/internal/CallCredentials2ApplyingTest.java deleted file mode 100644 index 963a586319b..00000000000 --- a/core/src/test/java/io/grpc/internal/CallCredentials2ApplyingTest.java +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Copyright 2016 The gRPC Authors - * - * 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 io.grpc.internal; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import io.grpc.Attributes; -import io.grpc.CallCredentials.MetadataApplier; -import io.grpc.CallCredentials.RequestInfo; -import io.grpc.CallOptions; -import io.grpc.ChannelLogger; -import io.grpc.ClientStreamTracer; -import io.grpc.IntegerMarshaller; -import io.grpc.Metadata; -import io.grpc.MethodDescriptor; -import io.grpc.SecurityLevel; -import io.grpc.Status; -import io.grpc.StringMarshaller; -import java.net.SocketAddress; -import java.util.concurrent.Executor; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatchers; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; -import org.mockito.stubbing.Answer; - -/** - * Unit test for {@link CallCredentials2} applying functionality implemented by {@link - * CallCredentialsApplyingTransportFactory} and {@link MetadataApplierImpl}. - */ -@SuppressWarnings("deprecation") -@RunWith(JUnit4.class) -public class CallCredentials2ApplyingTest { - @Rule - public final MockitoRule mocks = MockitoJUnit.rule(); - - @Mock - private ClientTransportFactory mockTransportFactory; - - @Mock - private ConnectionClientTransport mockTransport; - - @Mock - private ClientStream mockStream; - - @Mock - private io.grpc.CallCredentials2 mockCreds; - - @Mock - private Executor mockExecutor; - - @Mock - private SocketAddress address; - - // Noop logger; - @Mock - private ChannelLogger channelLogger; - - private static final String AUTHORITY = "testauthority"; - private static final String USER_AGENT = "testuseragent"; - private static final Attributes.Key ATTR_KEY = Attributes.Key.create("somekey"); - private static final String ATTR_VALUE = "somevalue"; - private static final MethodDescriptor method = - MethodDescriptor.newBuilder() - .setType(MethodDescriptor.MethodType.UNKNOWN) - .setFullMethodName("service/method") - .setRequestMarshaller(new StringMarshaller()) - .setResponseMarshaller(new IntegerMarshaller()) - .build(); - private static final Metadata.Key ORIG_HEADER_KEY = - Metadata.Key.of("header1", Metadata.ASCII_STRING_MARSHALLER); - private static final String ORIG_HEADER_VALUE = "some original header value"; - private static final Metadata.Key CREDS_KEY = - Metadata.Key.of("test-creds", Metadata.ASCII_STRING_MARSHALLER); - private static final String CREDS_VALUE = "some credentials"; - private static final ClientStreamTracer[] tracers = new ClientStreamTracer[] { - new ClientStreamTracer() {} - }; - - private final Metadata origHeaders = new Metadata(); - private ForwardingConnectionClientTransport transport; - private CallOptions callOptions; - - @Before - public void setUp() { - ClientTransportFactory.ClientTransportOptions clientTransportOptions = - new ClientTransportFactory.ClientTransportOptions() - .setAuthority(AUTHORITY) - .setUserAgent(USER_AGENT); - - origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE); - when(mockTransportFactory.newClientTransport(address, clientTransportOptions, channelLogger)) - .thenReturn(mockTransport); - when(mockTransport.newStream( - same(method), any(Metadata.class), any(CallOptions.class), - ArgumentMatchers.any())) - .thenReturn(mockStream); - ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory( - mockTransportFactory, null, mockExecutor); - transport = (ForwardingConnectionClientTransport) - transportFactory.newClientTransport(address, clientTransportOptions, channelLogger); - callOptions = CallOptions.DEFAULT.withCallCredentials(mockCreds); - verify(mockTransportFactory).newClientTransport(address, clientTransportOptions, channelLogger); - assertSame(mockTransport, transport.delegate()); - } - - @Test - public void parameterPropagation_base() { - Attributes transportAttrs = Attributes.newBuilder().set(ATTR_KEY, ATTR_VALUE).build(); - when(mockTransport.getAttributes()).thenReturn(transportAttrs); - - transport.newStream(method, origHeaders, callOptions, tracers); - - ArgumentCaptor infoCaptor = ArgumentCaptor.forClass(null); - verify(mockCreds).applyRequestMetadata( - infoCaptor.capture(), same(mockExecutor), - any(io.grpc.CallCredentials2.MetadataApplier.class)); - RequestInfo info = infoCaptor.getValue(); - assertSame(method, info.getMethodDescriptor()); - assertSame(ATTR_VALUE, info.getTransportAttrs().get(ATTR_KEY)); - assertSame(AUTHORITY, info.getAuthority()); - assertSame(SecurityLevel.NONE, info.getSecurityLevel()); - } - - @Test - public void parameterPropagation_transportSetSecurityLevel() { - Attributes transportAttrs = Attributes.newBuilder() - .set(ATTR_KEY, ATTR_VALUE) - .set(GrpcAttributes.ATTR_SECURITY_LEVEL, SecurityLevel.INTEGRITY) - .build(); - when(mockTransport.getAttributes()).thenReturn(transportAttrs); - - transport.newStream(method, origHeaders, callOptions, tracers); - - ArgumentCaptor infoCaptor = ArgumentCaptor.forClass(null); - verify(mockCreds).applyRequestMetadata( - infoCaptor.capture(), same(mockExecutor), - any(io.grpc.CallCredentials2.MetadataApplier.class)); - RequestInfo info = infoCaptor.getValue(); - assertSame(method, info.getMethodDescriptor()); - assertSame(ATTR_VALUE, info.getTransportAttrs().get(ATTR_KEY)); - assertSame(AUTHORITY, info.getAuthority()); - assertSame(SecurityLevel.INTEGRITY, info.getSecurityLevel()); - } - - @Test - public void parameterPropagation_callOptionsSetAuthority() { - Attributes transportAttrs = Attributes.newBuilder() - .set(ATTR_KEY, ATTR_VALUE) - .build(); - when(mockTransport.getAttributes()).thenReturn(transportAttrs); - Executor anotherExecutor = mock(Executor.class); - - transport.newStream( - method, origHeaders, - callOptions.withAuthority("calloptions-authority").withExecutor(anotherExecutor), - tracers); - - ArgumentCaptor infoCaptor = ArgumentCaptor.forClass(null); - verify(mockCreds).applyRequestMetadata( - infoCaptor.capture(), same(anotherExecutor), - any(io.grpc.CallCredentials2.MetadataApplier.class)); - RequestInfo info = infoCaptor.getValue(); - assertSame(method, info.getMethodDescriptor()); - assertSame(ATTR_VALUE, info.getTransportAttrs().get(ATTR_KEY)); - assertEquals("calloptions-authority", info.getAuthority()); - assertSame(SecurityLevel.NONE, info.getSecurityLevel()); - } - - @Test - public void credentialThrows() { - final RuntimeException ex = new RuntimeException(); - when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY); - doThrow(ex).when(mockCreds).applyRequestMetadata( - any(RequestInfo.class), same(mockExecutor), - any(io.grpc.CallCredentials2.MetadataApplier.class)); - - FailingClientStream stream = - (FailingClientStream) transport.newStream(method, origHeaders, callOptions, tracers); - - verify(mockTransport, never()).newStream( - any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), - ArgumentMatchers.any()); - assertEquals(Status.Code.UNAUTHENTICATED, stream.getError().getCode()); - assertSame(ex, stream.getError().getCause()); - transport.shutdown(Status.UNAVAILABLE); - assertTrue(transport.newStream(method, origHeaders, callOptions, tracers) - instanceof FailingClientStream); - verify(mockTransport).shutdown(Status.UNAVAILABLE); - } - - @Test - public void applyMetadata_inline() { - when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY); - doAnswer(new Answer() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - MetadataApplier applier = (MetadataApplier) invocation.getArguments()[2]; - Metadata headers = new Metadata(); - headers.put(CREDS_KEY, CREDS_VALUE); - applier.apply(headers); - return null; - } - }).when(mockCreds).applyRequestMetadata( - any(RequestInfo.class), same(mockExecutor), - any(io.grpc.CallCredentials2.MetadataApplier.class)); - - ClientStream stream = transport.newStream(method, origHeaders, callOptions, tracers); - - verify(mockTransport).newStream(method, origHeaders, callOptions, tracers); - assertSame(mockStream, stream); - assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY)); - assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY)); - transport.shutdown(Status.UNAVAILABLE); - assertTrue(transport.newStream(method, origHeaders, callOptions, tracers) - instanceof FailingClientStream); - verify(mockTransport).shutdown(Status.UNAVAILABLE); - } - - @Test - public void fail_inline() { - final Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds"); - when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY); - doAnswer(new Answer() { - @Override - public Void answer(InvocationOnMock invocation) throws Throwable { - MetadataApplier applier = (MetadataApplier) invocation.getArguments()[2]; - applier.fail(error); - return null; - } - }).when(mockCreds).applyRequestMetadata( - any(RequestInfo.class), same(mockExecutor), - any(io.grpc.CallCredentials2.MetadataApplier.class)); - - FailingClientStream stream = - (FailingClientStream) transport.newStream(method, origHeaders, callOptions, tracers); - - verify(mockTransport, never()).newStream( - any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), - ArgumentMatchers.any()); - assertSame(error, stream.getError()); - transport.shutdownNow(Status.UNAVAILABLE); - assertTrue(transport.newStream(method, origHeaders, callOptions, tracers) - instanceof FailingClientStream); - verify(mockTransport).shutdownNow(Status.UNAVAILABLE); - } - - @Test - public void applyMetadata_delayed() { - when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY); - - // Will call applyRequestMetadata(), which is no-op. - DelayedStream stream = (DelayedStream) transport.newStream( - method, origHeaders, callOptions, tracers); - - ArgumentCaptor applierCaptor = ArgumentCaptor.forClass(null); - verify(mockCreds).applyRequestMetadata( - any(RequestInfo.class), same(mockExecutor), applierCaptor.capture()); - verify(mockTransport, never()).newStream( - any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), - ArgumentMatchers.any()); - - transport.shutdown(Status.UNAVAILABLE); - verify(mockTransport, never()).shutdown(Status.UNAVAILABLE); - - Metadata headers = new Metadata(); - headers.put(CREDS_KEY, CREDS_VALUE); - applierCaptor.getValue().apply(headers); - - verify(mockTransport).newStream(method, origHeaders, callOptions, tracers); - assertSame(mockStream, stream.getRealStream()); - assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY)); - assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY)); - assertTrue(transport.newStream(method, origHeaders, callOptions, tracers) - instanceof FailingClientStream); - verify(mockTransport).shutdown(Status.UNAVAILABLE); - } - - @Test - public void fail_delayed() { - when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY); - - // Will call applyRequestMetadata(), which is no-op. - DelayedStream stream = (DelayedStream) transport.newStream( - method, origHeaders, callOptions, tracers); - - ArgumentCaptor applierCaptor = ArgumentCaptor.forClass(null); - verify(mockCreds).applyRequestMetadata( - any(RequestInfo.class), same(mockExecutor), applierCaptor.capture()); - - Status error = Status.FAILED_PRECONDITION.withDescription("channel not secure for creds"); - applierCaptor.getValue().fail(error); - - verify(mockTransport, never()).newStream( - any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class), - ArgumentMatchers.any()); - FailingClientStream failingStream = (FailingClientStream) stream.getRealStream(); - assertSame(error, failingStream.getError()); - transport.shutdown(Status.UNAVAILABLE); - assertTrue(transport.newStream(method, origHeaders, callOptions, tracers) - instanceof FailingClientStream); - verify(mockTransport).shutdown(Status.UNAVAILABLE); - } - - @Test - public void noCreds() { - callOptions = callOptions.withCallCredentials(null); - ClientStream stream = transport.newStream(method, origHeaders, callOptions, tracers); - - verify(mockTransport).newStream(method, origHeaders, callOptions, tracers); - assertSame(mockStream, stream); - assertNull(origHeaders.get(CREDS_KEY)); - assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY)); - transport.shutdown(Status.UNAVAILABLE); - assertTrue(transport.newStream(method, origHeaders, callOptions, tracers) - instanceof FailingClientStream); - verify(mockTransport).shutdown(Status.UNAVAILABLE); - } -} diff --git a/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java b/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java index ef49e66bf2d..2f0ce1070b1 100644 --- a/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java +++ b/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java @@ -176,6 +176,51 @@ public void parameterPropagation_overrideByCallOptions() { assertSame(SecurityLevel.INTEGRITY, info.getSecurityLevel()); } + @Test + public void parameterPropagation_transportSetSecurityLevel() { + Attributes transportAttrs = Attributes.newBuilder() + .set(ATTR_KEY, ATTR_VALUE) + .set(GrpcAttributes.ATTR_SECURITY_LEVEL, SecurityLevel.INTEGRITY) + .build(); + when(mockTransport.getAttributes()).thenReturn(transportAttrs); + + transport.newStream(method, origHeaders, callOptions, tracers); + + ArgumentCaptor infoCaptor = ArgumentCaptor.forClass(null); + verify(mockCreds).applyRequestMetadata( + infoCaptor.capture(), same(mockExecutor), + any(io.grpc.CallCredentials.MetadataApplier.class)); + RequestInfo info = infoCaptor.getValue(); + assertSame(method, info.getMethodDescriptor()); + assertSame(ATTR_VALUE, info.getTransportAttrs().get(ATTR_KEY)); + assertSame(AUTHORITY, info.getAuthority()); + assertSame(SecurityLevel.INTEGRITY, info.getSecurityLevel()); + } + + @Test + public void parameterPropagation_callOptionsSetAuthority() { + Attributes transportAttrs = Attributes.newBuilder() + .set(ATTR_KEY, ATTR_VALUE) + .build(); + when(mockTransport.getAttributes()).thenReturn(transportAttrs); + Executor anotherExecutor = mock(Executor.class); + + transport.newStream( + method, origHeaders, + callOptions.withAuthority("calloptions-authority").withExecutor(anotherExecutor), + tracers); + + ArgumentCaptor infoCaptor = ArgumentCaptor.forClass(null); + verify(mockCreds).applyRequestMetadata( + infoCaptor.capture(), same(anotherExecutor), + any(io.grpc.CallCredentials.MetadataApplier.class)); + RequestInfo info = infoCaptor.getValue(); + assertSame(method, info.getMethodDescriptor()); + assertSame(ATTR_VALUE, info.getTransportAttrs().get(ATTR_KEY)); + assertEquals("calloptions-authority", info.getAuthority()); + assertSame(SecurityLevel.NONE, info.getSecurityLevel()); + } + @Test public void credentialThrows() { final RuntimeException ex = new RuntimeException();