io.servicetalk.grpc.api.GrpcClientBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of servicetalk-grpc-api Show documentation
Show all versions of servicetalk-grpc-api Show documentation
A networking framework that evolves with your application
/*
* Copyright © 2019 Apple Inc. and the ServiceTalk project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.servicetalk.grpc.api;
import io.servicetalk.buffer.api.BufferAllocator;
import io.servicetalk.client.api.AutoRetryStrategyProvider;
import io.servicetalk.client.api.ConnectionFactoryFilter;
import io.servicetalk.client.api.ServiceDiscoverer;
import io.servicetalk.client.api.ServiceDiscovererEvent;
import io.servicetalk.concurrent.api.Single;
import io.servicetalk.http.api.FilterableStreamingHttpConnection;
import io.servicetalk.http.api.HttpExecutionStrategy;
import io.servicetalk.http.api.HttpLoadBalancerFactory;
import io.servicetalk.http.api.HttpProtocolConfig;
import io.servicetalk.http.api.StreamingHttpClientFilter;
import io.servicetalk.http.api.StreamingHttpClientFilterFactory;
import io.servicetalk.http.api.StreamingHttpConnectionFilterFactory;
import io.servicetalk.http.api.StreamingHttpRequest;
import io.servicetalk.http.api.StreamingHttpRequester;
import io.servicetalk.http.api.StreamingHttpResponse;
import io.servicetalk.logging.api.LogLevel;
import io.servicetalk.transport.api.IoExecutor;
import java.net.SocketOption;
import java.util.function.BooleanSupplier;
import java.util.function.Predicate;
import static io.servicetalk.concurrent.api.Single.failed;
import static io.servicetalk.grpc.api.GrpcStatus.fromThrowable;
/**
* A builder for building a gRPC client.
*
* @param the type of address before resolution (unresolved address)
* @param the type of address after resolution (resolved address)
*/
public abstract class GrpcClientBuilder
implements SingleAddressGrpcClientBuilder> {
private boolean appendedCatchAllFilter;
@Override
public abstract GrpcClientBuilder ioExecutor(IoExecutor ioExecutor);
@Override
public abstract GrpcClientBuilder bufferAllocator(BufferAllocator allocator);
@Override
public abstract GrpcClientBuilder executionStrategy(GrpcExecutionStrategy strategy);
@Override
public abstract GrpcClientBuilder socketOption(SocketOption option, T value);
@Override
@Deprecated
public abstract GrpcClientBuilder enableWireLogging(String loggerName);
@Override
public abstract GrpcClientBuilder enableWireLogging(String loggerName, LogLevel logLevel,
BooleanSupplier logUserData);
@Override
public abstract GrpcClientBuilder protocols(HttpProtocolConfig... protocols);
@Override
public abstract GrpcClientBuilder appendConnectionFactoryFilter(
ConnectionFactoryFilter factory);
@Override
public abstract GrpcClientBuilder appendConnectionFilter(StreamingHttpConnectionFilterFactory factory);
@Override
public abstract GrpcClientBuilder appendConnectionFilter(Predicate predicate,
StreamingHttpConnectionFilterFactory factory);
@Override
public abstract GrpcClientSecurityConfigurator secure();
@Override
public abstract GrpcClientBuilder autoRetryStrategy(
AutoRetryStrategyProvider autoRetryStrategyProvider);
@Override
public abstract GrpcClientBuilder serviceDiscoverer(
ServiceDiscoverer> serviceDiscoverer);
@Override
public abstract GrpcClientBuilder loadBalancerFactory(HttpLoadBalancerFactory loadBalancerFactory);
/**
* Append the filter to the chain of filters used to decorate the client created by this builder.
*
* The order of execution of these filters are in order of append. If 3 filters are added as follows:
*
* builder.append(filter1).append(filter2).append(filter3)
*
* making a request to a client wrapped by this filter chain the order of invocation of these filters will be:
*
* filter1 => filter2 => filter3 => client
*
*
* @param factory {@link StreamingHttpClientFilterFactory} to decorate a client for the purpose of filtering.
* @return {@code this}
*/
public final GrpcClientBuilder appendHttpClientFilter(StreamingHttpClientFilterFactory factory) {
appendCatchAllFilterIfRequired();
doAppendHttpClientFilter(factory);
return this;
}
/**
* Append the filter to the chain of filters used to decorate the client created by this builder, for every request
* that passes the provided {@link Predicate}.
*
* The order of execution of these filters are in order of append. If 3 filters are added as follows:
*
* builder.append(filter1).append(filter2).append(filter3)
*
* making a request to a client wrapped by this filter chain the order of invocation of these filters will be:
*
* filter1 => filter2 => filter3 => client
*
*
* @param predicate the {@link Predicate} to test if the filter must be applied.
* @param factory {@link StreamingHttpClientFilterFactory} to decorate a client for the purpose of filtering.
* @return {@code this}
*/
public final GrpcClientBuilder appendHttpClientFilter(Predicate predicate,
StreamingHttpClientFilterFactory factory) {
appendCatchAllFilterIfRequired();
doAppendHttpClientFilter(predicate, factory);
return this;
}
/**
* Builds a gRPC client.
*
* @param clientFactory {@link GrpcClientFactory} to use.
* @param gRPC service that any client built from
* this factory represents.
* @param Type for client filter
* @param Type of filterable client.
* @param Type of {@link GrpcClientFilterFactory}
*
* @return A gRPC client.
*/
public final ,
Filter extends FilterableClient, FilterableClient extends FilterableGrpcClient,
FilterFactory extends GrpcClientFilterFactory> Client
build(GrpcClientFactory clientFactory) {
return clientFactory.newClientForCallFactory(newGrpcClientCallFactory());
}
/**
* Builds a blocking gRPC client.
*
* @param clientFactory {@link GrpcClientFactory} to use.
* @param Blocking gRPC service that any
* client built from this builder represents.
* @param Type for client filter
* @param Type of filterable client.
* @param Type of {@link GrpcClientFilterFactory}
*
* @return A blocking gRPC client.
*/
public final ,
Filter extends FilterableClient, FilterableClient extends FilterableGrpcClient,
FilterFactory extends GrpcClientFilterFactory> BlockingClient
buildBlocking(GrpcClientFactory clientFactory) {
return clientFactory.newBlockingClientForCallFactory(newGrpcClientCallFactory());
}
/**
* Returns a {@link MultiClientBuilder} to be used to create multiple clients sharing the same underlying transport
* instance.
*
* @return A blocking gRPC client.
*/
public final MultiClientBuilder buildMulti() {
GrpcClientCallFactory callFactory = newGrpcClientCallFactory();
return new MultiClientBuilder() {
@Override
public ,
Filter extends FilterableClient, FilterableClient extends FilterableGrpcClient,
FilterFactory extends GrpcClientFilterFactory> Client
build(final GrpcClientFactory clientFactory) {
return clientFactory.newClient(callFactory);
}
@Override
public ,
Filter extends FilterableClient, FilterableClient extends FilterableGrpcClient,
FilterFactory extends GrpcClientFilterFactory> BlockingClient
buildBlocking(
final GrpcClientFactory clientFactory) {
return clientFactory.newBlockingClient(callFactory);
}
};
}
/**
* Create a new {@link GrpcClientCallFactory}.
*
* @return A new {@link GrpcClientCallFactory}.
*/
protected abstract GrpcClientCallFactory newGrpcClientCallFactory();
/**
* Append the filter to the chain of filters used to decorate the client created by this builder.
*
* The order of execution of these filters are in order of append. If 3 filters are added as follows:
*
* builder.append(filter1).append(filter2).append(filter3)
*
* making a request to a client wrapped by this filter chain the order of invocation of these filters will be:
*
* filter1 => filter2 => filter3 => client
*
*
* @param factory {@link StreamingHttpClientFilterFactory} to decorate a client for the purpose of filtering.
*/
protected abstract void doAppendHttpClientFilter(StreamingHttpClientFilterFactory factory);
/**
* Append the filter to the chain of filters used to decorate the client created by this builder, for every request
* that passes the provided {@link Predicate}.
*
* The order of execution of these filters are in order of append. If 3 filters are added as follows:
*
* builder.append(filter1).append(filter2).append(filter3)
*
* making a request to a client wrapped by this filter chain the order of invocation of these filters will be:
*
* filter1 => filter2 => filter3 => client
*
*
* @param predicate the {@link Predicate} to test if the filter must be applied.
* @param factory {@link StreamingHttpClientFilterFactory} to decorate a client for the purpose of filtering.
*/
protected abstract void doAppendHttpClientFilter(Predicate predicate,
StreamingHttpClientFilterFactory factory);
private void appendCatchAllFilterIfRequired() {
if (!appendedCatchAllFilter) {
doAppendHttpClientFilter(client -> new StreamingHttpClientFilter(client) {
@Override
protected Single request(final StreamingHttpRequester delegate,
final HttpExecutionStrategy strategy,
final StreamingHttpRequest request) {
final Single resp;
try {
resp = super.request(delegate, strategy, request);
} catch (Throwable t) {
return failed(toGrpcException(t));
}
return resp.recoverWith(t -> failed(toGrpcException(t)));
}
});
appendedCatchAllFilter = true;
}
}
private static GrpcStatusException toGrpcException(Throwable cause) {
return fromThrowable(cause).asException();
}
/**
* An interface to create multiple gRPC clients sharing the
* same underlying transport instance.
*/
public interface MultiClientBuilder {
/**
* Builds a gRPC client.
*
* @param clientFactory {@link GrpcClientFactory} to use.
* @param gRPC service that any client built
* from this factory represents.
* @param Type for client filter
* @param Type of filterable client.
* @param Type of {@link GrpcClientFilterFactory}
*
* @return A gRPC client.
*/
,
Filter extends FilterableClient, FilterableClient extends FilterableGrpcClient,
FilterFactory extends GrpcClientFilterFactory> Client
build(GrpcClientFactory clientFactory);
/**
* Builds a blocking gRPC client.
*
* @param clientFactory {@link GrpcClientFactory} to use.
* @param Blocking gRPC service that
* any client built from this builder represents.
* @param Type for client filter
* @param Type of filterable client.
* @param Type of {@link GrpcClientFilterFactory}
*
* @return A blocking gRPC client.
*/
,
Filter extends FilterableClient, FilterableClient extends FilterableGrpcClient,
FilterFactory extends GrpcClientFilterFactory> BlockingClient
buildBlocking(GrpcClientFactory clientFactory);
}
}