Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

Commit

Permalink
Move CredentialProvider up to ClientSettings (#305)
Browse files Browse the repository at this point in the history
Updates googleapis/google-cloud-java#2034.

This commit should resolve the first 3 bullets in the
linked issue.

Major changes are:
- ClientContext is added to pull together channel, executor, and credentials,
  which are often needed together.
  This change will also simplify future work if more ClientSettings are added.
  • Loading branch information
pongad authored May 22, 2017
1 parent dbbb76a commit 5830ace
Show file tree
Hide file tree
Showing 20 changed files with 530 additions and 140 deletions.
59 changes: 59 additions & 0 deletions gax-grpc/src/main/java/com/google/api/gax/grpc/AuthCallable.java
Original file line number Diff line number Diff line change
@@ -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}.
*
* <p>Package-private for internal use.
*/
class AuthCallable<RequestT, ResponseT> implements FutureCallable<RequestT, ResponseT> {
private final FutureCallable<RequestT, ResponseT> callable;
private final CallCredentials credentials;

AuthCallable(FutureCallable<RequestT, ResponseT> callable, Credentials credentials) {
this.callable = Preconditions.checkNotNull(callable);
this.credentials = MoreCallCredentials.from(Preconditions.checkNotNull(credentials));
}

@Override
public ApiFuture<ResponseT> futureCall(RequestT request, CallContext context) {
if (context.getCallOptions().getCredentials() == null) {
context = context.withCallOptions(context.getCallOptions().withCallCredentials(credentials));
}
return callable.futureCall(request, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -52,9 +50,10 @@ public final class BatchingCallSettings<RequestT, ResponseT>
private BatcherFactory<RequestT, ResponseT> batcherFactory;

/** Package-private, for use by UnaryCallable. */
UnaryCallable<RequestT, ResponseT> create(Channel channel, ScheduledExecutorService executor) {
UnaryCallable<RequestT, ResponseT> baseCallable = createBaseCallable(channel, executor);
batcherFactory = new BatcherFactory<>(batchingDescriptor, batchingSettings, executor);
UnaryCallable<RequestT, ResponseT> create(ClientContext context) {
UnaryCallable<RequestT, ResponseT> baseCallable = createBaseCallable(context);
batcherFactory =
new BatcherFactory<>(batchingDescriptor, batchingSettings, context.getExecutor());
return baseCallable.batching(batchingDescriptor, batcherFactory);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
*/
@BetaApi
@AutoValue
@Deprecated
public abstract class ChannelAndExecutor {
public abstract ScheduledExecutorService getExecutor();

Expand Down
116 changes: 116 additions & 0 deletions gax-grpc/src/main/java/com/google/api/gax/grpc/ClientContext.java
Original file line number Diff line number Diff line change
@@ -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.
*
* <p>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<AutoCloseable> 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<AutoCloseable> 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<AutoCloseable> value);

public abstract Builder setChannel(Channel value);

public abstract Builder setExecutor(ScheduledExecutorService value);

public abstract Builder setCredentials(Credentials value);

public abstract ClientContext build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}
Expand All @@ -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();
}

/**
Expand All @@ -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;
Expand All @@ -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<UnaryCallSettings.Builder> methodSettingsBuilders,
Expand All @@ -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();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -59,12 +57,10 @@ public final Duration getPollingInterval() {

// package-private for internal use.
OperationCallable<RequestT, ResponseT> createOperationCallable(
Channel channel, ScheduledExecutorService executor, OperationsClient operationsClient) {
UnaryCallable<RequestT, Operation> initialCallable =
initialCallSettings.create(channel, executor);
ClientContext context, OperationsClient operationsClient) {
UnaryCallable<RequestT, Operation> initialCallable = initialCallSettings.create(context);
OperationCallable<RequestT, ResponseT> operationCallable =
new OperationCallable<>(
initialCallable, channel, executor, operationsClient, responseClass, this);
new OperationCallable<>(initialCallable, context, operationsClient, responseClass, this);
return operationCallable;
}

Expand Down
Loading

0 comments on commit 5830ace

Please sign in to comment.