All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.turbospaces.rpc.DefaultGrpcApiResponse Maven / Gradle / Ivy
package com.turbospaces.rpc;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import com.google.common.util.concurrent.FluentFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.common.util.concurrent.SettableFuture;
import com.google.protobuf.Message;
import com.turbospaces.api.facade.RequestWrapperFacade;
import com.turbospaces.api.facade.ResponseWrapperFacade;
import com.turbospaces.api.mappers.RequestFacadeMapper;
import api.v1.ApiFactory;
import api.v1.Headers;
import api.v1.ReplyUtil;
import io.cloudevents.core.builder.CloudEventBuilder;
import io.grpc.StatusRuntimeException;
import io.grpc.protobuf.StatusProto;
import io.vavr.CheckedConsumer;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class DefaultGrpcApiResponse extends AbstractApiResponse {
private final FluentFuture> subject;
private final RESP prototype;
public DefaultGrpcApiResponse(
ApiFactory apiFactory,
RequestWrapperFacade req,
ListenableFuture post,
RESP prototype) {
super(apiFactory, req);
this.prototype = Objects.requireNonNull(prototype);
SettableFuture> completable = SettableFuture.create();
RequestFacadeMapper requestMapper = apiFactory.requestMapper();
CloudEventBuilder eventTemplate = apiFactory.eventTemplate();
Headers headers = req.headers();
subject = FluentFuture.from(completable);
FluentFuture.from(post).addCallback(new FutureCallback() {
@Override
@SuppressWarnings("unchecked")
public void onSuccess(RESP result) {
ResponseWrapperFacade reply = apiFactory.requestMapper().toReply(
apiFactory.eventTemplate(),
req.headers(),
result,
api.v1.CacheControl.getDefaultInstance());
Class clazz = (Class) result.getClass();
completable.set(new DefaultApiResponseEntity<>(reply, clazz));
}
@Override
@SuppressWarnings("unchecked")
public void onFailure(Throwable t) {
log.error(t.getMessage(), t);
if (t instanceof StatusRuntimeException) {
com.google.rpc.Status orig = StatusProto.fromThrowable(t);
com.google.rpc.Code origCode = com.google.rpc.Code.forNumber(orig.getCode());
String msg = String.format(ReplyUtil.ERROR_FORMAT, req.headers().getMessageId());
Class clazz = (Class) prototype.getClass();
switch (origCode) {
case OK: {
var resp = requestMapper.toReply(eventTemplate, headers, prototype, api.v1.CacheControl.getDefaultInstance());
completable.set(new DefaultApiResponseEntity<>(resp, clazz));
break;
}
case NOT_FOUND: {
var resp = requestMapper.toExceptionalNotFoundReply(eventTemplate, headers, prototype, msg);
completable.set(new DefaultApiResponseEntity<>(resp, clazz));
break;
}
case PERMISSION_DENIED:
case UNAUTHENTICATED: {
var resp = requestMapper.toExceptionalAuthReply(eventTemplate, headers, prototype, msg);
completable.set(new DefaultApiResponseEntity<>(resp, clazz));
break;
}
case FAILED_PRECONDITION:
case OUT_OF_RANGE:
case INVALID_ARGUMENT: {
var resp = requestMapper.toExceptionalBadRequestReply(eventTemplate, headers, prototype, msg);
completable.set(new DefaultApiResponseEntity<>(resp, clazz));
break;
}
case UNAVAILABLE:
case DEADLINE_EXCEEDED: {
var resp = requestMapper.toExceptionalTimeoutReply(eventTemplate, headers, prototype, msg);
completable.set(new DefaultApiResponseEntity<>(resp, clazz));
break;
}
case INTERNAL:
case CANCELLED:
case ABORTED:
case ALREADY_EXISTS:
case DATA_LOSS:
case RESOURCE_EXHAUSTED:
case UNIMPLEMENTED:
case UNKNOWN:
case UNRECOGNIZED:
default: {
var resp = requestMapper.toExceptionalSystemReply(eventTemplate, headers, prototype, msg);
completable.set(new DefaultApiResponseEntity<>(resp, clazz));
break;
}
}
} else {
completable.setException(t);
}
}
}, MoreExecutors.directExecutor());
}
public DefaultGrpcApiResponse(ApiFactory apiFactory, RequestWrapperFacade req, FluentFuture> subject, RESP prototype) {
super(apiFactory, req);
this.subject = Objects.requireNonNull(subject);
this.prototype = Objects.requireNonNull(prototype);
}
@Override
public ApiResponseEntity get() throws InterruptedException, ExecutionException {
return subject.get();
}
@Override
public ApiResponseEntity get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
return subject.get(timeout, unit);
}
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return subject.cancel(mayInterruptIfRunning);
}
@Override
public boolean isCancelled() {
return subject.isCancelled();
}
@Override
public boolean isDone() {
return subject.isDone();
}
@Override
public void addListener(Runnable listener, Executor executor) {
subject.addListener(listener, executor);
}
@Override
public void addCallback(FutureCallback> callback, Executor executor) {
var wrapper = new FutureCallbackWrapper>(callback);
wrapper.setBootstrap(bootstrap);
subject.addCallback(isDone() ? callback : wrapper, executor);
}
@Override
public ApiResponse thenVerifyOkAndAccept(CheckedConsumer callback, Executor executor) {
SettableFuture> toReturn = SettableFuture.create();
subject.addCallback(new FutureCallback>() {
@Override
public void onSuccess(ApiResponseEntity result) {
boolean isOK = true;
try {
result.verifyOk();
} catch (Exception err) {
toReturn.setException(err);
isOK = false;
}
if (isOK) {
try {
RESP body = result.body();
callback.accept(body);
toReturn.set(result);
} catch (Throwable err) {
toReturn.setException(err);
}
}
}
@Override
public void onFailure(Throwable t) {
toReturn.setException(t);
}
}, executor);
//
// ~ new API response by contract
//
DefaultGrpcApiResponse resp = new DefaultGrpcApiResponse(apiFactory, requestWrapper, FluentFuture.from(toReturn), prototype);
resp.setBootstrap(bootstrap);
return resp;
}
}