All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.inverno.mod.grpc.server.internal.GenericGrpcExchange Maven / Gradle / Ivy

There is a newer version: 1.12.0
Show newest version
/*
 * Copyright 2024 Jeremy Kuhn
 *
 * 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.inverno.mod.grpc.server.internal;

import com.google.protobuf.Message;
import io.inverno.mod.base.resource.MediaTypes;
import io.inverno.mod.grpc.base.GrpcException;
import io.inverno.mod.grpc.base.GrpcHeaders;
import io.inverno.mod.grpc.base.GrpcStatus;
import io.inverno.mod.grpc.server.GrpcExchange;
import io.inverno.mod.grpc.server.GrpcRequest;
import io.inverno.mod.grpc.server.GrpcResponse;
import io.inverno.mod.http.base.ExchangeContext;
import io.inverno.mod.http.base.Status;
import io.inverno.mod.http.server.Exchange;
import io.inverno.mod.http.server.ResetStreamException;
import io.netty.handler.codec.http2.Http2Error;
import java.util.Optional;
import java.util.function.Supplier;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * 

* Generic {@link GrpcExchange} implementation. *

* * @author Jeremy Kuhn * @since 1.9 * * @param The exchange context type * @param The request message type * @param The response message type * @param the request type * @param the response type */ public class GenericGrpcExchange, E extends GrpcResponse> implements GrpcExchange { public static final Logger LOGGER = LogManager.getLogger(GrpcExchange.class); /** * The underlying HTTP server exchange. */ private final Exchange exchange; /** * The gRPC request supplier. */ private final Supplier requestSupplier; /** * The gRPC response supplier. */ private final Supplier responseSupplier; /** * The gRPC request. */ private D request; /** * The gRPC response. */ private E response; /** * The cancel cause. */ private Optional cancelCause; /** *

* Creates a generic gRPC exchange. *

* * @param exchange the HTTP server exchange * @param requestSupplier the gRPC request supplier * @param responseSupplier the gRPC response supplier */ public GenericGrpcExchange(Exchange
exchange, Supplier requestSupplier, Supplier responseSupplier) { this.exchange = exchange; this.requestSupplier = requestSupplier; this.responseSupplier = responseSupplier; this.exchange.response().headers(headers -> headers.status(Status.OK).contentType(MediaTypes.APPLICATION_GRPC_PROTO)); this.exchange.response().trailers(trailers -> trailers.set(GrpcHeaders.NAME_GRPC_STATUS, Integer.toString(GrpcStatus.OK.getCode()))); } @Override public A context() { return this.exchange.context(); } @Override public D request() { if(this.request == null) { this.request = this.requestSupplier.get(); } return this.request; } @Override public E response() { if(this.response == null) { this.response = this.responseSupplier.get(); } return this.response; } @Override public void cancel() { this.exchange.reset(Http2Error.CANCEL.code()); } @Override public Optional getCancelCause() { if(this.cancelCause == null || this.cancelCause.isEmpty()) { this.cancelCause = this.exchange.getCancelCause().map(e -> { if(e instanceof GrpcException) { return (GrpcException)e; } else if(e instanceof ResetStreamException && ((ResetStreamException)e).getErrorCode() == Http2Error.CANCEL.code()) { return new GrpcException(GrpcStatus.CANCELLED, e); } return new GrpcException(GrpcStatus.UNKNOWN, e); }); } return this.cancelCause; } /** *

* Generic {@link GrpcExchange.Unary} implementation. *

* * @author
Jeremy Kuhn * @since 1.9 * * @param the exchange context type * @param the request message type * @param the response message type */ public static class GenericUnary extends GenericGrpcExchange, GrpcResponse.Unary> implements GrpcExchange.Unary { /** *

* Creates a generic unary gRPC exchange. *

* * @param exchange the HTTP server exchange * @param requestSupplier the gRPC request supplier * @param responseSupplier the gRPC response supplier */ public GenericUnary(Exchange
exchange, Supplier> requestSupplier, Supplier> responseSupplier) { super(exchange, requestSupplier, responseSupplier); } } /** *

* Generic {@link GrpcExchange.ClientStreaming} implementation. *

* * @author
Jeremy Kuhn * @since 1.9 * * @param the exchange context type * @param the request message type * @param the response message type */ public static class GenericClientStreaming extends GenericGrpcExchange, GrpcResponse.Unary> implements GrpcExchange.ClientStreaming { /** *

* Creates a generic client streaming gRPC exchange. *

* * @param exchange the HTTP server exchange * @param requestSupplier the gRPC request supplier * @param responseSupplier the gRPC response supplier */ public GenericClientStreaming(Exchange
exchange, Supplier> requestSupplier, Supplier> responseSupplier) { super(exchange, requestSupplier, responseSupplier); } } /** *

* Generic {@link GrpcExchange.ServerStreaming} implementation. *

* * @author
Jeremy Kuhn * @since 1.9 * * @param the exchange context type * @param the request message type * @param the response message type */ public static class GenericServerStreaming extends GenericGrpcExchange, GrpcResponse.Streaming> implements GrpcExchange.ServerStreaming { /** *

* Creates a generic server streaming gRPC exchange. *

* * @param exchange the HTTP server exchange * @param requestSupplier the gRPC request supplier * @param responseSupplier the gRPC response supplier */ public GenericServerStreaming(Exchange
exchange, Supplier> requestSupplier, Supplier> responseSupplier) { super(exchange, requestSupplier, responseSupplier); } } /** *

* Generic {@link GrpcExchange.BidirectionalStreaming} implementation. *

* * @author
Jeremy Kuhn * @since 1.9 * * @param the exchange context type * @param the request message type * @param the response message type */ public static class GenericBidirectionalStreaming extends GenericGrpcExchange, GrpcResponse.Streaming> implements GrpcExchange.BidirectionalStreaming { /** *

* Creates a generic bidirectional streaming gRPC exchange. *

* * @param exchange the HTTP server exchange * @param requestSupplier the gRPC request supplier * @param responseSupplier the gRPC response supplier */ public GenericBidirectionalStreaming(Exchange
exchange, Supplier> requestSupplier, Supplier> responseSupplier) { super(exchange, requestSupplier, responseSupplier); } } }