From 7c7a4f8cd06011c30bf4119e2c9381e4c6d5207c Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Wed, 7 Aug 2024 20:42:44 +0530 Subject: [PATCH 01/15] added custom accesslog filter --- .../gjex/core/context/AccessLogContext.java | 17 +++++--- .../core/filter/grpc/AccessLogGrpcFilter.java | 17 +++----- .../filter/CustomAccessLogFilter.java | 39 +++++++++++++++++++ .../helloworld/guice/HelloWorldModule.java | 4 +- .../helloworld/service/GreeterService.java | 4 +- .../grpc/interceptor/FilterInterceptor.java | 22 ++++++++++- 6 files changed, 83 insertions(+), 20 deletions(-) create mode 100644 examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java diff --git a/core/src/main/java/com/flipkart/gjex/core/context/AccessLogContext.java b/core/src/main/java/com/flipkart/gjex/core/context/AccessLogContext.java index 6873357d..d4633408 100644 --- a/core/src/main/java/com/flipkart/gjex/core/context/AccessLogContext.java +++ b/core/src/main/java/com/flipkart/gjex/core/context/AccessLogContext.java @@ -16,13 +16,15 @@ */ @Builder public class AccessLogContext { - String clientIp; - String resourcePath; - Integer contentLength; - Long responseTime; - Integer responseStatus; + private String clientIp; + private String resourcePath; + private Integer contentLength; + private Long responseTime; + private Integer responseStatus; @Builder.Default - Map headers = new HashMap<>(); + private Map headers = new HashMap<>(); + @Builder.Default + protected Map customFields = new HashMap<>(); /** @@ -42,6 +44,9 @@ private Map getValueMap() { for (Map.Entry entry : headers.entrySet()) { params.put("headers." + entry.getKey(), entry.getValue()); } + for (Map.Entry entry : customFields.entrySet()) { + params.put("custom." + entry.getKey(), entry.getValue()); + } params.put("thread", Thread.currentThread().getName()); return params; } 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 258d086b..413e0e2e 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 @@ -21,6 +21,8 @@ import com.google.protobuf.GeneratedMessageV3; import io.grpc.Metadata; import io.grpc.Status; +import lombok.Getter; +import lombok.Setter; import org.slf4j.Logger; import java.util.Map; @@ -47,9 +49,11 @@ public class AccessLogGrpcFilter requestParamsInput) { startTime = System.currentTimeMillis(); - accessLogContextBuilder = AccessLogContext.builder() + accessLogContextBuilder .clientIp(requestParamsInput.getClientIp()) .resourcePath(requestParamsInput.getResourcePath()); diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java new file mode 100644 index 00000000..cb1884c7 --- /dev/null +++ b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java @@ -0,0 +1,39 @@ +package com.flipkart.gjex.examples.helloworld.filter; + +import com.flipkart.gjex.core.filter.RequestParams; +import com.flipkart.gjex.core.filter.grpc.AccessLogGrpcFilter; +import com.flipkart.gjex.core.filter.grpc.GrpcFilter; +import com.google.protobuf.GeneratedMessageV3; + +import javax.inject.Named; +import java.util.HashMap; + +/** + * CustomAccessLogFilter extending {@link AccessLogGrpcFilter} + * + * @author ajay.jalgaonkar + */ +@Named("CustomAccessLogFilter") +public class CustomAccessLogFilter extends AccessLogGrpcFilter { + private static final String format = "{custom.className} {clientIp} {resourcePath} " + + "{contentLength} {responseStatus} {responseTime}"; + private static final HashMap customFields = new HashMap<>(); + + @Override + public void init() { + setFormat(format); + customFields.put("className", this.getClass().getSimpleName()); + } + + @Override + public void doProcessRequest(GeneratedMessageV3 req, RequestParams requestParamsInput) { + getAccessLogContextBuilder().customFields(customFields); + super.doProcessRequest(req, requestParamsInput); + } + + + @Override + public GrpcFilter getInstance() { + return new CustomAccessLogFilter(); + } +} 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 060c188d..250c0e22 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 @@ -19,6 +19,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.CustomAccessLogFilter; import com.flipkart.gjex.examples.helloworld.filter.LoggingFilter; import com.flipkart.gjex.examples.helloworld.service.GreeterService; import com.flipkart.gjex.examples.helloworld.tracing.AllWhitelistTracingSampler; @@ -50,11 +51,12 @@ 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("CustomAccessLogFilter")).to(CustomAccessLogFilter.class); bind(GrpcFilter.class).annotatedWith(Names.named("AuthFilter")).to(AuthFilter.class); // bind(AccessLogGrpcFilter.class).to(AccessLogTestFilter.class); bind(TracingSampler.class).to(AllWhitelistTracingSampler.class); bind(ResourceConfig.class).annotatedWith(Names.named("HelloWorldResourceConfig")).to(HelloWorldResourceConfig.class); - bind(JavaxFilterParams.class).annotatedWith(Names.named("ExampleJavaxFilter")) + 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 b98c78a9..bb185aa5 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 @@ -19,6 +19,7 @@ import javax.inject.Named; import com.flipkart.gjex.examples.helloworld.filter.AuthFilter; +import com.flipkart.gjex.examples.helloworld.filter.CustomAccessLogFilter; 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,8 @@ 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, AuthFilter.class, CustomAccessLogFilter.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 95865915..0198a93d 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 @@ -24,6 +24,7 @@ import com.flipkart.gjex.core.logging.Logging; import com.flipkart.gjex.core.util.Pair; import com.flipkart.gjex.grpc.utils.AnnotationUtils; +import io.grpc.Attributes; import io.grpc.BindableService; import io.grpc.Context; import io.grpc.ForwardingServerCall.SimpleForwardingServerCall; @@ -150,7 +151,7 @@ public void onHalfClose() { public void onMessage(Req request) { Context previous = attachContext(contextWithHeaders); // attaching headers to gRPC context RequestParams requestParams = RequestParams.builder() - .clientIp(call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR).toString()) + .clientIp(getClientIp(call.getAttributes())) .resourcePath(call.getMethodDescriptor().getFullMethodName().toLowerCase()) .metadata(headers) .build(); @@ -227,4 +228,23 @@ private void configureAccessLog(GrpcFilterConfig grpcFilterConfig, filtersForMethod.add(accessLogGrpcFilter); } } + + private String getClientIp(Attributes attributes){ + if (attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR) != null){ + String ipAddressString = attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR).toString(); + if (StringUtils.isNotEmpty(ipAddressString)){ + if (ipAddressString.startsWith("/")){ + ipAddressString = ipAddressString.split("/", 2)[1]; + } + } + if (StringUtils.isNotEmpty(ipAddressString)){ + int portIndex = ipAddressString.lastIndexOf(":"); + if (portIndex != -1){ + ipAddressString = ipAddressString.substring(0, portIndex); + } + } + return ipAddressString; + } + return null; + } } From b1282ad6bafbd040f2f3382bdd6a946553e46ce2 Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Wed, 7 Aug 2024 20:46:56 +0530 Subject: [PATCH 02/15] made static --- .../com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0198a93d..3eef4d99 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 @@ -229,7 +229,7 @@ private void configureAccessLog(GrpcFilterConfig grpcFilterConfig, } } - private String getClientIp(Attributes attributes){ + private static String getClientIp(Attributes attributes){ if (attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR) != null){ String ipAddressString = attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR).toString(); if (StringUtils.isNotEmpty(ipAddressString)){ From 343b4212c0a8009bba6b48d5ebc568b95ac0603c Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 10:16:32 +0530 Subject: [PATCH 03/15] removed import --- core/src/main/java/com/flipkart/gjex/core/filter/Filter.java | 2 -- 1 file changed, 2 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 8a6b27e5..cb59bfd6 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 @@ -15,8 +15,6 @@ */ package com.flipkart.gjex.core.filter; -import com.flipkart.gjex.core.logging.Logging; - /** * A Filter interface for processing Request, Request-Headers, Response and Response-Headers * around gRPC and HTTP method invocation From 173c895eff0206cd66d3537e5b953888a282b8e6 Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 13:44:15 +0530 Subject: [PATCH 04/15] removed --- examples/build.gradle | 2 +- .../filter/CustomAccessLogFilter.java | 39 ------------------- .../helloworld/guice/HelloWorldModule.java | 2 - .../helloworld/service/GreeterService.java | 3 +- 4 files changed, 2 insertions(+), 44 deletions(-) delete mode 100644 examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java diff --git a/examples/build.gradle b/examples/build.gradle index 70866749..7ba3e149 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -89,7 +89,7 @@ task runHelloWorldServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath mainClass = 'com.flipkart.gjex.examples.helloworld.HelloWorldApplication' args "server", "./src/main/resources/hello_world_config.yml" - jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED' +// jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED' } diff --git a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java b/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java deleted file mode 100644 index cb1884c7..00000000 --- a/examples/src/main/java/com/flipkart/gjex/examples/helloworld/filter/CustomAccessLogFilter.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.flipkart.gjex.examples.helloworld.filter; - -import com.flipkart.gjex.core.filter.RequestParams; -import com.flipkart.gjex.core.filter.grpc.AccessLogGrpcFilter; -import com.flipkart.gjex.core.filter.grpc.GrpcFilter; -import com.google.protobuf.GeneratedMessageV3; - -import javax.inject.Named; -import java.util.HashMap; - -/** - * CustomAccessLogFilter extending {@link AccessLogGrpcFilter} - * - * @author ajay.jalgaonkar - */ -@Named("CustomAccessLogFilter") -public class CustomAccessLogFilter extends AccessLogGrpcFilter { - private static final String format = "{custom.className} {clientIp} {resourcePath} " + - "{contentLength} {responseStatus} {responseTime}"; - private static final HashMap customFields = new HashMap<>(); - - @Override - public void init() { - setFormat(format); - customFields.put("className", this.getClass().getSimpleName()); - } - - @Override - public void doProcessRequest(GeneratedMessageV3 req, RequestParams requestParamsInput) { - getAccessLogContextBuilder().customFields(customFields); - super.doProcessRequest(req, requestParamsInput); - } - - - @Override - public GrpcFilter getInstance() { - return new CustomAccessLogFilter(); - } -} 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 250c0e22..0a5b7595 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 @@ -19,7 +19,6 @@ 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.CustomAccessLogFilter; import com.flipkart.gjex.examples.helloworld.filter.LoggingFilter; import com.flipkart.gjex.examples.helloworld.service.GreeterService; import com.flipkart.gjex.examples.helloworld.tracing.AllWhitelistTracingSampler; @@ -51,7 +50,6 @@ 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("CustomAccessLogFilter")).to(CustomAccessLogFilter.class); bind(GrpcFilter.class).annotatedWith(Names.named("AuthFilter")).to(AuthFilter.class); // bind(AccessLogGrpcFilter.class).to(AccessLogTestFilter.class); bind(TracingSampler.class).to(AllWhitelistTracingSampler.class); 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 bb185aa5..4915eeab 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 @@ -19,7 +19,6 @@ import javax.inject.Named; import com.flipkart.gjex.examples.helloworld.filter.AuthFilter; -import com.flipkart.gjex.examples.helloworld.filter.CustomAccessLogFilter; import io.dropwizard.metrics5.annotation.Timed; import com.flipkart.gjex.core.filter.grpc.ApplicationHeaders; import com.flipkart.gjex.core.filter.grpc.MethodFilters; @@ -69,7 +68,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, CustomAccessLogFilter.class}) // Method + @MethodFilters({LoggingFilter.class, AuthFilter.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) { From 95c0e319c5badc610c218aba25c9bc34f8c9315e Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 13:44:29 +0530 Subject: [PATCH 05/15] removed --- examples/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/build.gradle b/examples/build.gradle index 7ba3e149..70866749 100644 --- a/examples/build.gradle +++ b/examples/build.gradle @@ -89,7 +89,7 @@ task runHelloWorldServer(type: JavaExec) { classpath = sourceSets.main.runtimeClasspath mainClass = 'com.flipkart.gjex.examples.helloworld.HelloWorldApplication' args "server", "./src/main/resources/hello_world_config.yml" -// jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED' + jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED' } From 0dd7ec52a925d8a1f8a8552a335c230c999c9f9f Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 13:45:51 +0530 Subject: [PATCH 06/15] removed --- .../gjex/examples/helloworld/service/GreeterService.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 4915eeab..b98c78a9 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 @@ -68,8 +68,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, AuthFilter.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) { From 2b08faad9e4e9aedaf48fe1b04d13e2c6c1e8768 Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 14:01:46 +0530 Subject: [PATCH 07/15] removed --- .../flipkart/gjex/core/filter/http/AccessLogHttpFilter.java | 6 ++++-- .../gjex/http/interceptor/HttpFilterInterceptor.java | 5 ++--- 2 files changed, 6 insertions(+), 5 deletions(-) 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 ded5f8ae..1c32a102 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 @@ -3,12 +3,12 @@ import com.flipkart.gjex.core.context.AccessLogContext; import com.flipkart.gjex.core.filter.RequestParams; import com.flipkart.gjex.core.logging.Logging; -import io.netty.handler.codec.http.HttpHeaderNames; import org.slf4j.Logger; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.HttpHeaders; import java.util.Map; import java.util.Optional; @@ -84,7 +84,9 @@ public void doProcessResponse(ServletResponse response) { HttpServletResponse httpServletResponse = (HttpServletResponse) response; if (isSuccess(httpServletResponse.getStatus())) { // 2xx response - int contentLength = Optional.ofNullable(httpServletResponse.getHeader(HttpHeaderNames.CONTENT_LENGTH.toString())) + // TODO: check case where GET response is successful by content-length is -1. + int contentLength = + Optional.ofNullable(httpServletResponse.getHeader(HttpHeaders.CONTENT_LENGTH)) .map(Integer::parseInt).orElse(0); accessLogContextBuilder.contentLength(contentLength); } else { diff --git a/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java b/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java index 0de4f000..c4ab53d4 100644 --- a/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java +++ b/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java @@ -115,12 +115,11 @@ protected static String getFullURL(HttpServletRequest request) { * @return The real IP address of the client */ protected static String getClientIp(ServletRequest request) { - String remoteAddr = request.getRemoteAddr(); String xForwardedFor = ((HttpServletRequest) request).getHeader("X-Forwarded-For"); if (xForwardedFor != null) { - remoteAddr = xForwardedFor.split(",")[0]; + return xForwardedFor.split(",")[0]; } - return remoteAddr; + return request.getRemoteAddr(); } protected List getMatchingFilters(String path) { From d8ed0a3156c8ef0d1a9714fca0b40491e6aa661c Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 18:00:23 +0530 Subject: [PATCH 08/15] added test case --- .../grpc/interceptor/FilterInterceptor.java | 37 ++++++++++++------- .../interceptor/FilterInterceptorTest.java | 26 +++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) create mode 100644 guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java 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 3eef4d99..42a36282 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 @@ -42,6 +42,8 @@ import javax.inject.Singleton; import javax.validation.ConstraintViolationException; import java.lang.reflect.Method; +import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -151,7 +153,7 @@ public void onHalfClose() { public void onMessage(Req request) { Context previous = attachContext(contextWithHeaders); // attaching headers to gRPC context RequestParams requestParams = RequestParams.builder() - .clientIp(getClientIp(call.getAttributes())) + .clientIp(getClientIp(call.getAttributes().get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR))) .resourcePath(call.getMethodDescriptor().getFullMethodName().toLowerCase()) .metadata(headers) .build(); @@ -229,22 +231,29 @@ private void configureAccessLog(GrpcFilterConfig grpcFilterConfig, } } - private static String getClientIp(Attributes attributes){ - if (attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR) != null){ - String ipAddressString = attributes.get(Grpc.TRANSPORT_ATTR_REMOTE_ADDR).toString(); - if (StringUtils.isNotEmpty(ipAddressString)){ - if (ipAddressString.startsWith("/")){ - ipAddressString = ipAddressString.split("/", 2)[1]; + protected static String getClientIp(SocketAddress socketAddress){ + if (socketAddress != null){ + if (socketAddress instanceof InetSocketAddress){ + String ipAddressString = + ((InetSocketAddress) socketAddress).getAddress().toString(); + if (StringUtils.isNotEmpty(ipAddressString)){ + int startIndex = ipAddressString.indexOf("/"); + if (startIndex != -1){ + ipAddressString = ipAddressString.substring(startIndex + 1); + } } - } - if (StringUtils.isNotEmpty(ipAddressString)){ - int portIndex = ipAddressString.lastIndexOf(":"); - if (portIndex != -1){ - ipAddressString = ipAddressString.substring(0, portIndex); + if (StringUtils.isNotEmpty(ipAddressString)){ + int endIndex = ipAddressString.lastIndexOf(":"); + if (endIndex != -1){ + ipAddressString = ipAddressString.substring(0, endIndex); + } + } + if (StringUtils.isNotEmpty(ipAddressString)){ + return ipAddressString; } } - return ipAddressString; + return socketAddress.toString(); } - return null; + return "0.0.0.0"; } } diff --git a/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java new file mode 100644 index 00000000..fedfb0d4 --- /dev/null +++ b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java @@ -0,0 +1,26 @@ +package com.flipkart.gjex.grpc.interceptor; + +import org.junit.Assert; +import org.junit.Test; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +public class FilterInterceptorTest { + private static final String IP_ADDRESS = "1.2.3.4"; + + @Test + public void getClientIpTest(){ + InetSocketAddress inetSocketAddress = new InetSocketAddress(IP_ADDRESS, 1234); + Assert.assertEquals(IP_ADDRESS, FilterInterceptor.getClientIp(inetSocketAddress)); + + SocketAddress socketAddress = new SocketAddress() { + @Override + public String toString() { + return IP_ADDRESS; + } + }; + Assert.assertEquals(IP_ADDRESS, FilterInterceptor.getClientIp(socketAddress)); + } + +} From aaa4a64706336a9f1092a72fd1a66605f980061b Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 18:13:11 +0530 Subject: [PATCH 09/15] added test case --- .../gjex/grpc/interceptor/FilterInterceptorTest.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java index fedfb0d4..e1a4c7f1 100644 --- a/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java +++ b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java @@ -3,15 +3,16 @@ import org.junit.Assert; import org.junit.Test; +import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; public class FilterInterceptorTest { - private static final String IP_ADDRESS = "1.2.3.4"; + private static final String IP_ADDRESS = "0.0.0.0"; @Test public void getClientIpTest(){ - InetSocketAddress inetSocketAddress = new InetSocketAddress(IP_ADDRESS, 1234); + InetSocketAddress inetSocketAddress = new InetSocketAddress(1234); Assert.assertEquals(IP_ADDRESS, FilterInterceptor.getClientIp(inetSocketAddress)); SocketAddress socketAddress = new SocketAddress() { From 85b5a80b8b4dd36c125c837648c7b5b4e104934e Mon Sep 17 00:00:00 2001 From: "naman.soni" Date: Thu, 8 Aug 2024 18:13:59 +0530 Subject: [PATCH 10/15] added --- .../flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java index e1a4c7f1..26f87a19 100644 --- a/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java +++ b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java @@ -3,7 +3,6 @@ import org.junit.Assert; import org.junit.Test; -import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; From f72e94041bdb13ffc48388aae4699917b9e4b922 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Fri, 9 Aug 2024 17:26:36 +0530 Subject: [PATCH 11/15] test cases --- .../flipkart/gjex/core/util/NetworkUtils.java | 31 +++++++++ .../gjex/core/util/NetworkUtilsTest.java | 64 +++++++++++++++++++ .../grpc/interceptor/FilterInterceptor.java | 33 ++++------ .../interceptor/FilterInterceptorTest.java | 50 +++++++++++++-- 4 files changed, 149 insertions(+), 29 deletions(-) create mode 100644 core/src/main/java/com/flipkart/gjex/core/util/NetworkUtils.java create mode 100644 core/src/test/java/com/flipkart/gjex/core/util/NetworkUtilsTest.java diff --git a/core/src/main/java/com/flipkart/gjex/core/util/NetworkUtils.java b/core/src/main/java/com/flipkart/gjex/core/util/NetworkUtils.java new file mode 100644 index 00000000..5f7e9495 --- /dev/null +++ b/core/src/main/java/com/flipkart/gjex/core/util/NetworkUtils.java @@ -0,0 +1,31 @@ +package com.flipkart.gjex.core.util; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class NetworkUtils { + + private static final Pattern[] ipAddressPattern = { + Pattern.compile( "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"), + Pattern.compile("((([0-9a-fA-F]){1,4})\\:){7}([0-9a-fA-F]){1,4}") + }; + + + /** + * Extracts the IP address from a given string. + * + * @param str The input string from which the IP address is to be extracted. + * @return The IP address extracted from the input string. + */ + public static String extractIPAddress(String str) { + if (str != null) { + for (Pattern pattern : ipAddressPattern) { + Matcher matcher = pattern.matcher(str); + if (matcher.find()) { + return matcher.group(); + } + } + } + return "0.0.0.0"; + } +} diff --git a/core/src/test/java/com/flipkart/gjex/core/util/NetworkUtilsTest.java b/core/src/test/java/com/flipkart/gjex/core/util/NetworkUtilsTest.java new file mode 100644 index 00000000..539b5b42 --- /dev/null +++ b/core/src/test/java/com/flipkart/gjex/core/util/NetworkUtilsTest.java @@ -0,0 +1,64 @@ +package com.flipkart.gjex.core.util; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class NetworkUtilsTest { + + + @Test + public void extractIPAddressReturnsIPv4Address() { + String input = "User IP is 192.168.1.1 and should be extracted"; + String result = NetworkUtils.extractIPAddress(input); + assertEquals("192.168.1.1", result); + } + + @Test + public void extractIPAddressReturnsIPv6Address() { + String input = "User IP is 2001:0db8:85a3:0000:0000:8a2e:0370:7334 and should be extracted"; + String result = NetworkUtils.extractIPAddress(input); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", result); + } + + @Test + public void extractIPAddressReturnsFirstIPv4AddressWhenMultiplePresent() { + String input = "User IPs are 192.168.1.1 and 10.0.0.1, first one should be extracted"; + String result = NetworkUtils.extractIPAddress(input); + assertEquals("192.168.1.1", result); + } + + @Test + public void extractIPAddressReturnsWithPrefix() { + String input = "/192.168.1.1:1234"; + String result = NetworkUtils.extractIPAddress(input); + assertEquals("192.168.1.1", result); + } + + @Test + public void extractIPAddressReturnsFirstIPv6AddressWhenMultiplePresent() { + String input = "User IPs are 2001:0db8:85a3:0000:0000:8a2e:0370:7334 and fe80::1ff:fe23:4567:890a, first one should be extracted"; + String result = NetworkUtils.extractIPAddress(input); + assertEquals("2001:0db8:85a3:0000:0000:8a2e:0370:7334", result); + } + + @Test + public void extractIPFromStringReturnsDefaultWhenNoIPPresent() { + String input = "No IP address in this string"; + String result = NetworkUtils.extractIPAddress(input); + assertEquals("0.0.0.0", result); + } + + @Test + public void extractIPAddress() { + String input = ""; + String result = NetworkUtils.extractIPAddress(input); + assertEquals("0.0.0.0", result); + } + + @Test + public void extractIPAddressHandlesNullInput() { + String result = NetworkUtils.extractIPAddress(null); + assertEquals("0.0.0.0", result); + } +} 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 42a36282..af9934cc 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 @@ -22,9 +22,9 @@ import com.flipkart.gjex.core.filter.grpc.GrpcFilterConfig; import com.flipkart.gjex.core.filter.grpc.MethodFilters; import com.flipkart.gjex.core.logging.Logging; +import com.flipkart.gjex.core.util.NetworkUtils; import com.flipkart.gjex.core.util.Pair; import com.flipkart.gjex.grpc.utils.AnnotationUtils; -import io.grpc.Attributes; import io.grpc.BindableService; import io.grpc.Context; import io.grpc.ForwardingServerCall.SimpleForwardingServerCall; @@ -231,29 +231,18 @@ private void configureAccessLog(GrpcFilterConfig grpcFilterConfig, } } - protected static String getClientIp(SocketAddress socketAddress){ - if (socketAddress != null){ - if (socketAddress instanceof InetSocketAddress){ - String ipAddressString = - ((InetSocketAddress) socketAddress).getAddress().toString(); - if (StringUtils.isNotEmpty(ipAddressString)){ - int startIndex = ipAddressString.indexOf("/"); - if (startIndex != -1){ - ipAddressString = ipAddressString.substring(startIndex + 1); - } - } - if (StringUtils.isNotEmpty(ipAddressString)){ - int endIndex = ipAddressString.lastIndexOf(":"); - if (endIndex != -1){ - ipAddressString = ipAddressString.substring(0, endIndex); - } - } - if (StringUtils.isNotEmpty(ipAddressString)){ - return ipAddressString; - } + protected static String getClientIp(SocketAddress socketAddress) { + if (socketAddress != null) { + if (socketAddress instanceof InetSocketAddress inetSocketAddress) { + return inetSocketAddress.getHostName(); + } else { + // handle other scenarios use regex + String socketAddressString = socketAddress.toString(); + NetworkUtils.extractIPAddress(socketAddressString); } - return socketAddress.toString(); } return "0.0.0.0"; } + + } diff --git a/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java index 26f87a19..248a486d 100644 --- a/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java +++ b/guice/src/test/java/com/flipkart/gjex/grpc/interceptor/FilterInterceptorTest.java @@ -1,26 +1,62 @@ package com.flipkart.gjex.grpc.interceptor; -import org.junit.Assert; import org.junit.Test; import java.net.InetSocketAddress; import java.net.SocketAddress; +import static org.junit.Assert.assertEquals; + public class FilterInterceptorTest { - private static final String IP_ADDRESS = "0.0.0.0"; @Test - public void getClientIpTest(){ - InetSocketAddress inetSocketAddress = new InetSocketAddress(1234); - Assert.assertEquals(IP_ADDRESS, FilterInterceptor.getClientIp(inetSocketAddress)); + public void getClientIpReturnsHostNameForInetSocketAddress() { + InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost", 1234); + String result = FilterInterceptor.getClientIp(inetSocketAddress); + assertEquals("localhost", result); + } + @Test + public void getClientIpReturnsExtractedIpForNonInetSocketAddress() { SocketAddress socketAddress = new SocketAddress() { @Override public String toString() { - return IP_ADDRESS; + return "192.168.1.1:1234"; } }; - Assert.assertEquals(IP_ADDRESS, FilterInterceptor.getClientIp(socketAddress)); + String result = FilterInterceptor.getClientIp(socketAddress); + assertEquals("192.168.1.1", result); + } + + @Test + public void getClientIpReturnsDefaultIpForNullSocketAddress() { + String result = FilterInterceptor.getClientIp(null); + assertEquals("0.0.0.0", result); } + @Test + public void getClientIpReturnsExtractedIpForGRPCSocketAddress() { + SocketAddress socketAddress = new SocketAddress() { + @Override + public String toString() { + return "/192.168.1.1:1234"; + } + }; + String result = FilterInterceptor.getClientIp(socketAddress); + assertEquals("192.168.1.1", result); + } + + @Test + public void getClientIpReturnsExtractedFirstIpForGRPCSocketAddress() { + SocketAddress socketAddress = new SocketAddress() { + @Override + public String toString() { + return "192.168.1.1/192.168.1.2:1234"; + } + }; + String result = FilterInterceptor.getClientIp(socketAddress); + assertEquals("192.168.1.1", result); + } + + } From b03f093d4af7e03a35bcbe154b63440a2d947787 Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Fri, 9 Aug 2024 17:29:30 +0530 Subject: [PATCH 12/15] Update FilterInterceptor.java --- .../com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 af9934cc..fa6d9b42 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 @@ -233,8 +233,8 @@ private void configureAccessLog(GrpcFilterConfig grpcFilterConfig, protected static String getClientIp(SocketAddress socketAddress) { if (socketAddress != null) { - if (socketAddress instanceof InetSocketAddress inetSocketAddress) { - return inetSocketAddress.getHostName(); + if (socketAddress instanceof InetSocketAddress) { + return ((InetSocketAddress)socketAddress).getHostName(); } else { // handle other scenarios use regex String socketAddressString = socketAddress.toString(); From 6eb3ca0746a54ddf0f578b8da193760455cb049d Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Sat, 10 Aug 2024 18:07:19 +0530 Subject: [PATCH 13/15] Update AccessLogHttpFilter.java --- .../com/flipkart/gjex/core/filter/http/AccessLogHttpFilter.java | 1 + 1 file changed, 1 insertion(+) 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 f966954e..5e198ff6 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 @@ -3,6 +3,7 @@ import com.flipkart.gjex.core.context.AccessLogContext; import com.flipkart.gjex.core.filter.RequestParams; import com.flipkart.gjex.core.logging.Logging; +import io.netty.handler.codec.http.HttpHeaderNames; import org.slf4j.Logger; import javax.servlet.ServletRequest; From c4fe6c25df18948e59aa3658c9800b93b7409bda Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Sat, 10 Aug 2024 18:09:29 +0530 Subject: [PATCH 14/15] Update FilterInterceptor.java --- .../com/flipkart/gjex/grpc/interceptor/FilterInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d89dc9f1..d3877457 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 @@ -226,7 +226,7 @@ protected static String getClientIp(SocketAddress socketAddress) { } else { // handle other scenarios use regex String socketAddressString = socketAddress.toString(); - NetworkUtils.extractIPAddress(socketAddressString); + return NetworkUtils.extractIPAddress(socketAddressString); } } return "0.0.0.0"; From 850a83b3c6d9722ae510843021d38df29edada3c Mon Sep 17 00:00:00 2001 From: Kinshuk Bairagi Date: Sat, 10 Aug 2024 18:10:41 +0530 Subject: [PATCH 15/15] Update HttpFilterInterceptor.java --- .../gjex/http/interceptor/HttpFilterInterceptor.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java b/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java index 5c26779c..07635174 100644 --- a/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java +++ b/guice/src/main/java/com/flipkart/gjex/http/interceptor/HttpFilterInterceptor.java @@ -131,11 +131,12 @@ protected static String getFullURL(HttpServletRequest request) { * @return The real IP address of the client */ protected static String getClientIp(ServletRequest request) { + String remoteAddr = request.getRemoteAddr(); String xForwardedFor = ((HttpServletRequest) request).getHeader("X-Forwarded-For"); if (xForwardedFor != null) { - return xForwardedFor.split(",")[0]; + remoteAddr = xForwardedFor.split(",")[0]; } - return request.getRemoteAddr(); + return remoteAddr; } protected List getMatchingFilters(String path) {