From e5472c7b7b80bc4a10bb24bada9e8293dfe95f6e Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Wed, 21 Aug 2024 19:11:49 +0530 Subject: [PATCH 1/4] Grpc filter --- .../filter/CustomHeaderGRPCFilter.java | 34 +++++++++++++++++++ .../helloworld/guice/HelloWorldModule.java | 4 ++- .../helloworld/service/GreeterService.java | 3 +- .../grpc/interceptor/FilterInterceptor.java | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java new file mode 100644 index 00000000..c31ea450 --- /dev/null +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java @@ -0,0 +1,34 @@ +package com.flipkart.gjex.examples.helloworld.filter; + +import com.flipkart.gjex.core.filter.grpc.GrpcFilter; +import com.flipkart.gjex.core.logging.Logging; +import com.google.protobuf.GeneratedMessageV3; +import io.grpc.Metadata; + +import javax.inject.Named; + +@Named("CustomHeaderGRPCFilter") +public class CustomHeaderGRPCFilter extends GrpcFilter implements Logging { + + @Override + public void doProcessResponseHeaders(Metadata responseHeaders) { + super.doProcessResponseHeaders(responseHeaders); + responseHeaders.put(Metadata.Key.of("x-custom-header1", Metadata.ASCII_STRING_MARSHALLER), "value1"); + } + + @Override + public void doProcessResponse(Res response) { + + +// response = (Res) ((HelloReply) response).toBuilder().setMessage("Custom Header GRPC Filter").build(); + super.doProcessResponse(response); + + // Add custom header to response +// response.toBuilder().setHeader("x-custom-header2", "value2"); + } + + @Override + public GrpcFilter getInstance() { + return new CustomHeaderGRPCFilter<>(); + } +} diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java index 546818dc..6dbffe35 100644 --- a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java @@ -20,6 +20,7 @@ import com.flipkart.gjex.core.filter.http.JavaxFilterParams; import com.flipkart.gjex.core.tracing.TracingSampler; import com.flipkart.gjex.examples.helloworld.filter.AuthFilter; +import com.flipkart.gjex.examples.helloworld.filter.CustomHeaderGRPCFilter; import com.flipkart.gjex.examples.helloworld.filter.CustomHeaderHttpFilter; import com.flipkart.gjex.examples.helloworld.filter.LoggingFilter; import com.flipkart.gjex.examples.helloworld.service.GreeterService; @@ -52,7 +53,8 @@ protected void configure() { bind(GreeterGrpc.GreeterBlockingStub.class).toInstance(GreeterGrpc.newBlockingStub(channel)); bind(BindableService.class).annotatedWith(Names.named("GreeterService")).to(GreeterService.class); bind(GrpcFilter.class).annotatedWith(Names.named("LoggingFilter")).to(LoggingFilter.class); - bind(GrpcFilter.class).annotatedWith(Names.named("AuthFilter")).to(AuthFilter.class); + bind(GrpcFilter.class).annotatedWith(Names.named("AuthFilter")).to(AuthFilter.class); + bind(CustomHeaderGRPCFilter.class).annotatedWith(Names.named("CustomHeaderGRPCFilter")).to(CustomHeaderGRPCFilter.class); bind(TracingSampler.class).to(AllWhitelistTracingSampler.class); bind(ResourceConfig.class).annotatedWith(Names.named("HelloWorldResourceConfig")).to(HelloWorldResourceConfig.class); bind(JavaxFilterParams.class).annotatedWith(Names.named("ExampleJavaxFilter")).toInstance(JavaxFilterParams.builder().filter(new ExampleJavaxFilter()).pathSpec("/*").build()); diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/service/GreeterService.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/service/GreeterService.java index 4b6bcb06..7a613729 100644 --- a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/service/GreeterService.java +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/service/GreeterService.java @@ -20,6 +20,7 @@ import com.flipkart.gjex.core.context.GJEXContext; import com.flipkart.gjex.examples.helloworld.filter.AuthFilter; +import com.flipkart.gjex.examples.helloworld.filter.CustomHeaderGRPCFilter; import io.dropwizard.metrics5.annotation.Timed; import com.flipkart.gjex.core.filter.grpc.ApplicationHeaders; import com.flipkart.gjex.core.filter.grpc.MethodFilters; @@ -68,7 +69,7 @@ public GreeterService(@Named("hw.greeting") String greeting, HelloBeanService he @Override @Api(deadlineConfig = "apiProperties.sayhello.deadline") // specify an API level Deadline that will cascade to all @ConcurrentTask invoked in serving this API @Timed // the Timed annotation for publishing JMX metrics via MBean - @MethodFilters({LoggingFilter.class, AuthFilter.class}) // Method level filters + @MethodFilters({LoggingFilter.class, CustomHeaderGRPCFilter.class}) // Method level filters @Traced(withSamplingRate=0.0f) // Start a new Trace or participate in a Client-initiated distributed trace public void sayHello(HelloRequest req, StreamObserver responseObserver) { diff --git a/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java b/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java index 98d9bc7c..6514f0ab 100644 --- a/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java +++ b/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java @@ -121,7 +121,7 @@ public Listener interceptCall(ServerCall call, Metadat ServerCall.Listener listener = next.startCall(new SimpleForwardingServerCall(call) { @Override - public void sendMessage(final Res response) { + public void sendMessage(Res response) { Context previous = attachContext(contextWithHeaders); // attaching headers to gRPC context try { grpcFilters.forEach(filter -> filter.doProcessResponse(response)); From 0da5edf161b44730bb255c3e5ad872ed481084e1 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Wed, 21 Aug 2024 19:46:34 +0530 Subject: [PATCH 2/4] Allow modification of response from filters --- .../java/com/flipkart/gjex/core/filter/Filter.java | 5 ++++- .../gjex/core/filter/grpc/AccessLogGrpcFilter.java | 3 ++- .../flipkart/gjex/core/filter/grpc/GrpcFilter.java | 3 +-- .../gjex/core/filter/http/AccessLogHttpFilter.java | 4 +++- .../helloworld/filter/CustomHeaderGRPCFilter.java | 14 ++++++-------- .../helloworld/filter/CustomHeaderHttpFilter.java | 4 +++- .../examples/helloworld/filter/LoggingFilter.java | 3 ++- .../helloworld/guice/HelloWorldModule.java | 2 +- .../gjex/grpc/interceptor/FilterInterceptor.java | 4 +++- 9 files changed, 25 insertions(+), 17 deletions(-) diff --git a/core/src/main/java/com/flipkart/gjex/core/filter/Filter.java b/core/src/main/java/com/flipkart/gjex/core/filter/Filter.java index 4e1a02f0..544aaa0c 100644 --- a/core/src/main/java/com/flipkart/gjex/core/filter/Filter.java +++ b/core/src/main/java/com/flipkart/gjex/core/filter/Filter.java @@ -54,8 +54,11 @@ public void doProcessResponseHeaders(M responseHeaders) {} * This method should be viewed almost like a proxy for the Response body. * * @param response the Response body/message + * @return */ - public void doProcessResponse(Res response) {} + public Res doProcessResponse(Res response) { + return response; + } /** * Call-back to handle exceptions that occur during the processing of the request or response. diff --git a/core/src/main/java/com/flipkart/gjex/core/filter/grpc/AccessLogGrpcFilter.java b/core/src/main/java/com/flipkart/gjex/core/filter/grpc/AccessLogGrpcFilter.java index 426009c0..0a93e766 100644 --- a/core/src/main/java/com/flipkart/gjex/core/filter/grpc/AccessLogGrpcFilter.java +++ b/core/src/main/java/com/flipkart/gjex/core/filter/grpc/AccessLogGrpcFilter.java @@ -108,13 +108,14 @@ public void doProcessResponseHeaders(Metadata responseHeaders) { * @param response The outgoing gRPC response message. */ @Override - public void doProcessResponse(S response) { + public S doProcessResponse(S response) { accessLogContextBuilder .contentLength(response.getSerializedSize()) .responseTime(System.currentTimeMillis() - startTime) .responseStatus(Status.Code.OK.value()) .build(); logger.info(accessLogContextBuilder.build().format(format)); + return response; } /** diff --git a/core/src/main/java/com/flipkart/gjex/core/filter/grpc/GrpcFilter.java b/core/src/main/java/com/flipkart/gjex/core/filter/grpc/GrpcFilter.java index fd9ff701..805b219a 100644 --- a/core/src/main/java/com/flipkart/gjex/core/filter/grpc/GrpcFilter.java +++ b/core/src/main/java/com/flipkart/gjex/core/filter/grpc/GrpcFilter.java @@ -26,8 +26,7 @@ * @param Proto V3 message * @author ajay.jalgaonkar */ -public abstract class GrpcFilter - extends Filter { +public abstract class GrpcFilter extends Filter { /** * Function for creating an instance of this {@link Filter} diff --git a/core/src/main/java/com/flipkart/gjex/core/filter/http/AccessLogHttpFilter.java b/core/src/main/java/com/flipkart/gjex/core/filter/http/AccessLogHttpFilter.java index c7102c51..65208e7b 100644 --- a/core/src/main/java/com/flipkart/gjex/core/filter/http/AccessLogHttpFilter.java +++ b/core/src/main/java/com/flipkart/gjex/core/filter/http/AccessLogHttpFilter.java @@ -84,9 +84,10 @@ public void doProcessResponseHeaders(Map responseHeaders) { * Logs the client IP, requested URI, response status, content length, and the time taken to process the request. * * @param response The outgoing servlet response. + * @return */ @Override - public void doProcessResponse(ServletResponse response) { + public ServletResponse doProcessResponse(ServletResponse response) { HttpServletResponse httpServletResponse = (HttpServletResponse) response; if (isSuccess(httpServletResponse.getStatus())) { // 2xx response @@ -103,6 +104,7 @@ public void doProcessResponse(ServletResponse response) { .responseStatus(httpServletResponse.getStatus()) .responseTime(System.currentTimeMillis() - startTime); logger.info(accessLogContextBuilder.build().format(format)); + return response; } @Override diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java index c31ea450..49b3f17e 100644 --- a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderGRPCFilter.java @@ -1,11 +1,14 @@ package com.flipkart.gjex.examples.helloworld.filter; +import com.flipkart.gjex.core.filter.RequestParams; import com.flipkart.gjex.core.filter.grpc.GrpcFilter; import com.flipkart.gjex.core.logging.Logging; import com.google.protobuf.GeneratedMessageV3; import io.grpc.Metadata; +import io.grpc.examples.helloworld.HelloReply; import javax.inject.Named; +import java.util.Optional; @Named("CustomHeaderGRPCFilter") public class CustomHeaderGRPCFilter extends GrpcFilter implements Logging { @@ -17,14 +20,9 @@ public void doProcessResponseHeaders(Metadata responseHeaders) { } @Override - public void doProcessResponse(Res response) { - - -// response = (Res) ((HelloReply) response).toBuilder().setMessage("Custom Header GRPC Filter").build(); - super.doProcessResponse(response); - - // Add custom header to response -// response.toBuilder().setHeader("x-custom-header2", "value2"); + public Res doProcessResponse(Res response) { + response = (Res) ((HelloReply) response).toBuilder().setMessage("Custom Header GRPC Filter").build(); + return response; } @Override diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderHttpFilter.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderHttpFilter.java index 4149ee93..686c8158 100644 --- a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderHttpFilter.java +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomHeaderHttpFilter.java @@ -50,12 +50,14 @@ public void doProcessResponseHeaders(Map responseHeaders) { * Processes the response and also adds a custom header. * * @param response the servlet response + * @return */ @Override - public void doProcessResponse(ServletResponse response) { + public ServletResponse doProcessResponse(ServletResponse response) { super.doProcessResponse(response); HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.addHeader("x-custom-header2", "value2"); + return response; } @Override diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/LoggingFilter.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/LoggingFilter.java index a37e2330..36b1e32c 100644 --- a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/LoggingFilter.java +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/LoggingFilter.java @@ -49,8 +49,9 @@ public void doProcessResponseHeaders(Metadata responseHeaders) { } @Override - public void doProcessResponse(Res response) { + public Res doProcessResponse(Res response) { info("Logging from filter. Response payload is : " + response.toString()); + return response; } diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java index 6dbffe35..dd79d15d 100644 --- a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/guice/HelloWorldModule.java @@ -54,7 +54,7 @@ protected void configure() { bind(BindableService.class).annotatedWith(Names.named("GreeterService")).to(GreeterService.class); bind(GrpcFilter.class).annotatedWith(Names.named("LoggingFilter")).to(LoggingFilter.class); bind(GrpcFilter.class).annotatedWith(Names.named("AuthFilter")).to(AuthFilter.class); - bind(CustomHeaderGRPCFilter.class).annotatedWith(Names.named("CustomHeaderGRPCFilter")).to(CustomHeaderGRPCFilter.class); + bind(GrpcFilter.class).annotatedWith(Names.named("CustomHeaderGRPCFilter")).to(CustomHeaderGRPCFilter.class); bind(TracingSampler.class).to(AllWhitelistTracingSampler.class); bind(ResourceConfig.class).annotatedWith(Names.named("HelloWorldResourceConfig")).to(HelloWorldResourceConfig.class); bind(JavaxFilterParams.class).annotatedWith(Names.named("ExampleJavaxFilter")).toInstance(JavaxFilterParams.builder().filter(new ExampleJavaxFilter()).pathSpec("/*").build()); diff --git a/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java b/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java index 6514f0ab..e6370039 100644 --- a/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java +++ b/guice/src/main/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java @@ -124,7 +124,9 @@ public Listener interceptCall(ServerCall call, Metadat public void sendMessage(Res response) { Context previous = attachContext(contextWithHeaders); // attaching headers to gRPC context try { - grpcFilters.forEach(filter -> filter.doProcessResponse(response)); + for (GrpcFilter f : grpcFilters) { + response = (Res) f.doProcessResponse(response); + } super.sendMessage(response); } finally { detachContext(contextWithHeaders, previous); // detach headers from gRPC context From a106ae3e57dd1bb27d4cd1b83173507eff5edefa Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Wed, 21 Aug 2024 23:48:53 +0530 Subject: [PATCH 3/4] Update CreateLoggingFilter.java --- .../com/flipkart/grpc/jexpress/filter/CreateLoggingFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/CreateLoggingFilter.java b/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/CreateLoggingFilter.java index 0a851968..e8c5bca9 100644 --- a/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/CreateLoggingFilter.java +++ b/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/CreateLoggingFilter.java @@ -44,8 +44,9 @@ public void doProcessRequest(CreateRequest request, RequestParams requ public void doProcessResponseHeaders(Metadata responseHeaders) {} @Override - public void doProcessResponse(CreateResponse response) { + public CreateResponse doProcessResponse(CreateResponse response) { info("Response: " + response); + return response; } } From 88ca66b145ffd694093e83e9357f60707acc3b78 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Thu, 22 Aug 2024 01:27:58 +0530 Subject: [PATCH 4/4] Update GetLoggingFilter.java --- .../com/flipkart/grpc/jexpress/filter/GetLoggingFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/GetLoggingFilter.java b/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/GetLoggingFilter.java index fb420f53..680b0dbf 100644 --- a/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/GetLoggingFilter.java +++ b/grpc-jexpress-template/src/main/java/com/flipkart/grpc/jexpress/filter/GetLoggingFilter.java @@ -46,8 +46,9 @@ public void doProcessResponseHeaders(Metadata reponseHeaders) { } @Override - public void doProcessResponse(GetResponse response) { + public GetResponse doProcessResponse(GetResponse response) { info("Response: " + response); + return response; } }