Skip to content
This repository was archived by the owner on Sep 26, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 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,31 @@
@AutoValue
public abstract class ConnectionSettings {

/*
* package-private so that the AutoValue derived class can access it
/**
* Provides an interface to hold and acquire the credentials that will be used to call the
* service.
*/
interface CredentialsProvider {
public interface CredentialsProvider {

This comment was marked as spam.

/**
* 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;
}

/**
* 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 {
public Credentials getOrBuildCredentials() throws IOException {

This comment was marked as spam.

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 +103,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
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ protected ApiCallable<RequestT, ResponseT> createBaseCallable(
new DescriptorClientCallFactory<>(methodDescriptor);
ApiCallable<RequestT, ResponseT> callable =
new ApiCallable<>(new DirectCallable<>(clientCallFactory), this);
ManagedChannel channel = serviceSettings.getChannel();
ScheduledExecutorService executor = serviceSettings.getExecutor();
ManagedChannel channel = serviceSettings.getOrBuildChannel();
ScheduledExecutorService executor = serviceSettings.getOrBuildExecutor();
if (getRetryableCodes() != null) {
callable = callable.retryableOn(ImmutableSet.copyOf(getRetryableCodes()));
}
Expand Down
178 changes: 104 additions & 74 deletions src/main/java/com/google/api/gax/grpc/ServiceApiSettings.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,44 @@
*/
public abstract class ServiceApiSettings {

private final ManagedChannel channel;
private final boolean shouldAutoCloseChannel;
private final ScheduledExecutorService executor;
/**
* Provides an interface to hold and build the channel that will be used. If the channel does not
* already exist, it will not be constructed until getChannel is called.
*/
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.
*/
ManagedChannel getChannel(Executor executor) throws IOException;
}

@Nullable
private final ConnectionSettings connectionSettings;
/**
* Provides an interface to hold and create the Executor to be used. If the executor does not
* already exist, it will not be constructed until getExecutor is called.
*/
public interface ExecutorProvider {
/**
* 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.
*/
ScheduledExecutorService getExecutor();
}

private final ChannelProvider channelProvider;
private final ExecutorProvider executorProvider;

private final String generatorName;
private final String generatorVersion;
Expand All @@ -66,34 +98,51 @@ public abstract class ServiceApiSettings {
/**
* Constructs an instance of ServiceApiSettings.
*/
protected ServiceApiSettings(ManagedChannel channel,
boolean shouldAutoCloseChannel,
ScheduledExecutorService executor,
ConnectionSettings connectionSettings,
String generatorName,
String generatorVersion,
String clientLibName,
String clientLibVersion) {
this.channel = channel;
this.executor = executor;
this.connectionSettings = connectionSettings;
this.shouldAutoCloseChannel = shouldAutoCloseChannel;
protected ServiceApiSettings(
ChannelProvider channelProvider,
ExecutorProvider executorProvider,
String generatorName,
String generatorVersion,
String clientLibName,
String clientLibVersion) {
this.channelProvider = channelProvider;
this.executorProvider = executorProvider;
this.clientLibName = clientLibName;
this.clientLibVersion = clientLibVersion;
this.generatorName = generatorName;
this.generatorVersion = generatorVersion;
}

public final ManagedChannel getChannel() {
return channel;
/**
* Return the channel to be used to connect to the service, retrieved using the channelProvider.
* If no channel was set, a default channel will be instantiated.
*/
public final ManagedChannel getOrBuildChannel() throws IOException {
return getChannelProvider().getChannel(getOrBuildExecutor());

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

This comment was marked as spam.

}

public final ScheduledExecutorService getExecutor() {
return executor;
/**
* Return the channel provider. If no channel provider was set, the default channel provider will
* be returned.
*/
public final ChannelProvider getChannelProvider() {
return channelProvider;
}

public final boolean shouldAutoCloseChannel() {
return shouldAutoCloseChannel;
/**
* The Executor used for channels, retries, and bundling, retrieved using the executorProvider. If
* no executor was set, a default executor will be instantiated.
*/
public final ScheduledExecutorService getOrBuildExecutor() {
return getExecutorProvider().getExecutor();
}

/**
* Return the executor provider. It no executor provider was set, the default executor provider
* will be returned.
*/
public final ExecutorProvider getExecutorProvider() {
return executorProvider;
}

public abstract static class Builder {
Expand All @@ -114,16 +163,6 @@ public abstract static class Builder {
private ChannelProvider channelProvider;
private ExecutorProvider executorProvider;

private interface ChannelProvider {
ConnectionSettings connectionSettings();
boolean shouldAutoClose();
ManagedChannel getChannel(Executor executor) throws IOException;
}

private interface ExecutorProvider {
ScheduledExecutorService getExecutor();
}

protected Builder(ConnectionSettings connectionSettings) {
this();
channelProvider = createChannelProvider(connectionSettings);
Expand All @@ -134,11 +173,7 @@ protected Builder(ConnectionSettings connectionSettings) {
*/
protected Builder(ServiceApiSettings settings) {
this();
if (settings.connectionSettings != null) {
channelProvider = createChannelProvider(settings.connectionSettings);
} else {
channelProvider = createChannelProvider(settings.channel, settings.shouldAutoCloseChannel);
}
this.channelProvider = settings.channelProvider;

This comment was marked as spam.

this.clientLibName = settings.clientLibName;
this.clientLibVersion = settings.clientLibVersion;
this.serviceGeneratorName = settings.generatorName;
Expand All @@ -165,13 +200,20 @@ public ScheduledExecutorService getExecutor() {
};
}

/**
* Set the executor provider to be used.
*/
public Builder setExecutorProvider(ExecutorProvider executorProvider) {
this.executorProvider = executorProvider;
return this;
}

/**
* Sets the executor to use for channels, retries, and bundling.
*
* It is up to the user to terminate the {@code Executor} when it is no longer needed.
*/
public Builder setExecutor(final ScheduledExecutorService executor) {
public Builder provideExecutorWith(final ScheduledExecutorService executor) {
executorProvider = new ExecutorProvider() {
@Override
public ScheduledExecutorService getExecutor() {
Expand All @@ -182,44 +224,31 @@ public ScheduledExecutorService getExecutor() {
}

/**
* Sets a channel for this ServiceApiSettings to use. This prevents a channel
* from being created.
*
* See class documentation for more details on channels.
*/
public Builder provideChannelWith(
final ManagedChannel channel, final boolean shouldAutoClose) {
channelProvider = createChannelProvider(channel, shouldAutoClose);
return this;
}

/**
* Provides the connection settings necessary to create a channel.
* Set the channel provider to be used.
*/
public Builder provideChannelWith(
final ConnectionSettings settings) {
channelProvider = createChannelProvider(settings);
public Builder setChannelProvider(ChannelProvider channelProvider) {
this.channelProvider = channelProvider;
return this;
}

/**
* The channel used to send requests to the service.
*
* If no channel was set, a default channel will be instantiated, using
* the connection settings provided.
* Sets a channel for this ServiceApiSettings to use. This prevents a channel from being
* created.
*
* See class documentation for more details on channels.
*/
public ManagedChannel getOrBuildChannel() throws IOException {
return channelProvider.getChannel(this.getOrBuildExecutor());
public Builder provideChannelWith(final ManagedChannel channel, final boolean shouldAutoClose) {
setChannelProvider(createChannelProvider(channel, shouldAutoClose));
return this;
}

/**
* The Executor used for channels, retries, and bundling..
* If no executor was set, a default executor will be instantiated.
* Provides the connection settings necessary to create a channel.
*/
public ScheduledExecutorService getOrBuildExecutor() {
return executorProvider.getExecutor();
public Builder provideChannelWith(
final ConnectionSettings settings) {
setChannelProvider(createChannelProvider(settings));
return this;
}

/**
Expand All @@ -240,6 +269,14 @@ public Builder setClientLibHeader(String name, String version) {
return this;
}

public ChannelProvider getChannelProvider() {
return channelProvider;
}

public ExecutorProvider getExecutorProvider() {
return executorProvider;
}

public String getClientLibName() {
return clientLibName;
}
Expand All @@ -256,14 +293,6 @@ public String getGeneratorVersion() {
return serviceGeneratorVersion;
}

public ConnectionSettings getConnectionSettings() {
return channelProvider.connectionSettings();
}

public boolean shouldAutoCloseChannel() {
return channelProvider.shouldAutoClose();
}

/**
* Performs a merge, using only non-null fields
*/
Expand All @@ -289,14 +318,15 @@ protected Builder applyToAllApiMethods(
private ChannelProvider createChannelProvider(final ConnectionSettings settings) {
return new ChannelProvider() {
private ManagedChannel channel = null;

@Override
public ManagedChannel getChannel(Executor executor) throws IOException {
if (channel != null) {
return channel;
}

List<ClientInterceptor> interceptors = Lists.newArrayList();
interceptors.add(new ClientAuthInterceptor(settings.getCredentials(), executor));
interceptors.add(new ClientAuthInterceptor(settings.getOrBuildCredentials(), executor));
interceptors.add(new HeaderInterceptor(serviceHeader()));

channel = NettyChannelBuilder.forAddress(settings.getServiceAddress(), settings.getPort())
Expand Down