diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/AuthCallable.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/AuthCallable.java new file mode 100644 index 000000000..b6417ffba --- /dev/null +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/AuthCallable.java @@ -0,0 +1,59 @@ +/* + * Copyright 2017, 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 com.google.api.gax.grpc; + +import com.google.api.core.ApiFuture; +import com.google.auth.Credentials; +import com.google.common.base.Preconditions; +import io.grpc.CallCredentials; +import io.grpc.auth.MoreCallCredentials; + +/** + * Implements the credential insertion for {@link UnaryCallable}. + * + *

Package-private for internal use. + */ +class AuthCallable implements FutureCallable { + private final FutureCallable callable; + private final CallCredentials credentials; + + AuthCallable(FutureCallable callable, Credentials credentials) { + this.callable = Preconditions.checkNotNull(callable); + this.credentials = MoreCallCredentials.from(Preconditions.checkNotNull(credentials)); + } + + @Override + public ApiFuture futureCall(RequestT request, CallContext context) { + if (context.getCallOptions().getCredentials() == null) { + context = context.withCallOptions(context.getCallOptions().withCallCredentials(credentials)); + } + return callable.futureCall(request, context); + } +} diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/BatchingCallSettings.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/BatchingCallSettings.java index b413f1bf8..7a2749e2d 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/BatchingCallSettings.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/BatchingCallSettings.java @@ -34,11 +34,9 @@ import com.google.api.gax.retrying.RetrySettings; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; -import io.grpc.Channel; import io.grpc.MethodDescriptor; import io.grpc.Status; import java.util.Set; -import java.util.concurrent.ScheduledExecutorService; /** * A settings class to configure a UnaryCallable for calls to an API method that supports batching. @@ -52,9 +50,10 @@ public final class BatchingCallSettings private BatcherFactory batcherFactory; /** Package-private, for use by UnaryCallable. */ - UnaryCallable create(Channel channel, ScheduledExecutorService executor) { - UnaryCallable baseCallable = createBaseCallable(channel, executor); - batcherFactory = new BatcherFactory<>(batchingDescriptor, batchingSettings, executor); + UnaryCallable create(ClientContext context) { + UnaryCallable baseCallable = createBaseCallable(context); + batcherFactory = + new BatcherFactory<>(batchingDescriptor, batchingSettings, context.getExecutor()); return baseCallable.batching(batchingDescriptor, batcherFactory); } diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/ChannelAndExecutor.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/ChannelAndExecutor.java index 5eb58b542..60b38f3d9 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/ChannelAndExecutor.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/ChannelAndExecutor.java @@ -41,6 +41,7 @@ */ @BetaApi @AutoValue +@Deprecated public abstract class ChannelAndExecutor { public abstract ScheduledExecutorService getExecutor(); diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/ClientContext.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/ClientContext.java new file mode 100644 index 000000000..c95cac8dc --- /dev/null +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/ClientContext.java @@ -0,0 +1,116 @@ +/* + * Copyright 2017, 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 com.google.api.gax.grpc; + +import com.google.api.core.BetaApi; +import com.google.auth.Credentials; +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableList; +import io.grpc.Channel; +import io.grpc.ManagedChannel; +import java.io.IOException; +import java.util.Collection; +import java.util.concurrent.ScheduledExecutorService; +import javax.annotation.Nullable; + +/** + * Encapsulates client state, including channel, executor, and credentials. + * + *

Unlike {@link ClientSettings} which allows users to configure the client, {@code + * ClientContext} is intended to be used in generated code. Most users will not need to use it. + */ +@BetaApi +@AutoValue +public abstract class ClientContext { + public abstract Collection getCloseables(); + + public abstract Channel getChannel(); + + public abstract ScheduledExecutorService getExecutor(); + + @Nullable + public abstract Credentials getCredentials(); + + static Builder newBuilder() { + return new AutoValue_ClientContext.Builder(); + } + + public static ClientContext create(ClientSettings settings) throws IOException { + ImmutableList.Builder closeables = ImmutableList.builder(); + + ExecutorProvider executorProvider = settings.getExecutorProvider(); + final ScheduledExecutorService executor = executorProvider.getExecutor(); + if (executorProvider.shouldAutoClose()) { + closeables.add( + new AutoCloseable() { + @Override + public void close() { + executor.shutdown(); + } + }); + } + + final ManagedChannel channel; + ChannelProvider channelProvider = settings.getChannelProvider(); + if (channelProvider.needsExecutor()) { + channel = channelProvider.getChannel(executor); + } else { + channel = channelProvider.getChannel(); + } + if (channelProvider.shouldAutoClose()) { + closeables.add( + new AutoCloseable() { + @Override + public void close() { + channel.shutdown(); + } + }); + } + return newBuilder() + .setCloseables(closeables.build()) + .setChannel(channel) + .setExecutor(executor) + .setCredentials(settings.getCredentialsProvider().getCredentials()) + .build(); + } + + @AutoValue.Builder + abstract static class Builder { + public abstract Builder setCloseables(Collection value); + + public abstract Builder setChannel(Channel value); + + public abstract Builder setExecutor(ScheduledExecutorService value); + + public abstract Builder setCredentials(Credentials value); + + public abstract ClientContext build(); + } +} diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/ClientSettings.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/ClientSettings.java index fc1d3a5f6..86ba65bc8 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/ClientSettings.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/ClientSettings.java @@ -30,10 +30,14 @@ package com.google.api.gax.grpc; import com.google.api.core.BetaApi; +import com.google.api.gax.core.CredentialsProvider; +import com.google.api.gax.core.NoCredentialsProvider; import com.google.api.gax.retrying.RetrySettings; +import com.google.common.base.MoreObjects; import io.grpc.Status; import java.io.IOException; import java.util.Set; +import javax.annotation.Nullable; /** * A base settings class to configure a service API class. @@ -65,14 +69,25 @@ public abstract class ClientSettings { private final ExecutorProvider executorProvider; private final ChannelProvider channelProvider; + @Nullable private final CredentialsProvider credentialsProvider; - /** Constructs an instance of ClientSettings. */ + @Deprecated protected ClientSettings(ExecutorProvider executorProvider, ChannelProvider channelProvider) { + this(executorProvider, channelProvider, null); + } + + /** Constructs an instance of ClientSettings. */ + protected ClientSettings( + ExecutorProvider executorProvider, + ChannelProvider channelProvider, + CredentialsProvider credentialsProvider) { this.executorProvider = executorProvider; this.channelProvider = channelProvider; + this.credentialsProvider = credentialsProvider; } /** Gets a channel and an executor for making calls. */ + @Deprecated public final ChannelAndExecutor getChannelAndExecutor() throws IOException { return ChannelAndExecutor.create(executorProvider, channelProvider); } @@ -85,20 +100,36 @@ public final ChannelProvider getChannelProvider() { return channelProvider; } + @Nullable + public final CredentialsProvider getCredentialsProvider() { + return credentialsProvider; + } + + public String toString() { + return MoreObjects.toStringHelper(this) + .add("executorProvider", executorProvider) + .add("channelProvider", channelProvider) + .add("credentialsProvider", credentialsProvider) + .toString(); + } + public abstract static class Builder { private ExecutorProvider executorProvider; private ChannelProvider channelProvider; + private CredentialsProvider credentialsProvider; /** Create a builder from a ClientSettings object. */ protected Builder(ClientSettings settings) { this.executorProvider = settings.executorProvider; this.channelProvider = settings.channelProvider; + this.credentialsProvider = settings.credentialsProvider; } protected Builder(InstantiatingChannelProvider channelProvider) { this.executorProvider = InstantiatingExecutorProvider.newBuilder().build(); this.channelProvider = channelProvider; + this.credentialsProvider = new NoCredentialsProvider(); } /** @@ -118,6 +149,12 @@ public Builder setChannelProvider(ChannelProvider channelProvider) { return this; } + /** Sets the CredentialsProvider to use for getting the channel to make calls with. */ + public Builder setCredentialsProvider(CredentialsProvider credentialsProvider) { + this.credentialsProvider = credentialsProvider; + return this; + } + /** Gets the ExecutorProvider that was previously set on this Builder. */ public ExecutorProvider getExecutorProvider() { return executorProvider; @@ -128,6 +165,11 @@ public ChannelProvider getChannelProvider() { return channelProvider; } + /** Gets the CredentialsProvider that was previously set on this Builder. */ + public CredentialsProvider getCredentialsProvider() { + return credentialsProvider; + } + /** Performs a merge, using only non-null fields */ protected Builder applyToAllUnaryMethods( Iterable methodSettingsBuilders, @@ -148,5 +190,13 @@ protected Builder applyToAllUnaryMethods( } public abstract ClientSettings build() throws IOException; + + public String toString() { + return MoreObjects.toStringHelper(this) + .add("executorProvider", executorProvider) + .add("channelProvider", channelProvider) + .add("credentialsProvider", credentialsProvider) + .toString(); + } } } diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingChannelProvider.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingChannelProvider.java index 45e8d210f..09fedace9 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingChannelProvider.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/InstantiatingChannelProvider.java @@ -139,6 +139,7 @@ private ManagedChannel createChannel(Executor executor) throws IOException { * Gets the credentials which will be used to call the service. If the credentials have not been * acquired yet, then they will be acquired when this function is called. */ + @Deprecated public Credentials getCredentials() throws IOException { return getCredentialsProvider().getCredentials(); } @@ -147,6 +148,7 @@ public Credentials getCredentials() throws IOException { * The credentials to use in order to call the service. Credentials will not be acquired until * they are required. */ + @Deprecated public CredentialsProvider getCredentialsProvider() { return credentialsProvider; } @@ -261,12 +263,14 @@ public Builder setExecutorProvider(ExecutorProvider executorProvider) { * Sets the CredentialsProvider which will acquire the credentials for making calls to the * service. Credentials will not be acquired until they are required. */ + @Deprecated public Builder setCredentialsProvider(CredentialsProvider credentialsProvider) { this.credentialsProvider = credentialsProvider; return this; } /** The previously set CredentialsProvider. */ + @Deprecated public CredentialsProvider getCredentialsProvider() { return credentialsProvider; } diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallSettings.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallSettings.java index 4ea687d82..4096bd94c 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallSettings.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallSettings.java @@ -33,9 +33,7 @@ import com.google.longrunning.Operation; import com.google.longrunning.OperationsClient; import com.google.protobuf.Message; -import io.grpc.Channel; import io.grpc.MethodDescriptor; -import java.util.concurrent.ScheduledExecutorService; import org.threeten.bp.Duration; /** @@ -59,12 +57,10 @@ public final Duration getPollingInterval() { // package-private for internal use. OperationCallable createOperationCallable( - Channel channel, ScheduledExecutorService executor, OperationsClient operationsClient) { - UnaryCallable initialCallable = - initialCallSettings.create(channel, executor); + ClientContext context, OperationsClient operationsClient) { + UnaryCallable initialCallable = initialCallSettings.create(context); OperationCallable operationCallable = - new OperationCallable<>( - initialCallable, channel, executor, operationsClient, responseClass, this); + new OperationCallable<>(initialCallable, context, operationsClient, responseClass, this); return operationCallable; } diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallable.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallable.java index 5c0d5a26e..c0765baca 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallable.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/OperationCallable.java @@ -48,8 +48,7 @@ @BetaApi public final class OperationCallable { private final UnaryCallable initialCallable; - private final Channel channel; - private final ScheduledExecutorService executor; + private final ClientContext clientContext; private final OperationsClient operationsClient; private final Class responseClass; private final OperationCallSettings settings; @@ -57,53 +56,49 @@ public final class OperationCallable { /** Package-private for internal use. */ OperationCallable( UnaryCallable initialCallable, - Channel channel, - ScheduledExecutorService executor, + ClientContext clientContext, OperationsClient operationsClient, Class responseClass, OperationCallSettings settings) { this.initialCallable = Preconditions.checkNotNull(initialCallable); - this.channel = channel; - this.executor = executor; + this.clientContext = clientContext; this.operationsClient = operationsClient; this.responseClass = responseClass; this.settings = settings; } - /** - * Create an OperationCallable with a bound channel. If a call is made without specifying a - * channel, the {@code boundChannel} is used instead. - * - *

Package-private for internal use. - */ - OperationCallable bind(Channel boundChannel) { - return new OperationCallable<>( - initialCallable, boundChannel, executor, operationsClient, responseClass, settings); - } - /** * Creates a callable object that represents a long-running operation. Public only for technical * reasons - for advanced usage * * @param operationCallSettings {@link com.google.api.gax.grpc.OperationCallSettings} to configure * the method-level settings with. - * @param channel {@link Channel} to use to connect to the service. - * @param executor {@link ScheduledExecutorService} to use to schedule polling work. + * @param clientContext {@link ClientContext} to use to connect to the service. * @param operationsClient {@link OperationsClient} to use to poll for updates on the Operation. * @return {@link com.google.api.gax.grpc.OperationCallable} callable object. */ + public static OperationCallable create( + OperationCallSettings operationCallSettings, + ClientContext clientContext, + OperationsClient operationsClient) { + return operationCallSettings.createOperationCallable(clientContext, operationsClient); + } + + @Deprecated public static OperationCallable create( OperationCallSettings operationCallSettings, Channel channel, ScheduledExecutorService executor, OperationsClient operationsClient) { - return operationCallSettings.createOperationCallable(channel, executor, operationsClient); + return operationCallSettings.createOperationCallable( + ClientContext.newBuilder().setChannel(channel).setExecutor(executor).build(), + operationsClient); } /** * Initiates an operation asynchronously. If the {@link io.grpc.Channel} encapsulated in the given - * {@link com.google.api.gax.grpc.CallContext} is null, a channel must have already been bound - * either at construction time or using {@link #bind(Channel)}. + * {@link com.google.api.gax.grpc.CallContext} is null, a channel must have already been bound at + * construction time. * * @param request The request to initiate the operation. * @param context {@link com.google.api.gax.grpc.CallContext} to make the call with @@ -111,14 +106,18 @@ public static OperationCallable futureCall(RequestT request, CallContext context) { if (context.getChannel() == null) { - context = context.withChannel(channel); + context = context.withChannel(clientContext.getChannel()); } ApiFuture initialCallFuture = initialCallable.futureCall(request, context); Duration pollingInterval = settings != null ? settings.getPollingInterval() : OperationFuture.DEFAULT_POLLING_INTERVAL; OperationFuture operationFuture = OperationFuture.create( - operationsClient, initialCallFuture, executor, responseClass, pollingInterval); + operationsClient, + initialCallFuture, + clientContext.getExecutor(), + responseClass, + pollingInterval); return operationFuture; } @@ -130,13 +129,13 @@ public OperationFuture futureCall(RequestT request, CallContext conte * @return {@link OperationFuture} for the call result */ public OperationFuture futureCall(RequestT request) { - return futureCall(request, CallContext.createDefault().withChannel(channel)); + return futureCall(request, CallContext.createDefault().withChannel(clientContext.getChannel())); } /** * Initiates an operation and polls for the final result. If the {@link io.grpc.Channel} * encapsulated in the given {@link com.google.api.gax.grpc.CallContext} is null, a channel must - * have already been bound, using {@link #bind(Channel)}. + * have already been bound at construction time. * * @param request The request to initiate the operation. * @param context {@link com.google.api.gax.grpc.CallContext} to make the call with @@ -175,7 +174,8 @@ public OperationFuture resumeFutureCall(String operationName) { .getOperationCallable() .futureCall(GetOperationRequest.newBuilder().setName(operationName).build()); OperationFuture operationFuture = - OperationFuture.create(operationsClient, getOperationFuture, executor, responseClass); + OperationFuture.create( + operationsClient, getOperationFuture, clientContext.getExecutor(), responseClass); return operationFuture; } } diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/PagedCallSettings.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/PagedCallSettings.java index 0fbdc701f..15edcc026 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/PagedCallSettings.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/PagedCallSettings.java @@ -32,11 +32,9 @@ import com.google.api.core.BetaApi; import com.google.api.gax.retrying.RetrySettings; import com.google.common.collect.ImmutableSet; -import io.grpc.Channel; import io.grpc.MethodDescriptor; import io.grpc.Status; import java.util.Set; -import java.util.concurrent.ScheduledExecutorService; /** * A settings class to configure a UnaryCallable for calls to an API method that supports page @@ -49,14 +47,13 @@ public final class PagedCallSettings pagedListResponseFactory; /** Package-private, for use by UnaryCallable. */ - UnaryCallable create(Channel channel, ScheduledExecutorService executor) { - return createBaseCallable(channel, executor); + UnaryCallable create(ClientContext context) { + return createBaseCallable(context); } /** Package-private, for use by UnaryCallable. */ - UnaryCallable createPagedVariant( - Channel channel, ScheduledExecutorService executor) { - UnaryCallable baseCallable = createBaseCallable(channel, executor); + UnaryCallable createPagedVariant(ClientContext context) { + UnaryCallable baseCallable = createBaseCallable(context); return baseCallable.paged(pagedListResponseFactory); } diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/SimpleCallSettings.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/SimpleCallSettings.java index 02e50bfeb..1255127f4 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/SimpleCallSettings.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/SimpleCallSettings.java @@ -32,11 +32,9 @@ import com.google.api.core.BetaApi; import com.google.api.gax.retrying.RetrySettings; import com.google.common.collect.ImmutableSet; -import io.grpc.Channel; import io.grpc.MethodDescriptor; import io.grpc.Status; import java.util.Set; -import java.util.concurrent.ScheduledExecutorService; /** * A settings class to configure a UnaryCallable for calls to a simple API method (i.e. that doesn't @@ -47,8 +45,8 @@ public final class SimpleCallSettings extends UnaryCallSettingsTyped { /** Package-private, for use by UnaryCallable. */ - UnaryCallable create(Channel channel, ScheduledExecutorService executor) { - return createBaseCallable(channel, executor); + UnaryCallable create(ClientContext context) { + return createBaseCallable(context); } private SimpleCallSettings( diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallSettingsTyped.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallSettingsTyped.java index 1a4799567..60c259c8e 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallSettingsTyped.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallSettingsTyped.java @@ -32,10 +32,8 @@ import com.google.api.core.BetaApi; import com.google.api.gax.retrying.RetrySettings; import com.google.common.collect.ImmutableSet; -import io.grpc.Channel; import io.grpc.MethodDescriptor; import io.grpc.Status; -import java.util.concurrent.ScheduledExecutorService; /** * A settings class with generic typing configure a UnaryCallable. @@ -67,18 +65,19 @@ protected UnaryCallSettingsTyped( this.methodDescriptor = methodDescriptor; } - protected UnaryCallable createBaseCallable( - Channel channel, ScheduledExecutorService executor) { + protected UnaryCallable createBaseCallable(ClientContext context) { ClientCallFactory clientCallFactory = new DescriptorClientCallFactory<>(methodDescriptor); UnaryCallable callable = - new UnaryCallable<>(new DirectCallable<>(clientCallFactory), channel, this); + new UnaryCallable<>(new DirectCallable<>(clientCallFactory), context.getChannel(), this); if (getRetryableCodes() != null) { callable = callable.retryableOn(ImmutableSet.copyOf(getRetryableCodes())); } if (getRetrySettings() != null) { - callable = callable.retrying(getRetrySettings(), executor); + callable = callable.retrying(getRetrySettings(), context.getExecutor()); } + // withAuth works properly even if getCredentials returns null. + callable = callable.withAuth(context.getCredentials()); return callable; } diff --git a/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallable.java b/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallable.java index df3e79c59..9649176ff 100644 --- a/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallable.java +++ b/gax-grpc/src/main/java/com/google/api/gax/grpc/UnaryCallable.java @@ -35,6 +35,7 @@ import com.google.api.core.NanoClock; import com.google.api.gax.batching.BatchingSettings; import com.google.api.gax.retrying.RetrySettings; +import com.google.auth.Credentials; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableSet; @@ -95,6 +96,20 @@ public final class UnaryCallable { private final Channel channel; @Nullable private final UnaryCallSettings settings; + /** + * Create a callable object that represents a simple API method. Public only for technical reasons + * - for advanced usage + * + * @param simpleCallSettings {@link com.google.api.gax.grpc.SimpleCallSettings} to configure the + * method-level settings with. + * @param context {@link ClientContext} to use to connect to the service. + * @return {@link com.google.api.gax.grpc.UnaryCallable} callable object. + */ + public static UnaryCallable create( + SimpleCallSettings simpleCallSettings, ClientContext context) { + return simpleCallSettings.create(context); + } + /** * Create a callable object that represents a simple API method. Public only for technical reasons * - for advanced usage @@ -105,11 +120,29 @@ public final class UnaryCallable { * @param executor {@link ScheduledExecutorService} to use when connecting to the service. * @return {@link com.google.api.gax.grpc.UnaryCallable} callable object. */ + @Deprecated public static UnaryCallable create( SimpleCallSettings simpleCallSettings, Channel channel, ScheduledExecutorService executor) { - return simpleCallSettings.create(channel, executor); + return simpleCallSettings.create( + ClientContext.newBuilder().setChannel(channel).setExecutor(executor).build()); + } + + /** + * Create a paged callable object that represents a paged API method. Public only for technical + * reasons - for advanced usage + * + * @param PagedCallSettings {@link com.google.api.gax.grpc.PagedCallSettings} to configure the + * paged settings with. + * @param context {@link ClientContext} to use to connect to the service. + * @return {@link com.google.api.gax.grpc.UnaryCallable} callable object. + */ + public static + UnaryCallable createPagedVariant( + PagedCallSettings PagedCallSettings, + ClientContext context) { + return PagedCallSettings.createPagedVariant(context); } /** @@ -122,12 +155,29 @@ public static UnaryCallable create( * @param executor {@link ScheduledExecutorService} to use to when connecting to the service. * @return {@link com.google.api.gax.grpc.UnaryCallable} callable object. */ + @Deprecated public static UnaryCallable createPagedVariant( PagedCallSettings PagedCallSettings, Channel channel, ScheduledExecutorService executor) { - return PagedCallSettings.createPagedVariant(channel, executor); + return PagedCallSettings.createPagedVariant( + ClientContext.newBuilder().setChannel(channel).setExecutor(executor).build()); + } + + /** + * Create a base callable object that represents a paged API method. Public only for technical + * reasons - for advanced usage + * + * @param PagedCallSettings {@link com.google.api.gax.grpc.PagedCallSettings} to configure the + * paged settings with. + * @param context {@link ClientContext} to use to connect to the service. + * @return {@link com.google.api.gax.grpc.UnaryCallable} callable object. + */ + public static UnaryCallable create( + PagedCallSettings PagedCallSettings, + ClientContext context) { + return PagedCallSettings.create(context); } /** @@ -140,11 +190,27 @@ UnaryCallable createPagedVariant( * @param executor {@link ScheduledExecutorService} to use to when connecting to the service. * @return {@link com.google.api.gax.grpc.UnaryCallable} callable object. */ + @Deprecated public static UnaryCallable create( PagedCallSettings PagedCallSettings, Channel channel, ScheduledExecutorService executor) { - return PagedCallSettings.create(channel, executor); + return PagedCallSettings.create( + ClientContext.newBuilder().setChannel(channel).setExecutor(executor).build()); + } + + /** + * Create a callable object that represents a batching API method. Public only for technical + * reasons - for advanced usage + * + * @param batchingCallSettings {@link BatchingSettings} to configure the batching related settings + * with. + * @param context {@link ClientContext} to use to connect to the service. + * @return {@link com.google.api.gax.grpc.UnaryCallable} callable object. + */ + public static UnaryCallable create( + BatchingCallSettings batchingCallSettings, ClientContext context) { + return batchingCallSettings.create(context); } /** @@ -157,11 +223,13 @@ public static UnaryCallable UnaryCallable create( BatchingCallSettings batchingCallSettings, Channel channel, ScheduledExecutorService executor) { - return batchingCallSettings.create(channel, executor); + return batchingCallSettings.create( + ClientContext.newBuilder().setChannel(channel).setExecutor(executor).build()); } /** @@ -328,4 +396,11 @@ UnaryCallable batching( return new UnaryCallable<>( new BatchingCallable<>(callable, batchingDescriptor, batcherFactory), channel, settings); } + + UnaryCallable withAuth(Credentials credentials) { + if (credentials == null) { + return this; + } + return new UnaryCallable<>(new AuthCallable<>(callable, credentials), channel, settings); + } } diff --git a/gax-grpc/src/main/java/com/google/longrunning/OperationsClient.java b/gax-grpc/src/main/java/com/google/longrunning/OperationsClient.java index a5bd46890..f85b26292 100644 --- a/gax-grpc/src/main/java/com/google/longrunning/OperationsClient.java +++ b/gax-grpc/src/main/java/com/google/longrunning/OperationsClient.java @@ -31,16 +31,13 @@ import static com.google.longrunning.PagedResponseWrappers.ListOperationsPagedResponse; -import com.google.api.gax.grpc.ChannelAndExecutor; +import com.google.api.core.BetaApi; +import com.google.api.gax.grpc.ClientContext; import com.google.api.gax.grpc.UnaryCallable; import com.google.protobuf.Empty; -import com.google.protobuf.ExperimentalApi; -import io.grpc.ManagedChannel; -import java.io.Closeable; import java.io.IOException; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.ScheduledExecutorService; import javax.annotation.Generated; // AUTO-GENERATED DOCUMENTATION AND SERVICE @@ -73,13 +70,13 @@ * methods: * *

    - *
  1. A "flattened" method. With this type of method, the fields of the request type have been + *
  2. A "flattened" method. With this type of method, the fields of the request type have been * converted into function parameters. It may be the case that not all fields are available as * parameters, and not every API method will have a flattened method entry point. - *
  3. A "request object" method. This type of method only takes one parameter, a request object, + *
  4. A "request object" method. This type of method only takes one parameter, a request object, * which must be constructed before the call. Not every API method will have a request object * method. - *
  5. A "callable" method. This type of method takes no parameters and returns an immutable API + *
  6. A "callable" method. This type of method takes no parameters and returns an immutable API * callable object, which can be used to initiate calls to the service. *
* @@ -94,23 +91,19 @@ * *
  * 
- * InstantiatingChannelProvider channelProvider =
- *     OperationsSettings.defaultChannelProviderBuilder()
+ * OperationsSettings operationsSettings =
+ *     OperationsSettings.defaultBuilder()
  *         .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
  *         .build();
- * OperationsSettings operationsSettings =
- *     OperationsSettings.defaultBuilder().setChannelProvider(channelProvider).build();
  * OperationsClient operationsClient =
  *     OperationsClient.create(operationsSettings);
  * 
  * 
*/ @Generated("by GAPIC") -@ExperimentalApi +@BetaApi public class OperationsClient implements AutoCloseable { private final OperationsSettings settings; - private final ScheduledExecutorService executor; - private final ManagedChannel channel; private final List closeables = new ArrayList<>(); private final UnaryCallable getOperationCallable; @@ -134,40 +127,21 @@ public static final OperationsClient create(OperationsSettings settings) throws */ protected OperationsClient(OperationsSettings settings) throws IOException { this.settings = settings; - ChannelAndExecutor channelAndExecutor = settings.getChannelAndExecutor(); - this.executor = channelAndExecutor.getExecutor(); - this.channel = channelAndExecutor.getChannel(); + + ClientContext clientContext = ClientContext.create(settings); this.getOperationCallable = - UnaryCallable.create(settings.getOperationSettings(), this.channel, this.executor); + UnaryCallable.create(settings.getOperationSettings(), clientContext); this.listOperationsCallable = - UnaryCallable.create(settings.listOperationsSettings(), this.channel, this.executor); + UnaryCallable.create(settings.listOperationsSettings(), clientContext); this.listOperationsPagedCallable = - UnaryCallable.createPagedVariant( - settings.listOperationsSettings(), this.channel, this.executor); + UnaryCallable.createPagedVariant(settings.listOperationsSettings(), clientContext); this.cancelOperationCallable = - UnaryCallable.create(settings.cancelOperationSettings(), this.channel, this.executor); + UnaryCallable.create(settings.cancelOperationSettings(), clientContext); this.deleteOperationCallable = - UnaryCallable.create(settings.deleteOperationSettings(), this.channel, this.executor); + UnaryCallable.create(settings.deleteOperationSettings(), clientContext); - if (settings.getChannelProvider().shouldAutoClose()) { - closeables.add( - new Closeable() { - @Override - public void close() throws IOException { - channel.shutdown(); - } - }); - } - if (settings.getExecutorProvider().shouldAutoClose()) { - closeables.add( - new Closeable() { - @Override - public void close() throws IOException { - executor.shutdown(); - } - }); - } + closeables.addAll(clientContext.getCloseables()); } public final OperationsSettings getSettings() { diff --git a/gax-grpc/src/main/java/com/google/longrunning/OperationsSettings.java b/gax-grpc/src/main/java/com/google/longrunning/OperationsSettings.java index 1993cf41d..a2233f4df 100644 --- a/gax-grpc/src/main/java/com/google/longrunning/OperationsSettings.java +++ b/gax-grpc/src/main/java/com/google/longrunning/OperationsSettings.java @@ -32,6 +32,8 @@ import static com.google.longrunning.PagedResponseWrappers.ListOperationsPagedResponse; import com.google.api.core.ApiFuture; +import com.google.api.core.BetaApi; +import com.google.api.gax.core.CredentialsProvider; import com.google.api.gax.core.GoogleCredentialsProvider; import com.google.api.gax.core.PropertiesProvider; import com.google.api.gax.grpc.CallContext; @@ -54,7 +56,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.protobuf.Empty; -import com.google.protobuf.ExperimentalApi; import io.grpc.Status; import java.io.IOException; import javax.annotation.Generated; @@ -63,7 +64,7 @@ // AUTO-GENERATED DOCUMENTATION AND CLASS /** Settings class to configure an instance of {@link OperationsClient}. */ @Generated("by GAPIC v0.0.5") -@ExperimentalApi +@BetaApi public class OperationsSettings extends ClientSettings { private static final String DEFAULT_GAPIC_NAME = "gapic"; @@ -145,8 +146,7 @@ public static GoogleCredentialsProvider.Builder defaultCredentialsProviderBuilde /** Returns a builder for the default ChannelProvider for this service. */ public static InstantiatingChannelProvider.Builder defaultChannelProviderBuilder() { return InstantiatingChannelProvider.newBuilder() - .setGeneratorHeader(DEFAULT_GAPIC_NAME, getGapicVersion()) - .setCredentialsProvider(defaultCredentialsProviderBuilder().build()); + .setGeneratorHeader(DEFAULT_GAPIC_NAME, getGapicVersion()); } private static String getGapicVersion() { @@ -175,7 +175,10 @@ public Builder toBuilder() { } private OperationsSettings(Builder settingsBuilder) throws IOException { - super(settingsBuilder.getExecutorProvider(), settingsBuilder.getChannelProvider()); + super( + settingsBuilder.getExecutorProvider(), + settingsBuilder.getChannelProvider(), + settingsBuilder.getCredentialsProvider()); getOperationSettings = settingsBuilder.getOperationSettings().build(); listOperationsSettings = settingsBuilder.listOperationsSettings().build(); @@ -353,6 +356,12 @@ public Builder setChannelProvider(ChannelProvider channelProvider) { return this; } + @Override + public Builder setCredentialsProvider(CredentialsProvider credentialsProvider) { + super.setCredentialsProvider(credentialsProvider); + return this; + } + /** * Applies the given settings to all of the unary API methods in this service. Only values that * are non-null will be applied, so this method is not capable of un-setting any values. diff --git a/gax-grpc/src/main/java/com/google/longrunning/PagedResponseWrappers.java b/gax-grpc/src/main/java/com/google/longrunning/PagedResponseWrappers.java index a887c4e03..2aee28385 100644 --- a/gax-grpc/src/main/java/com/google/longrunning/PagedResponseWrappers.java +++ b/gax-grpc/src/main/java/com/google/longrunning/PagedResponseWrappers.java @@ -32,11 +32,11 @@ import com.google.api.core.ApiFunction; import com.google.api.core.ApiFuture; import com.google.api.core.ApiFutures; +import com.google.api.core.BetaApi; import com.google.api.gax.grpc.AbstractFixedSizeCollection; import com.google.api.gax.grpc.AbstractPage; import com.google.api.gax.grpc.AbstractPagedListResponse; import com.google.api.gax.grpc.PageContext; -import com.google.protobuf.ExperimentalApi; import java.util.List; import javax.annotation.Generated; @@ -47,7 +47,7 @@ * page streaming pattern. */ @Generated("by GAPIC") -@ExperimentalApi +@BetaApi public class PagedResponseWrappers { public static class ListOperationsPagedResponse diff --git a/gax-grpc/src/main/java/com/google/longrunning/package-info.java b/gax-grpc/src/main/java/com/google/longrunning/package-info.java index ce09bf29b..76593c6ce 100644 --- a/gax-grpc/src/main/java/com/google/longrunning/package-info.java +++ b/gax-grpc/src/main/java/com/google/longrunning/package-info.java @@ -33,7 +33,7 @@ * *

The interfaces provided are listed below, along with usage samples. * - *

= =============== OperationsClient ================ + *

================ OperationsClient ================ * *

Service Description: Manages long-running operations with an API service. * diff --git a/gax-grpc/src/test/java/com/google/api/gax/grpc/AuthCallableTest.java b/gax-grpc/src/test/java/com/google/api/gax/grpc/AuthCallableTest.java new file mode 100644 index 000000000..014c59d56 --- /dev/null +++ b/gax-grpc/src/test/java/com/google/api/gax/grpc/AuthCallableTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2017, 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 com.google.api.gax.grpc; + +import com.google.api.core.ApiFuture; +import com.google.api.core.ApiFutures; +import com.google.auth.Credentials; +import com.google.common.truth.Truth; +import io.grpc.CallCredentials; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mockito; + +@RunWith(JUnit4.class) +public class AuthCallableTest { + private static class StashCallable implements FutureCallable { + CallCredentials lastCredentials; + + @Override + public ApiFuture futureCall(Integer request, CallContext context) { + lastCredentials = context.getCallOptions().getCredentials(); + return ApiFutures.immediateFuture(42); + } + } + + @Test + public void testAuth() throws InterruptedException, ExecutionException, CancellationException { + StashCallable stash = new StashCallable(); + Truth.assertThat(UnaryCallable.create(stash).futureCall(0).get()).isEqualTo(42); + Truth.assertThat(stash.lastCredentials).isNull(); + + Truth.assertThat( + UnaryCallable.create(stash) + .withAuth(Mockito.mock(Credentials.class)) + .futureCall(0) + .get()) + .isEqualTo(42); + Truth.assertThat(stash.lastCredentials).isNotNull(); + } +} diff --git a/gax-grpc/src/test/java/com/google/api/gax/grpc/OperationCallableTest.java b/gax-grpc/src/test/java/com/google/api/gax/grpc/OperationCallableTest.java index e88dfd929..87fad1bd1 100644 --- a/gax-grpc/src/test/java/com/google/api/gax/grpc/OperationCallableTest.java +++ b/gax-grpc/src/test/java/com/google/api/gax/grpc/OperationCallableTest.java @@ -42,6 +42,7 @@ import io.grpc.Channel; import java.io.IOException; import java.util.Arrays; +import java.util.Collections; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import org.junit.After; @@ -94,36 +95,20 @@ public void testCall() { OperationCallable callable = new OperationCallable( - stashUnaryCallable, null, executor, operationsClient, Color.class, null); + stashUnaryCallable, + ClientContext.newBuilder() + .setChannel(Mockito.mock(Channel.class)) + .setExecutor(executor) + .setCloseables(Collections.emptyList()) + .build(), + operationsClient, + Color.class, + null); Color response = callable.call(2, CallContext.createDefault()); Truth.assertThat(response).isEqualTo(injectedResponse); - Truth.assertThat(stash.context.getChannel()).isNull(); Truth.assertThat(stash.context.getCallOptions()).isEqualTo(CallOptions.DEFAULT); } - @Test - public void testBind() { - String opName = "testBind"; - Color injectedResponse = Color.newBuilder().setBlue(1.0f).build(); - Operation resultOperation = - Operation.newBuilder() - .setName(opName) - .setDone(true) - .setResponse(Any.pack(injectedResponse)) - .build(); - StashCallable stash = new StashCallable<>(resultOperation); - UnaryCallable stashUnaryCallable = new UnaryCallable<>(stash); - - Channel channel = Mockito.mock(Channel.class); - OperationCallable callable = - new OperationCallable( - stashUnaryCallable, null, executor, operationsClient, Color.class, null); - callable = callable.bind(channel); - Color response = callable.call(2); - Truth.assertThat(response).isEqualTo(injectedResponse); - Truth.assertThat(stash.context.getChannel()).isSameAs(channel); - } - @Test public void testResumeFutureCall() throws Exception { String opName = "testCall"; @@ -141,7 +126,15 @@ public void testResumeFutureCall() throws Exception { OperationCallable callable = new OperationCallable( - stashUnaryCallable, null, executor, operationsClient, Color.class, null); + stashUnaryCallable, + ClientContext.newBuilder() + .setChannel(Mockito.mock(Channel.class)) + .setExecutor(executor) + .setCloseables(Collections.emptyList()) + .build(), + operationsClient, + Color.class, + null); OperationFuture operationFuture = callable.futureCall(2); Color response = callable.resumeFutureCall(operationFuture.getOperationName()).get(); diff --git a/gax-grpc/src/test/java/com/google/api/gax/grpc/SettingsTest.java b/gax-grpc/src/test/java/com/google/api/gax/grpc/SettingsTest.java index 330d6fd9c..6dea8de41 100644 --- a/gax-grpc/src/test/java/com/google/api/gax/grpc/SettingsTest.java +++ b/gax-grpc/src/test/java/com/google/api/gax/grpc/SettingsTest.java @@ -157,7 +157,10 @@ public Builder toBuilder() { } private FakeSettings(Builder settingsBuilder) throws IOException { - super(settingsBuilder.getExecutorProvider(), settingsBuilder.getChannelProvider()); + super( + settingsBuilder.getExecutorProvider(), + settingsBuilder.getChannelProvider(), + settingsBuilder.getCredentialsProvider()); this.fakeMethodSimple = settingsBuilder.fakeMethodSimple().build(); this.fakePagedMethod = settingsBuilder.fakePagedMethod().build(); @@ -544,13 +547,15 @@ private static void assertIsReflectionEqual(FakeSettings settingsA, FakeSettings "fakePagedMethod", "fakeMethodBatching", "channelProvider", - "executorProvider" + "executorProvider", + "credentialsProvider" }); assertIsReflectionEqual(settingsA.fakeMethodSimple, settingsB.fakeMethodSimple); assertIsReflectionEqual(settingsA.fakePagedMethod, settingsB.fakePagedMethod); assertIsReflectionEqual(settingsA.fakeMethodBatching, settingsB.fakeMethodBatching); assertIsReflectionEqual(settingsA.getChannelProvider(), settingsB.getChannelProvider()); assertIsReflectionEqual(settingsA.getExecutorProvider(), settingsB.getExecutorProvider()); + assertIsReflectionEqual(settingsA.getCredentialsProvider(), settingsB.getCredentialsProvider()); } private static void assertIsReflectionEqual( @@ -563,13 +568,15 @@ private static void assertIsReflectionEqual( "fakePagedMethod", "fakeMethodBatching", "channelProvider", - "executorProvider" + "executorProvider", + "credentialsProvider" }); assertIsReflectionEqual(builderA.fakeMethodSimple, builderB.fakeMethodSimple); assertIsReflectionEqual(builderA.fakePagedMethod, builderB.fakePagedMethod); assertIsReflectionEqual(builderA.fakeMethodBatching, builderB.fakeMethodBatching); assertIsReflectionEqual(builderA.getChannelProvider(), builderB.getChannelProvider()); assertIsReflectionEqual(builderA.getExecutorProvider(), builderB.getExecutorProvider()); + assertIsReflectionEqual(builderA.getCredentialsProvider(), builderB.getCredentialsProvider()); } private static void assertIsReflectionEqual( diff --git a/gax/src/main/java/com/google/api/gax/core/NoCredentialsProvider.java b/gax/src/main/java/com/google/api/gax/core/NoCredentialsProvider.java new file mode 100644 index 000000000..149490a11 --- /dev/null +++ b/gax/src/main/java/com/google/api/gax/core/NoCredentialsProvider.java @@ -0,0 +1,43 @@ +/* + * Copyright 2017, 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 com.google.api.gax.core; + +import com.google.api.core.BetaApi; +import com.google.auth.Credentials; + +/** NoCredentialsProvider is a CredentialsProvider which always returns null. */ +@BetaApi +public final class NoCredentialsProvider implements CredentialsProvider { + + @Override + public Credentials getCredentials() { + return null; + } +}