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

Commit

Permalink
Make ServiceApiSettings provider interfaces public (#75)
Browse files Browse the repository at this point in the history
Change Channel and Executor provision

Make ChannelProvider, ExecutorProvider and CredentialsProvider
interfaces public. This allows the ApiSettings object to be
constructed without instantiating the channel, executor or
credentials until they are required by the Api object.
Use executor for channel
Added shouldAutoClose parameter to ExecutorProvider
Added IllegalStateException to ExecutorProvider
and ChannelProvider when a fixed executor/channel is accessed
multiple times.
  • Loading branch information
michaelbausor committed Apr 28, 2016
1 parent 496005a commit 6ba722c
Show file tree
Hide file tree
Showing 12 changed files with 428 additions and 174 deletions.
24 changes: 9 additions & 15 deletions src/main/java/com/google/api/gax/core/ConnectionSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,25 +56,19 @@
@AutoValue
public abstract class ConnectionSettings {

/*
* package-private so that the AutoValue derived class can access it
*/
interface CredentialsProvider {
Credentials getCredentials() 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.
* 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.
*/
public Credentials getCredentials() throws IOException {
return getCredentialsProvider().getCredentials();
}

/*
* package-private so that the AutoValue derived class can access it
/**
* The credentials to use in order to call the service. Credentials will not be acquired until
* they are required.
*/
abstract CredentialsProvider getCredentialsProvider();
public abstract CredentialsProvider getCredentialsProvider();

/**
* The address used to reach the service.
Expand All @@ -97,10 +91,10 @@ public Builder toBuilder() {
@AutoValue.Builder
public abstract static class Builder {

/*
* package-private so that the AutoValue derived class can access it
/**
* Set the credentials to use in order to call the service.
*/
abstract Builder setCredentialsProvider(CredentialsProvider provider);
public abstract Builder setCredentialsProvider(CredentialsProvider provider);

/**
* Sets the credentials to use in order to call the service.
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/google/api/gax/core/CredentialsProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.google.api.gax.core;

import com.google.auth.Credentials;

import java.io.IOException;

/**
* Provides an interface to hold and acquire the credentials that will be used to call the service.
*/
public interface CredentialsProvider {
/**
* 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.
*/
Credentials getCredentials() throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import io.grpc.MethodDescriptor;
import io.grpc.Status;

import java.io.IOException;
import java.util.concurrent.ScheduledExecutorService;

/**
Expand Down Expand Up @@ -39,13 +38,11 @@ protected ApiCallSettingsTyped(ImmutableSet<Status.Code> retryableCodes,
}

protected ApiCallable<RequestT, ResponseT> createBaseCallable(
ServiceApiSettings serviceSettings) throws IOException {
ManagedChannel channel, ScheduledExecutorService executor) {
ClientCallFactory<RequestT, ResponseT> clientCallFactory =
new DescriptorClientCallFactory<>(methodDescriptor);
ApiCallable<RequestT, ResponseT> callable =
new ApiCallable<>(new DirectCallable<>(clientCallFactory), this);
ManagedChannel channel = serviceSettings.getChannel();
ScheduledExecutorService executor = serviceSettings.getExecutor();
if (getRetryableCodes() != null) {
callable = callable.retryableOn(ImmutableSet.copyOf(getRetryableCodes()));
}
Expand Down
67 changes: 35 additions & 32 deletions src/main/java/com/google/api/gax/grpc/ApiCallable.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
import com.google.common.util.concurrent.UncheckedExecutionException;

import io.grpc.Channel;
import io.grpc.ManagedChannel;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;

import java.io.IOException;
import java.util.concurrent.ScheduledExecutorService;

import javax.annotation.Nullable;
Expand Down Expand Up @@ -103,69 +103,72 @@ public final class ApiCallable<RequestT, ResponseT> {
private final ApiCallSettings settings;

/**
* Create a callable object that represents a simple API method.
* Public only for technical reasons - for advanced usage
* 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 serviceSettings{@link com.google.api.gax.grpc.ServiceApiSettings}
* to configure the service-level settings with.
* @param simpleCallSettings {@link com.google.api.gax.grpc.SimpleCallSettings} to configure the
* method-level settings with.
* @param channel {@link ManagedChannel} to use to connect to the service.
* @param executor {@link ScheduledExecutorService} to use when connecting to the service.
* @return {@link com.google.api.gax.grpc.ApiCallable} callable object.
*/
public static <RequestT, ResponseT> ApiCallable<RequestT, ResponseT> create(
SimpleCallSettings<RequestT, ResponseT> simpleCallSettings,
ServiceApiSettings serviceSettings) throws IOException {
return simpleCallSettings.create(serviceSettings);
ManagedChannel channel,
ScheduledExecutorService executor) {
return simpleCallSettings.create(channel, executor);
}

/**
* Create a paged callable object that represents a page-streaming API method.
* Public only for technical reasons - for advanced usage
* Create a paged callable object that represents a page-streaming API method. Public only for
* technical reasons - for advanced usage
*
* @param pageStreamingCallSettings {@link com.google.api.gax.grpc.PageStreamingCallSettings} to
* configure the page-streaming related settings with.
* @param serviceSettings{@link com.google.api.gax.grpc.ServiceApiSettings}
* to configure the service-level settings with.
* @param channel {@link ManagedChannel} to use to connect to the service.
* @param executor {@link ScheduledExecutorService} to use to when connecting to the service.
* @return {@link com.google.api.gax.grpc.ApiCallable} callable object.
*/
public static <RequestT, ResponseT, ResourceT>
ApiCallable<RequestT, PageAccessor<ResourceT>> createPagedVariant(
PageStreamingCallSettings<RequestT, ResponseT, ResourceT> pageStreamingCallSettings,
ServiceApiSettings serviceSettings) throws IOException {
return pageStreamingCallSettings.createPagedVariant(serviceSettings);
ManagedChannel channel,
ScheduledExecutorService executor) {
return pageStreamingCallSettings.createPagedVariant(channel, executor);
}

/**
* Create a base callable object that represents a page-streaming API method.
* Public only for technical reasons - for advanced usage
* Create a base callable object that represents a page-streaming API method. Public only for
* technical reasons - for advanced usage
*
* @param pageStreamingCallSettings {@link com.google.api.gax.grpc.PageStreamingCallSettings} to
* configure the page-streaming related settings with.
* @param serviceSettings{@link com.google.api.gax.grpc.ServiceApiSettings}
* to configure the service-level settings with.
* @param channel {@link ManagedChannel} to use to connect to the service.
* @param executor {@link ScheduledExecutorService} to use to when connecting to the service.
* @return {@link com.google.api.gax.grpc.ApiCallable} callable object.
*/
public static <RequestT, ResponseT, ResourceT>
ApiCallable<RequestT, ResponseT> create(
PageStreamingCallSettings<RequestT, ResponseT, ResourceT> pageStreamingCallSettings,
ServiceApiSettings serviceSettings) throws IOException {
return pageStreamingCallSettings.create(serviceSettings);
public static <RequestT, ResponseT, ResourceT> ApiCallable<RequestT, ResponseT> create(
PageStreamingCallSettings<RequestT, ResponseT, ResourceT> pageStreamingCallSettings,
ManagedChannel channel,
ScheduledExecutorService executor) {
return pageStreamingCallSettings.create(channel, executor);
}

/**
* Create a callable object that represents a bundling API method.
* Public only for technical reasons - for advanced usage
* Create a callable object that represents a bundling API method. Public only for technical
* reasons - for advanced usage
*
* @param bundlingCallSettings {@link com.google.api.gax.grpc.BundlingSettings} to configure
* the bundling related settings with.
* @param serviceSettings{@link com.google.api.gax.grpc.ServiceApiSettings}
* to configure the service-level settings with.
* @param bundlingCallSettings {@link com.google.api.gax.grpc.BundlingSettings} to configure the
* bundling related settings with.
* @param channel {@link ManagedChannel} to use to connect to the service.
* @param executor {@link ScheduledExecutorService} to use to when connecting to the service.
* @return {@link com.google.api.gax.grpc.ApiCallable} callable object.
*/
public static <RequestT, ResponseT> ApiCallable<RequestT, ResponseT> create(
BundlingCallSettings<RequestT, ResponseT> bundlingCallSettings,
ServiceApiSettings serviceSettings) throws IOException {
return bundlingCallSettings.create(serviceSettings);
ManagedChannel channel,
ScheduledExecutorService executor) {
return bundlingCallSettings.create(channel, executor);
}

/**
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/com/google/api/gax/grpc/ApiException.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@
/**
* Represents an exception thrown during an RPC call.
*
* <p>It stores information useful for functionalities in {@link ApiCallable}.
* <p>
* It stores information useful for functionalities in {@link ApiCallable}. For more information
* about the status codes returned by the underlying grpc exception see {@link Status}.
*/
public class ApiException extends RuntimeException {
private final Status.Code statusCode;
Expand All @@ -58,9 +60,9 @@ public boolean isRetryable() {
}

/**
* Returns the status code of the underlying grpc exception. In cases
* where the underlying exception is not of type StatusException or
* StatusRuntimeException, the status code will be Status.Code.UNKNOWN
* Returns the status code of the underlying grpc exception. In cases where the underlying
* exception is not of type StatusException or StatusRuntimeException, the status code will be
* Status.Code.UNKNOWN. For more information about status codes see {@link Status}.
*/
public Status.Code getStatusCode() {
return statusCode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import com.google.api.gax.core.RetrySettings;
import com.google.common.collect.ImmutableSet;

import io.grpc.ManagedChannel;
import io.grpc.MethodDescriptor;
import io.grpc.Status;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;

/**
* A settings class to configure an ApiCallable for calls to an API method that supports
Expand All @@ -23,8 +24,8 @@ public final class BundlingCallSettings<RequestT, ResponseT>
* Package-private, for use by ApiCallable.
*/
ApiCallable<RequestT, ResponseT> create(
ServiceApiSettings serviceSettings) throws IOException {
ApiCallable<RequestT, ResponseT> baseCallable = createBaseCallable(serviceSettings);
ManagedChannel channel, ScheduledExecutorService executor) {
ApiCallable<RequestT, ResponseT> baseCallable = createBaseCallable(channel, executor);
bundlerFactory = new BundlerFactory<>(bundlingDescriptor, bundlingSettings);
return baseCallable.bundling(bundlingDescriptor, bundlerFactory);
}
Expand Down
50 changes: 50 additions & 0 deletions src/main/java/com/google/api/gax/grpc/ChannelProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.google.api.gax.grpc;

import com.google.api.gax.core.ConnectionSettings;

import io.grpc.ManagedChannel;

import java.io.IOException;
import java.util.concurrent.Executor;

import javax.annotation.Nullable;

/**
* Provides an interface to hold and build the channel that will be used. If the channel does not
* already exist, it will be constructed when {@link #getOrBuildChannel} is called.
*
* Implementations of {@link ChannelProvider} may choose to create a new {@link ManagedChannel} for
* each call to {@link #getOrBuildChannel}, or may return a fixed {@link ManagedChannel} instance.
* In cases where the same {@link ManagedChannel} instance is returned, for example by a
* {@link ChannelProvider} created using the {@link ServiceApiSettings}
* provideChannelWith(ManagedChannel, boolean) method, and shouldAutoClose returns true, the
* {@link #getOrBuildChannel} method will throw an {@link IllegalStateException} if it is called
* more than once. This is to prevent the same {@link ManagedChannel} being closed prematurely when
* it is used by multiple client objects.
*/
public interface ChannelProvider {
/**
* Connection settings used to build the channel. If a channel is provided directly this will be
* set to null.
*/
@Nullable
ConnectionSettings connectionSettings();

/**
* Indicates whether the channel should be closed by the containing API class.
*/
boolean shouldAutoClose();

/**
* Get the channel to be used to connect to the service. The first time this is called, if the
* channel does not already exist, it will be created. The {@link Executor} will only be used when
* the channel is created. For implementations returning a fixed {@link ManagedChannel} object,
* the executor is unused.
*
* If the {@link ChannelProvider} is configured to return a fixed {@link ManagedChannel} object
* and to return shouldAutoClose as true, then after the first call to {@link #getOrBuildChannel},
* subsequent calls should throw an {@link IllegalStateException}. See interface level docs for
* {@link ChannelProvider} for more details.
*/
ManagedChannel getOrBuildChannel(Executor executor) throws IOException;
}
36 changes: 36 additions & 0 deletions src/main/java/com/google/api/gax/grpc/ExecutorProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.google.api.gax.grpc;

import java.util.concurrent.ScheduledExecutorService;

/**
* Provides an interface to hold and create the Executor to be used. If the executor does not
* already exist, it will be constructed when {@link #getOrBuildExecutor} is called.
*
* Implementations of ExecutorProvider may choose to create a new {@link ScheduledExecutorService}
* for each call to {@link #getOrBuildExecutor}, or may return a fixed
* {@link ScheduledExecutorService} instance. In cases where the same
* {@link ScheduledExecutorService} instance is returned, for example by an {@link ExecutorProvider}
* created using the {@link ServiceApiSettings} provideExecutorWith(ScheduledExecutorService,
* boolean) method, and shouldAutoClose returns true, the {@link #getOrBuildExecutor} method will
* throw an {@link IllegalStateException} if it is called more than once. This is to prevent the
* same {@link ScheduledExecutorService} being closed prematurely when it is used by multiple client
* objects.
*/
public interface ExecutorProvider {
/**
* Indicates whether the channel should be closed by the containing API class.
*/
boolean shouldAutoClose();

/**
* Get the executor to be used to connect to the service. The first time this is called, if the
* executor does not already exist, it will be created.
*
* If the {@link ExecutorProvider} is configured to return a fixed
* {@link ScheduledExecutorService} object and to return shouldAutoClose as true, then after the
* first call to {@link #getOrBuildExecutor}, subsequent calls should throw an
* {@link IllegalStateException}. See interface level docs for {@link ExecutorProvider} for more
* details.
*/
ScheduledExecutorService getOrBuildExecutor();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import com.google.api.gax.core.RetrySettings;
import com.google.common.collect.ImmutableSet;

import io.grpc.ManagedChannel;
import io.grpc.MethodDescriptor;
import io.grpc.Status;

import java.io.IOException;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;


/**
Expand All @@ -23,16 +24,16 @@ public final class PageStreamingCallSettings<RequestT, ResponseT, ResourceT>
* Package-private, for use by ApiCallable.
*/
ApiCallable<RequestT, ResponseT> create(
ServiceApiSettings serviceSettings) throws IOException {
return createBaseCallable(serviceSettings);
ManagedChannel channel, ScheduledExecutorService executor) {
return createBaseCallable(channel, executor);
}

/**
* Package-private, for use by ApiCallable.
*/
ApiCallable<RequestT, PageAccessor<ResourceT>> createPagedVariant(
ServiceApiSettings serviceSettings) throws IOException {
ApiCallable<RequestT, ResponseT> baseCallable = createBaseCallable(serviceSettings);
ManagedChannel channel, ScheduledExecutorService executor) {
ApiCallable<RequestT, ResponseT> baseCallable = createBaseCallable(channel, executor);
return baseCallable.pageStreaming(pageDescriptor);
}

Expand Down
Loading

0 comments on commit 6ba722c

Please sign in to comment.