core: promote CallCredentials API v2. (#4952)

This is Step 3 of #4901.  The old interface has been deprecated in the
latest release.  Now it's time to replace it with the new API.
diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java
index 300fd78..b87f7a2 100644
--- a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java
+++ b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java
@@ -20,7 +20,6 @@
 import com.google.common.base.Preconditions;
 import com.google.protobuf.Any;
 import io.grpc.Attributes;
-import io.grpc.CallCredentials;
 import io.grpc.Grpc;
 import io.grpc.InternalChannelz.OtherSecurity;
 import io.grpc.InternalChannelz.Security;
@@ -28,6 +27,7 @@
 import io.grpc.Status;
 import io.grpc.alts.internal.RpcProtocolVersionsUtil.RpcVersionsCheckResult;
 import io.grpc.alts.internal.TsiHandshakeHandler.TsiHandshakeCompletionEvent;
+import io.grpc.internal.GrpcAttributes;
 import io.grpc.netty.GrpcHttp2ConnectionHandler;
 import io.grpc.netty.ProtocolNegotiator;
 import io.grpc.netty.ProtocolNegotiators.AbstractBufferingHandler;
@@ -146,7 +146,7 @@
                     .set(ALTS_CONTEXT_KEY, altsContext)
                     .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, ctx.channel().remoteAddress())
                     .set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, ctx.channel().localAddress())
-                    .set(CallCredentials.ATTR_SECURITY_LEVEL, SecurityLevel.PRIVACY_AND_INTEGRITY)
+                    .set(GrpcAttributes.ATTR_SECURITY_LEVEL, SecurityLevel.PRIVACY_AND_INTEGRITY)
                     .build(),
                 new Security(new OtherSecurity("alts", Any.pack(altsContext.context))));
           }
diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java
index 1670a4c..88f6478 100644
--- a/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java
+++ b/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java
@@ -24,13 +24,13 @@
 import static org.junit.Assert.assertTrue;
 
 import io.grpc.Attributes;
-import io.grpc.CallCredentials;
 import io.grpc.Grpc;
 import io.grpc.InternalChannelz;
 import io.grpc.SecurityLevel;
 import io.grpc.alts.internal.Handshaker.HandshakerResult;
 import io.grpc.alts.internal.TsiFrameProtector.Consumer;
 import io.grpc.alts.internal.TsiPeer.Property;
+import io.grpc.internal.GrpcAttributes;
 import io.grpc.netty.GrpcHttp2ConnectionHandler;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
@@ -349,7 +349,7 @@
         .isEqualTo("embedded");
     assertThat(grpcHandler.attrs.get(Grpc.TRANSPORT_ATTR_LOCAL_ADDR).toString())
         .isEqualTo("embedded");
-    assertThat(grpcHandler.attrs.get(CallCredentials.ATTR_SECURITY_LEVEL))
+    assertThat(grpcHandler.attrs.get(GrpcAttributes.ATTR_SECURITY_LEVEL))
         .isEqualTo(SecurityLevel.PRIVACY_AND_INTEGRITY);
   }
 
diff --git a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java
index 32855e3..2851dce 100644
--- a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java
+++ b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java
@@ -22,7 +22,7 @@
 import com.google.auth.RequestMetadataCallback;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.io.BaseEncoding;
-import io.grpc.CallCredentials2;
+import io.grpc.CallCredentials;
 import io.grpc.Metadata;
 import io.grpc.MethodDescriptor;
 import io.grpc.SecurityLevel;
@@ -46,7 +46,7 @@
 /**
  * Wraps {@link Credentials} as a {@link CallCredentials}.
  */
-final class GoogleAuthLibraryCallCredentials extends CallCredentials2 {
+final class GoogleAuthLibraryCallCredentials extends CallCredentials {
   private static final Logger log
       = Logger.getLogger(GoogleAuthLibraryCallCredentials.class.getName());
   private static final JwtHelper jwtHelper
diff --git a/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTest.java b/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTest.java
index a740741..3b32d00 100644
--- a/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTest.java
+++ b/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTest.java
@@ -39,8 +39,8 @@
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.Multimaps;
 import io.grpc.Attributes;
+import io.grpc.CallCredentials;
 import io.grpc.CallCredentials.MetadataApplier;
-import io.grpc.CallCredentials2;
 import io.grpc.Metadata;
 import io.grpc.MethodDescriptor;
 import io.grpc.SecurityLevel;
@@ -393,7 +393,7 @@
     return savedPendingRunnables.size();
   }
 
-  private final class RequestInfoImpl extends CallCredentials2.RequestInfo {
+  private final class RequestInfoImpl extends CallCredentials.RequestInfo {
     final String authority;
     final SecurityLevel securityLevel;
 
diff --git a/core/src/main/java/io/grpc/CallCredentials.java b/core/src/main/java/io/grpc/CallCredentials.java
index 2bc4b28..cfca24a 100644
--- a/core/src/main/java/io/grpc/CallCredentials.java
+++ b/core/src/main/java/io/grpc/CallCredentials.java
@@ -16,7 +16,6 @@
 
 package io.grpc;
 
-import io.grpc.Attributes.Key;
 import java.util.concurrent.Executor;
 
 /**
@@ -35,35 +34,10 @@
  * pass that reference to gRPC for usage. However, code may not call or implement the {@code
  * CallCredentials} itself if it wishes to only use stable APIs.
  */
-public interface CallCredentials {
+public abstract class CallCredentials {
   /**
-   * The security level of the transport. It is guaranteed to be present in the {@code attrs} passed
-   * to {@link #applyRequestMetadata}. It is by default {@link SecurityLevel#NONE} but can be
-   * overridden by the transport.
-   *
-   * @deprecated transport implementations should use {@code
-   * io.grpc.internal.GrpcAttributes.ATTR_SECURITY_LEVEL} instead.
-   */
-  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
-  @Grpc.TransportAttr
-  @Deprecated
-  public static final Key<SecurityLevel> ATTR_SECURITY_LEVEL =
-      Key.create("io.grpc.internal.GrpcAttributes.securityLevel");
-
-  /**
-   * The authority string used to authenticate the server. Usually it's the server's host name. It
-   * is guaranteed to be present in the {@code attrs} passed to {@link #applyRequestMetadata}. It is
-   * by default from the channel, but can be overridden by the transport and {@link
-   * io.grpc.CallOptions} with increasing precedence.
-   */
-  @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
-  @Grpc.TransportAttr
-  @Deprecated
-  public static final Key<String> ATTR_AUTHORITY = Key.create("io.grpc.CallCredentials.authority");
-
-  /**
-   * Pass the credential data to the given {@link MetadataApplier}, which will propagate it to
-   * the request metadata.
+   * Pass the credential data to the given {@link CallCredentials.MetadataApplier}, which will
+   * propagate it to the request metadata.
    *
    * <p>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
@@ -71,28 +45,22 @@
    * 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 method The method descriptor of this RPC
-   * @param attrs Additional attributes from the transport, along with the keys defined in this
-   *        interface (i.e. the {@code ATTR_*} fields) which are guaranteed to be present.
+   * @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.
-   *
-   * @deprecated implement {@link CallCredentials2} instead.
    */
   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
-  @Deprecated
-  void applyRequestMetadata(
-      MethodDescriptor<?, ?> method, Attributes attrs,
-      Executor appExecutor, MetadataApplier applier);
+  public abstract void applyRequestMetadata(
+      RequestInfo requestInfo, Executor appExecutor, MetadataApplier applier);
 
   /**
    * Should be a noop but never called; tries to make it clearer to implementors that they may break
    * in the future.
    */
   @ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
-  void thisUsesUnstableApi();
+  public abstract void thisUsesUnstableApi();
 
   /**
    * The outlet of the produced headers. Not thread-safe.
diff --git a/core/src/main/java/io/grpc/CallCredentials2.java b/core/src/main/java/io/grpc/CallCredentials2.java
index 458a04c..8d8539b 100644
--- a/core/src/main/java/io/grpc/CallCredentials2.java
+++ b/core/src/main/java/io/grpc/CallCredentials2.java
@@ -16,69 +16,13 @@
 
 package io.grpc;
 
-import static com.google.common.base.MoreObjects.firstNonNull;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.concurrent.Executor;
-
 /**
  * The new interface for {@link CallCredentials}.
  *
- * <p>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 SHOULD ONLY BE REFERENCED BY
- * IMPLEMENTIONS.  All consumers should still reference {@link CallCredentials}.
+ * @deprecated implementations should subclass {@link CallCredentials} instead. This name is part
+ *             of a migration and will be deleted in the next release.
  */
 @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4901")
-public abstract class CallCredentials2 implements CallCredentials {
-  /**
-   * Pass the credential data to the given {@link CallCredentials.MetadataApplier}, which will
-   * propagate it to the request metadata.
-   *
-   * <p>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
-  @SuppressWarnings("deprecation")
-  public final void applyRequestMetadata(
-      final MethodDescriptor<?, ?> method, final Attributes attrs,
-      Executor appExecutor, CallCredentials.MetadataApplier applier) {
-    final String authority = checkNotNull(attrs.get(ATTR_AUTHORITY), "authority");
-    final SecurityLevel securityLevel =
-        firstNonNull(attrs.get(ATTR_SECURITY_LEVEL), SecurityLevel.NONE);
-    RequestInfo requestInfo = new RequestInfo() {
-        @Override
-        public MethodDescriptor<?, ?> getMethodDescriptor() {
-          return method;
-        }
-
-        @Override
-        public SecurityLevel getSecurityLevel() {
-          return securityLevel;
-        }
-
-        @Override
-        public String getAuthority() {
-          return authority;
-        }
-
-        @Override
-        public Attributes getTransportAttrs() {
-          return attrs;
-        }
-      };
-    applyRequestMetadata(requestInfo, appExecutor, applier);
-  }
+@Deprecated
+public abstract class CallCredentials2 extends CallCredentials {
 }
diff --git a/core/src/main/java/io/grpc/internal/CallCredentialsApplyingTransportFactory.java b/core/src/main/java/io/grpc/internal/CallCredentialsApplyingTransportFactory.java
index e5141cf..9195563 100644
--- a/core/src/main/java/io/grpc/internal/CallCredentialsApplyingTransportFactory.java
+++ b/core/src/main/java/io/grpc/internal/CallCredentialsApplyingTransportFactory.java
@@ -21,11 +21,13 @@
 
 import io.grpc.Attributes;
 import io.grpc.CallCredentials;
+import io.grpc.CallCredentials.RequestInfo;
 import io.grpc.CallOptions;
 import io.grpc.Metadata;
 import io.grpc.MethodDescriptor;
 import io.grpc.SecurityLevel;
 import io.grpc.Status;
+import io.grpc.internal.GrpcAttributes;
 import java.net.SocketAddress;
 import java.util.concurrent.Executor;
 import java.util.concurrent.ScheduledExecutorService;
@@ -72,23 +74,38 @@
     }
 
     @Override
-    @SuppressWarnings("deprecation")
     public ClientStream newStream(
-        MethodDescriptor<?, ?> method, Metadata headers, CallOptions callOptions) {
+        final MethodDescriptor<?, ?> method, Metadata headers, final CallOptions callOptions) {
       CallCredentials creds = callOptions.getCredentials();
       if (creds != null) {
+        final Attributes attrs = delegate.getAttributes();
         MetadataApplierImpl applier = new MetadataApplierImpl(
             delegate, method, headers, callOptions);
-        Attributes.Builder effectiveAttrsBuilder = Attributes.newBuilder()
-            .set(CallCredentials.ATTR_AUTHORITY, authority)
-            .set(CallCredentials.ATTR_SECURITY_LEVEL, SecurityLevel.NONE)
-            .setAll(delegate.getAttributes());
-        if (callOptions.getAuthority() != null) {
-          effectiveAttrsBuilder.set(CallCredentials.ATTR_AUTHORITY, callOptions.getAuthority());
-        }
+        RequestInfo requestInfo = new RequestInfo() {
+            @Override
+            public MethodDescriptor<?, ?> getMethodDescriptor() {
+              return method;
+            }
+
+            @Override
+            public SecurityLevel getSecurityLevel() {
+              return firstNonNull(
+                  attrs.get(GrpcAttributes.ATTR_SECURITY_LEVEL), SecurityLevel.NONE);
+            }
+
+            @Override
+            public String getAuthority() {
+              return firstNonNull(callOptions.getAuthority(), authority);
+            }
+
+            @Override
+            public Attributes getTransportAttrs() {
+              return attrs;
+            }
+          };
         try {
-          creds.applyRequestMetadata(method, effectiveAttrsBuilder.build(),
-              firstNonNull(callOptions.getExecutor(), appExecutor), applier);
+          creds.applyRequestMetadata(
+              requestInfo, firstNonNull(callOptions.getExecutor(), appExecutor), applier);
         } catch (Throwable t) {
           applier.fail(Status.UNAUTHENTICATED
               .withDescription("Credentials should use fail() instead of throwing exceptions")
diff --git a/core/src/main/java/io/grpc/internal/GrpcAttributes.java b/core/src/main/java/io/grpc/internal/GrpcAttributes.java
index 6a63864..574d9e6 100644
--- a/core/src/main/java/io/grpc/internal/GrpcAttributes.java
+++ b/core/src/main/java/io/grpc/internal/GrpcAttributes.java
@@ -54,10 +54,9 @@
    * The security level of the transport.  If it's not present, {@link SecurityLevel#NONE} should be
    * assumed.
    */
-  @SuppressWarnings("deprecation")
   @Grpc.TransportAttr
   public static final Attributes.Key<SecurityLevel> ATTR_SECURITY_LEVEL =
-      io.grpc.CallCredentials.ATTR_SECURITY_LEVEL;
+      Attributes.Key.create("io.grpc.internal.GrpcAttributes.securityLevel");
 
   private GrpcAttributes() {}
 }
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 587fac3..0000000
--- a/core/src/test/java/io/grpc/internal/CallCredentials2ApplyingTest.java
+++ /dev/null
@@ -1,290 +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.mockito.Matchers.any;
-import static org.mockito.Matchers.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.CallCredentials2;
-import io.grpc.CallOptions;
-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.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-/**
- * Unit test for {@link CallCredentials2} applying functionality implemented by {@link
- * CallCredentialsApplyingTransportFactory} and {@link MetadataApplierImpl}.
- */
-@RunWith(JUnit4.class)
-public class CallCredentials2ApplyingTest {
-  @Mock
-  private ClientTransportFactory mockTransportFactory;
-
-  @Mock
-  private ConnectionClientTransport mockTransport;
-
-  @Mock
-  private ClientStream mockStream;
-
-  @Mock
-  private CallCredentials2 mockCreds;
-
-  @Mock
-  private Executor mockExecutor;
-
-  @Mock
-  private SocketAddress address;
-
-  private static final String AUTHORITY = "testauthority";
-  private static final String USER_AGENT = "testuseragent";
-  private static final Attributes.Key<String> ATTR_KEY = Attributes.Key.create("somekey");
-  private static final String ATTR_VALUE = "somevalue";
-  private static final MethodDescriptor<String, Integer> method =
-      MethodDescriptor.<String, Integer>newBuilder()
-          .setType(MethodDescriptor.MethodType.UNKNOWN)
-          .setFullMethodName("service/method")
-          .setRequestMarshaller(new StringMarshaller())
-          .setResponseMarshaller(new IntegerMarshaller())
-          .build();
-  private static final Metadata.Key<String> 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<String> CREDS_KEY =
-      Metadata.Key.of("test-creds", Metadata.ASCII_STRING_MARSHALLER);
-  private static final String CREDS_VALUE = "some credentials";
-
-  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);
-
-    MockitoAnnotations.initMocks(this);
-    origHeaders.put(ORIG_HEADER_KEY, ORIG_HEADER_VALUE);
-    when(mockTransportFactory.newClientTransport(address, clientTransportOptions))
-        .thenReturn(mockTransport);
-    when(mockTransport.newStream(same(method), any(Metadata.class), any(CallOptions.class)))
-        .thenReturn(mockStream);
-    ClientTransportFactory transportFactory = new CallCredentialsApplyingTransportFactory(
-        mockTransportFactory, mockExecutor);
-    transport = (ForwardingConnectionClientTransport)
-        transportFactory.newClientTransport(address, clientTransportOptions);
-    callOptions = CallOptions.DEFAULT.withCallCredentials(mockCreds);
-    verify(mockTransportFactory).newClientTransport(address, clientTransportOptions);
-    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);
-
-    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(
-        infoCaptor.capture(), same(mockExecutor), any(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);
-
-    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(
-        infoCaptor.capture(), same(mockExecutor), any(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));
-
-    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(
-        infoCaptor.capture(), same(anotherExecutor), any(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(MetadataApplier.class));
-
-    FailingClientStream stream =
-        (FailingClientStream) transport.newStream(method, origHeaders, callOptions);
-
-    verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
-    assertEquals(Status.Code.UNAUTHENTICATED, stream.getError().getCode());
-    assertSame(ex, stream.getError().getCause());
-  }
-
-  @Test
-  public void applyMetadata_inline() {
-    when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
-    doAnswer(new Answer<Void>() {
-        @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(MetadataApplier.class));
-
-    ClientStream stream = transport.newStream(method, origHeaders, callOptions);
-
-    verify(mockTransport).newStream(method, origHeaders, callOptions);
-    assertSame(mockStream, stream);
-    assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
-    assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
-  }
-
-  @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<Void>() {
-        @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(MetadataApplier.class));
-
-    FailingClientStream stream =
-        (FailingClientStream) transport.newStream(method, origHeaders, callOptions);
-
-    verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
-    assertSame(error, stream.getError());
-  }
-
-  @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);
-
-    ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(
-        any(RequestInfo.class), same(mockExecutor), applierCaptor.capture());
-    verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
-
-    Metadata headers = new Metadata();
-    headers.put(CREDS_KEY, CREDS_VALUE);
-    applierCaptor.getValue().apply(headers);
-
-    verify(mockTransport).newStream(method, origHeaders, callOptions);
-    assertSame(mockStream, stream.getRealStream());
-    assertEquals(CREDS_VALUE, origHeaders.get(CREDS_KEY));
-    assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
-  }
-
-  @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);
-
-    ArgumentCaptor<MetadataApplier> 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(method, origHeaders, callOptions);
-    FailingClientStream failingStream = (FailingClientStream) stream.getRealStream();
-    assertSame(error, failingStream.getError());
-  }
-
-  @Test
-  public void noCreds() {
-    callOptions = callOptions.withCallCredentials(null);
-    ClientStream stream = transport.newStream(method, origHeaders, callOptions);
-
-    verify(mockTransport).newStream(method, origHeaders, callOptions);
-    assertSame(mockStream, stream);
-    assertNull(origHeaders.get(CREDS_KEY));
-    assertEquals(ORIG_HEADER_VALUE, origHeaders.get(ORIG_HEADER_KEY));
-  }
-}
diff --git a/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java b/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java
index 51df406..42cd8f9 100644
--- a/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java
+++ b/core/src/test/java/io/grpc/internal/CallCredentialsApplyingTest.java
@@ -31,6 +31,7 @@
 import io.grpc.Attributes;
 import io.grpc.CallCredentials;
 import io.grpc.CallCredentials.MetadataApplier;
+import io.grpc.CallCredentials.RequestInfo;
 import io.grpc.CallOptions;
 import io.grpc.IntegerMarshaller;
 import io.grpc.Metadata;
@@ -55,7 +56,6 @@
  * CallCredentialsApplyingTransportFactory} and {@link MetadataApplierImpl}.
  */
 @RunWith(JUnit4.class)
-@Deprecated
 public class CallCredentialsApplyingTest {
   @Mock
   private ClientTransportFactory mockTransportFactory;
@@ -126,41 +126,40 @@
 
     transport.newStream(method, origHeaders, callOptions);
 
-    ArgumentCaptor<Attributes> attrsCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(same(method), attrsCaptor.capture(), same(mockExecutor),
-        any(MetadataApplier.class));
-    Attributes attrs = attrsCaptor.getValue();
-    assertSame(ATTR_VALUE, attrs.get(ATTR_KEY));
-    assertSame(AUTHORITY, attrs.get(CallCredentials.ATTR_AUTHORITY));
-    assertSame(SecurityLevel.NONE, attrs.get(CallCredentials.ATTR_SECURITY_LEVEL));
+    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
+    verify(mockCreds).applyRequestMetadata(
+        infoCaptor.capture(), same(mockExecutor), any(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_overrideByTransport() {
+  public void parameterPropagation_transportSetSecurityLevel() {
     Attributes transportAttrs = Attributes.newBuilder()
         .set(ATTR_KEY, ATTR_VALUE)
-        .set(CallCredentials.ATTR_AUTHORITY, "transport-override-authority")
-        .set(CallCredentials.ATTR_SECURITY_LEVEL, SecurityLevel.INTEGRITY)
+        .set(GrpcAttributes.ATTR_SECURITY_LEVEL, SecurityLevel.INTEGRITY)
         .build();
     when(mockTransport.getAttributes()).thenReturn(transportAttrs);
 
     transport.newStream(method, origHeaders, callOptions);
 
-    ArgumentCaptor<Attributes> attrsCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(same(method), attrsCaptor.capture(), same(mockExecutor),
-        any(MetadataApplier.class));
-    Attributes attrs = attrsCaptor.getValue();
-    assertSame(ATTR_VALUE, attrs.get(ATTR_KEY));
-    assertEquals("transport-override-authority", attrs.get(CallCredentials.ATTR_AUTHORITY));
-    assertSame(SecurityLevel.INTEGRITY, attrs.get(CallCredentials.ATTR_SECURITY_LEVEL));
+    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
+    verify(mockCreds).applyRequestMetadata(
+        infoCaptor.capture(), same(mockExecutor), any(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_overrideByCallOptions() {
+  public void parameterPropagation_callOptionsSetAuthority() {
     Attributes transportAttrs = Attributes.newBuilder()
         .set(ATTR_KEY, ATTR_VALUE)
-        .set(CallCredentials.ATTR_AUTHORITY, "transport-override-authority")
-        .set(CallCredentials.ATTR_SECURITY_LEVEL, SecurityLevel.INTEGRITY)
         .build();
     when(mockTransport.getAttributes()).thenReturn(transportAttrs);
     Executor anotherExecutor = mock(Executor.class);
@@ -168,13 +167,14 @@
     transport.newStream(method, origHeaders,
         callOptions.withAuthority("calloptions-authority").withExecutor(anotherExecutor));
 
-    ArgumentCaptor<Attributes> attrsCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(same(method), attrsCaptor.capture(),
-        same(anotherExecutor), any(MetadataApplier.class));
-    Attributes attrs = attrsCaptor.getValue();
-    assertSame(ATTR_VALUE, attrs.get(ATTR_KEY));
-    assertEquals("calloptions-authority", attrs.get(CallCredentials.ATTR_AUTHORITY));
-    assertSame(SecurityLevel.INTEGRITY, attrs.get(CallCredentials.ATTR_SECURITY_LEVEL));
+    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
+    verify(mockCreds).applyRequestMetadata(
+        infoCaptor.capture(), same(anotherExecutor), any(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
@@ -182,7 +182,7 @@
     final RuntimeException ex = new RuntimeException();
     when(mockTransport.getAttributes()).thenReturn(Attributes.EMPTY);
     doThrow(ex).when(mockCreds).applyRequestMetadata(
-        same(method), any(Attributes.class), same(mockExecutor), any(MetadataApplier.class));
+        any(RequestInfo.class), same(mockExecutor), any(MetadataApplier.class));
 
     FailingClientStream stream =
         (FailingClientStream) transport.newStream(method, origHeaders, callOptions);
@@ -198,14 +198,14 @@
     doAnswer(new Answer<Void>() {
         @Override
         public Void answer(InvocationOnMock invocation) throws Throwable {
-          MetadataApplier applier = (MetadataApplier) invocation.getArguments()[3];
+          MetadataApplier applier = (MetadataApplier) invocation.getArguments()[2];
           Metadata headers = new Metadata();
           headers.put(CREDS_KEY, CREDS_VALUE);
           applier.apply(headers);
           return null;
         }
-      }).when(mockCreds).applyRequestMetadata(same(method), any(Attributes.class),
-          same(mockExecutor), any(MetadataApplier.class));
+      }).when(mockCreds).applyRequestMetadata(
+          any(RequestInfo.class), same(mockExecutor), any(MetadataApplier.class));
 
     ClientStream stream = transport.newStream(method, origHeaders, callOptions);
 
@@ -222,12 +222,12 @@
     doAnswer(new Answer<Void>() {
         @Override
         public Void answer(InvocationOnMock invocation) throws Throwable {
-          MetadataApplier applier = (MetadataApplier) invocation.getArguments()[3];
+          MetadataApplier applier = (MetadataApplier) invocation.getArguments()[2];
           applier.fail(error);
           return null;
         }
-      }).when(mockCreds).applyRequestMetadata(same(method), any(Attributes.class),
-          same(mockExecutor), any(MetadataApplier.class));
+      }).when(mockCreds).applyRequestMetadata(
+          any(RequestInfo.class), same(mockExecutor), any(MetadataApplier.class));
 
     FailingClientStream stream =
         (FailingClientStream) transport.newStream(method, origHeaders, callOptions);
@@ -244,8 +244,8 @@
     DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions);
 
     ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(same(method), any(Attributes.class),
-        same(mockExecutor), applierCaptor.capture());
+    verify(mockCreds).applyRequestMetadata(
+        any(RequestInfo.class), same(mockExecutor), applierCaptor.capture());
     verify(mockTransport, never()).newStream(method, origHeaders, callOptions);
 
     Metadata headers = new Metadata();
@@ -266,8 +266,8 @@
     DelayedStream stream = (DelayedStream) transport.newStream(method, origHeaders, callOptions);
 
     ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(null);
-    verify(mockCreds).applyRequestMetadata(same(method), any(Attributes.class),
-        same(mockExecutor), applierCaptor.capture());
+    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);
diff --git a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java
index a112ae7..18ffc13 100644
--- a/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java
+++ b/core/src/test/java/io/grpc/internal/ManagedChannelImplTest.java
@@ -59,6 +59,7 @@
 import io.grpc.BinaryLog;
 import io.grpc.CallCredentials;
 import io.grpc.CallCredentials.MetadataApplier;
+import io.grpc.CallCredentials.RequestInfo;
 import io.grpc.CallOptions;
 import io.grpc.Channel;
 import io.grpc.ClientCall;
@@ -1389,7 +1390,6 @@
    * propagated to newStream() and applyRequestMetadata().
    */
   @Test
-  @SuppressWarnings("deprecation")
   public void informationPropagatedToNewStreamAndCallCredentials() {
     createChannel();
     CallOptions callOptions = CallOptions.DEFAULT.withCallCredentials(creds);
@@ -1403,9 +1403,8 @@
           credsApplyContexts.add(Context.current());
           return null;
         }
-      }).when(creds).applyRequestMetadata(  // TODO(zhangkun83): remove suppression of deprecations
-          any(MethodDescriptor.class), any(Attributes.class), any(Executor.class),
-          any(MetadataApplier.class));
+      }).when(creds).applyRequestMetadata(
+          any(RequestInfo.class), any(Executor.class), any(MetadataApplier.class));
 
     // First call will be on delayed transport.  Only newCall() is run within the expected context,
     // so that we can verify that the context is explicitly attached before calling newStream() and
@@ -1436,8 +1435,7 @@
           any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
 
     verify(creds, never()).applyRequestMetadata(
-        any(MethodDescriptor.class), any(Attributes.class), any(Executor.class),
-        any(MetadataApplier.class));
+        any(RequestInfo.class), any(Executor.class), any(MetadataApplier.class));
 
     // applyRequestMetadata() is called after the transport becomes ready.
     transportInfo.listener.transportReady();
@@ -1445,14 +1443,15 @@
         .thenReturn(PickResult.withSubchannel(subchannel));
     helper.updateBalancingState(READY, mockPicker);
     executor.runDueTasks();
-    ArgumentCaptor<Attributes> attrsCaptor = ArgumentCaptor.forClass(Attributes.class);
+    ArgumentCaptor<RequestInfo> infoCaptor = ArgumentCaptor.forClass(null);
     ArgumentCaptor<MetadataApplier> applierCaptor = ArgumentCaptor.forClass(MetadataApplier.class);
-    verify(creds).applyRequestMetadata(same(method), attrsCaptor.capture(),
+    verify(creds).applyRequestMetadata(infoCaptor.capture(),
         same(executor.getScheduledExecutorService()), applierCaptor.capture());
+    RequestInfo info = infoCaptor.getValue();
+    assertSame(method, info.getMethodDescriptor());
     assertEquals("testValue", testKey.get(credsApplyContexts.poll()));
-    assertEquals(AUTHORITY, attrsCaptor.getValue().get(CallCredentials.ATTR_AUTHORITY));
-    assertEquals(SecurityLevel.NONE,
-        attrsCaptor.getValue().get(CallCredentials.ATTR_SECURITY_LEVEL));
+    assertEquals(AUTHORITY, info.getAuthority());
+    assertEquals(SecurityLevel.NONE, info.getSecurityLevel());
     verify(transport, never()).newStream(
         any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));
 
@@ -1470,12 +1469,13 @@
     ctx.detach(origCtx);
     call.start(mockCallListener, new Metadata());
 
-    verify(creds, times(2)).applyRequestMetadata(same(method), attrsCaptor.capture(),
+    verify(creds, times(2)).applyRequestMetadata(infoCaptor.capture(),
         same(executor.getScheduledExecutorService()), applierCaptor.capture());
+    info = infoCaptor.getValue();
+    assertSame(method, info.getMethodDescriptor());
     assertEquals("testValue", testKey.get(credsApplyContexts.poll()));
-    assertEquals(AUTHORITY, attrsCaptor.getValue().get(CallCredentials.ATTR_AUTHORITY));
-    assertEquals(SecurityLevel.NONE,
-        attrsCaptor.getValue().get(CallCredentials.ATTR_SECURITY_LEVEL));
+    assertEquals(AUTHORITY, info.getAuthority());
+    assertEquals(SecurityLevel.NONE, info.getSecurityLevel());
     // This is from the first call
     verify(transport).newStream(
         any(MethodDescriptor.class), any(Metadata.class), any(CallOptions.class));