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

grpcstarter.server.GrpcRequestContextServerInterceptor Maven / Gradle / Ivy

package grpcstarter.server;

import static grpcstarter.server.GrpcContextKeys.ResponseMetadataModifier;

import io.grpc.Context;
import io.grpc.Contexts;
import io.grpc.ForwardingServerCall;
import io.grpc.Metadata;
import io.grpc.ServerCall;
import io.grpc.ServerCallHandler;
import io.grpc.ServerInterceptor;
import io.grpc.Status;
import java.util.Optional;
import org.springframework.core.PriorityOrdered;

/**
 * @author Freeman
 */
public class GrpcRequestContextServerInterceptor implements ServerInterceptor, PriorityOrdered {
    public static final Integer ORDER = 0;

    private final GrpcServerProperties grpcServerProperties;

    public GrpcRequestContextServerInterceptor(GrpcServerProperties grpcServerProperties) {
        this.grpcServerProperties = grpcServerProperties;
    }

    @Override
    public  ServerCall.Listener interceptCall(
            ServerCall call, Metadata headers, ServerCallHandler next) {
        Context context = Context.current()
                .withValue(GrpcRequestContext.INSTANCE, new GrpcRequestContext(call, headers))
                .withValue(ResponseMetadataModifier.INSTANCE, new ResponseMetadataModifier());
        Integer maxDescriptionLength = grpcServerProperties.getResponse().getMaxDescriptionLength();
        return Contexts.interceptCall(context, new ModifyResponseCall<>(call, maxDescriptionLength), headers, next);
    }

    @Override
    public int getOrder() {
        return ORDER;
    }

    private static final class ModifyResponseCall
            extends ForwardingServerCall.SimpleForwardingServerCall {

        private final int maxDescriptionLength;

        private ModifyResponseCall(ServerCall delegate, int maxDescriptionLength) {
            super(delegate);
            this.maxDescriptionLength = maxDescriptionLength;
        }

        @Override
        public void sendHeaders(Metadata headers) {

            setResponseMetadata(headers);

            super.sendHeaders(headers);
        }

        @Override
        public void close(Status status, Metadata trailers) {
            Metadata trailersToUse = Optional.ofNullable(trailers).orElseGet(Metadata::new);

            setResponseMetadata(trailersToUse);

            super.close(truncateDescriptionIfNecessary(status), trailersToUse);
        }

        private Status truncateDescriptionIfNecessary(Status status) {
            String description = status.getDescription();
            if (description != null && description.length() > maxDescriptionLength) {
                return status.withDescription(String.format(
                        "%s... (%d length)", description.substring(0, maxDescriptionLength), description.length()));
            }
            return status;
        }

        private static void setResponseMetadata(Metadata headers) {
            ResponseMetadataModifier responseMetadataModifier = ResponseMetadataModifier.get();
            if (responseMetadataModifier != null) {
                responseMetadataModifier.consumers.forEach(consumer -> consumer.accept(headers));
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy