com.salesforce.reactorgrpc.stub.ClientCalls Maven / Gradle / Ivy
/*
* Copyright (c) 2017, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
package com.salesforce.reactorgrpc.stub;
import com.google.common.util.concurrent.Runnables;
import com.salesforce.grpc.contrib.LambdaStreamObserver;
import com.salesforce.reactivegrpccommon.CancellableStreamObserver;
import com.salesforce.reactivegrpccommon.ReactiveProducerStreamObserver;
import io.grpc.stub.StreamObserver;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.publisher.Operators;
import java.util.function.BiConsumer;
import java.util.function.Function;
/**
* Utility functions for processing different client call idioms. We have one-to-one correspondence
* between utilities in this class and the potential signatures in a generated stub client class so
* that the runtime can vary behavior without requiring regeneration of the stub.
*/
public final class ClientCalls {
private ClientCalls() {
}
/**
* Implements a unary -> unary call using {@link Mono} -> {@link Mono}.
*/
public static Mono oneToOne(
Mono rxRequest,
BiConsumer> delegate) {
try {
return Mono
.create(emitter -> rxRequest.subscribe(
request -> delegate.accept(request, new LambdaStreamObserver(
emitter::success,
emitter::error,
Runnables.doNothing()
)),
emitter::error
))
.transform(Operators.lift(new SubscribeOnlyOnceLifter()));
} catch (Throwable throwable) {
return Mono.error(throwable);
}
}
/**
* Implements a unary -> stream call as {@link Mono} -> {@link Flux}, where the server responds with a
* stream of messages.
*/
public static Flux oneToMany(
Mono rxRequest,
BiConsumer> delegate) {
try {
ReactorConsumerStreamObserver consumerStreamObserver = new ReactorConsumerStreamObserver<>();
rxRequest.subscribe(request -> delegate.accept(request, consumerStreamObserver));
return ((Flux) consumerStreamObserver.getRxConsumer())
.transform(Operators.lift(new SubscribeOnlyOnceLifter()));
} catch (Throwable throwable) {
return Flux.error(throwable);
}
}
/**
* Implements a stream -> unary call as {@link Flux} -> {@link Mono}, where the client transits a stream of
* messages.
*/
public static Mono manyToOne(
Flux rxRequest,
Function, StreamObserver> delegate) {
try {
return Mono
.create(emitter -> {
ReactiveProducerStreamObserver reactiveProducerStreamObserver = new ReactiveProducerStreamObserver<>(
rxRequest,
emitter::success,
emitter::error,
Runnables.doNothing());
delegate.apply(
new CancellableStreamObserver<>(reactiveProducerStreamObserver,
reactiveProducerStreamObserver::cancel));
reactiveProducerStreamObserver.rxSubscribe();
})
.transform(Operators.lift(new SubscribeOnlyOnceLifter()));
} catch (Throwable throwable) {
return Mono.error(throwable);
}
}
/**
* Implements a bidirectional stream -> stream call as {@link Flux} -> {@link Flux}, where both the client
* and the server independently stream to each other.
*/
public static Flux manyToMany(
Flux rxRequest,
Function, StreamObserver> delegate) {
try {
ReactorProducerConsumerStreamObserver consumerStreamObserver = new ReactorProducerConsumerStreamObserver<>(rxRequest);
delegate.apply(new CancellableStreamObserver<>(consumerStreamObserver, consumerStreamObserver::cancel));
consumerStreamObserver.rxSubscribe();
return ((Flux) consumerStreamObserver.getRxConsumer())
.transform(Operators.lift(new SubscribeOnlyOnceLifter()));
} catch (Throwable throwable) {
return Flux.error(throwable);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy