From 249509508863545aa40ccfd2a8c7c030be3c340b Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:42:15 +0300 Subject: [PATCH 01/10] feat[ServletAdapter]: Ability remove context path when get method name Refs: #5066 --- .../main/java/io/grpc/servlet/ServletAdapter.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java index 5a567916f99..160aec9f83b 100644 --- a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java +++ b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java @@ -70,6 +70,7 @@ */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/5066") public final class ServletAdapter { + public static final String REMOVE_CONTEXT_PATH = "REMOVE_CONTEXT_PATH"; static final Logger logger = Logger.getLogger(ServletAdapter.class.getName()); @@ -119,7 +120,7 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx AsyncContext asyncCtx = req.startAsync(req, resp); - String method = req.getRequestURI().substring(1); // remove the leading "/" + String method = getMethod(req); Metadata headers = getHeaders(req); if (logger.isLoggable(FINEST)) { @@ -158,6 +159,15 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx asyncCtx.addListener(new GrpcAsyncListener(stream, logId)); } + private static String getMethod(HttpServletRequest req) { + Boolean removeContextPath = Boolean.parseBoolean(getInitParameter(REMOVE_CONTEXT_PATH)); + String method = req.getRequestURI(); + if (removeContextPath) { + method = method.substring(req.getContextPath().length()); // remove Context Path from application server + } + return method.substring(1); // remove the leading "/" + } + // This method must use Enumeration and its members, since that is the only way to read headers // from the servlet api. @SuppressWarnings("JdkObsolete") From 4bb9d650ce8908d43ce0b2aedd0cd9ac6ac1ea3c Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:58:33 +0300 Subject: [PATCH 02/10] fix: getMethod must be not static --- servlet/src/main/java/io/grpc/servlet/ServletAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java index 160aec9f83b..0b9a8f8965b 100644 --- a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java +++ b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java @@ -159,7 +159,7 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx asyncCtx.addListener(new GrpcAsyncListener(stream, logId)); } - private static String getMethod(HttpServletRequest req) { + private String getMethod(HttpServletRequest req) { Boolean removeContextPath = Boolean.parseBoolean(getInitParameter(REMOVE_CONTEXT_PATH)); String method = req.getRequestURI(); if (removeContextPath) { From 2f4aea57107e1b26eae1d78d371dfe1c84f835f9 Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:11:52 +0300 Subject: [PATCH 03/10] fix: wrong realisation --- .../src/main/java/io/grpc/servlet/GrpcServlet.java | 12 +++++++++++- .../main/java/io/grpc/servlet/ServletAdapter.java | 13 +------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java b/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java index f68ed083506..65b9471420b 100644 --- a/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java +++ b/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java @@ -36,6 +36,7 @@ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/5066") public class GrpcServlet extends HttpServlet { private static final long serialVersionUID = 1L; + public static final String REMOVE_CONTEXT_PATH = "REMOVE_CONTEXT_PATH"; private final ServletAdapter servletAdapter; @@ -58,6 +59,15 @@ private static ServletAdapter loadServices(List extends BindableService> binda return serverBuilder.buildServletAdapter(); } + private String getMethod(HttpServletRequest req) { + Boolean removeContextPath = Boolean.parseBoolean(getInitParameter(REMOVE_CONTEXT_PATH)); + String method = req.getRequestURI(); + if (removeContextPath) { + method = method.substring(req.getContextPath().length()); // remove Context Path from application server + } + return method.substring(1); // remove the leading "/" + } + @Override protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { @@ -67,7 +77,7 @@ protected final void doGet(HttpServletRequest request, HttpServletResponse respo @Override protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { - servletAdapter.doPost(request, response); + servletAdapter.doPost(getMethod(request), request, response); } @Override diff --git a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java index 0b9a8f8965b..0c3f2315d53 100644 --- a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java +++ b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java @@ -70,7 +70,6 @@ */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/5066") public final class ServletAdapter { - public static final String REMOVE_CONTEXT_PATH = "REMOVE_CONTEXT_PATH"; static final Logger logger = Logger.getLogger(ServletAdapter.class.getName()); @@ -111,7 +110,7 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOExc *
Do not modify {@code req} and {@code resp} before or after calling this method. However, * calling {@code resp.setBufferSize()} before invocation is allowed. */ - public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { + public void doPost(String method, HttpServletRequest req, HttpServletResponse resp) throws IOException { checkArgument(req.isAsyncSupported(), "servlet does not support asynchronous operation"); checkArgument(ServletAdapter.isGrpc(req), "the request is not a gRPC request"); @@ -120,7 +119,6 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx AsyncContext asyncCtx = req.startAsync(req, resp); - String method = getMethod(req); Metadata headers = getHeaders(req); if (logger.isLoggable(FINEST)) { @@ -159,15 +157,6 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOEx asyncCtx.addListener(new GrpcAsyncListener(stream, logId)); } - private String getMethod(HttpServletRequest req) { - Boolean removeContextPath = Boolean.parseBoolean(getInitParameter(REMOVE_CONTEXT_PATH)); - String method = req.getRequestURI(); - if (removeContextPath) { - method = method.substring(req.getContextPath().length()); // remove Context Path from application server - } - return method.substring(1); // remove the leading "/" - } - // This method must use Enumeration and its members, since that is the only way to read headers // from the servlet api. @SuppressWarnings("JdkObsolete") From 33ed4c66c5000b7a3b2d6d8f3d96ec69dcec8152 Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 18:24:48 +0300 Subject: [PATCH 04/10] fix[ServletAdapter]: java doc --- .../src/main/java/io/grpc/servlet/ServletAdapter.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java index 0c3f2315d53..f20b34bef4d 100644 --- a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java +++ b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java @@ -59,10 +59,11 @@ * process it, and transforms the gRPC response into {@link HttpServletResponse}. An adapter can be * instantiated by {@link ServletServerBuilder#buildServletAdapter()}. * - *
In a servlet, calling {@link #doPost(HttpServletRequest, HttpServletResponse)} inside {@link - * javax.servlet.http.HttpServlet#doPost(HttpServletRequest, HttpServletResponse)} makes the servlet - * backed by the gRPC server associated with the adapter. The servlet must support Asynchronous - * Processing and must be deployed to a container that supports servlet 4.0 and enables HTTP/2. + *
In a servlet, calling {@link #doPost(String, HttpServletRequest, HttpServletResponse)} inside + * {@link javax.servlet.http.HttpServlet#doPost(HttpServletRequest, HttpServletResponse)} makes + * the servlet backed by the gRPC server associated with the adapter. The servlet must support + * Asynchronous Processing and must be deployed to a container that supports servlet 4.0 + * and enables HTTP/2. * *
The API is experimental. The authors would like to know more about the real usecases. Users * are welcome to provide feedback by commenting on From 9ffaeb71439ccfd61da943f688f7f3e498bffc3d Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:01:46 +0300 Subject: [PATCH 05/10] fix: code style --- servlet/src/main/java/io/grpc/servlet/GrpcServlet.java | 3 ++- servlet/src/main/java/io/grpc/servlet/ServletAdapter.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java b/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java index 65b9471420b..5e9cec4a008 100644 --- a/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java +++ b/servlet/src/main/java/io/grpc/servlet/GrpcServlet.java @@ -63,7 +63,8 @@ private String getMethod(HttpServletRequest req) { Boolean removeContextPath = Boolean.parseBoolean(getInitParameter(REMOVE_CONTEXT_PATH)); String method = req.getRequestURI(); if (removeContextPath) { - method = method.substring(req.getContextPath().length()); // remove Context Path from application server + // remove context path used in application server + method = method.substring(req.getContextPath().length()); } return method.substring(1); // remove the leading "/" } diff --git a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java index f20b34bef4d..b6e0eabd502 100644 --- a/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java +++ b/servlet/src/main/java/io/grpc/servlet/ServletAdapter.java @@ -111,7 +111,8 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOExc *
Do not modify {@code req} and {@code resp} before or after calling this method. However, * calling {@code resp.setBufferSize()} before invocation is allowed. */ - public void doPost(String method, HttpServletRequest req, HttpServletResponse resp) throws IOException { + public void doPost(String method, HttpServletRequest req, HttpServletResponse resp) + throws IOException { checkArgument(req.isAsyncSupported(), "servlet does not support asynchronous operation"); checkArgument(ServletAdapter.isGrpc(req), "the request is not a gRPC request"); From bb7a6d42a94d6756f4a34b84083a1e1b7d9e519b Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:17:30 +0300 Subject: [PATCH 06/10] fix[ServletServerBuilderTest]: compile test --- .../src/test/java/io/grpc/servlet/ServletServerBuilderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java index d571cfd45d5..c51b7f2e588 100644 --- a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java +++ b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java @@ -78,7 +78,7 @@ public void scheduledExecutorService() throws Exception { ServletServerBuilder serverBuilder = new ServletServerBuilder().scheduledExecutorService(scheduler); ServletAdapter servletAdapter = serverBuilder.buildServletAdapter(); - servletAdapter.doPost(request, response); + servletAdapter.doPost(req.getRequestURI().substring(1), request, response); verify(asyncContext).setTimeout(1); From 2c1c2f1782ab394b726e3092b35579ef48e3f301 Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:31:26 +0300 Subject: [PATCH 07/10] fix[bb7a6d4]: var name --- .../src/test/java/io/grpc/servlet/ServletServerBuilderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java index c51b7f2e588..99410143bd0 100644 --- a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java +++ b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java @@ -78,7 +78,7 @@ public void scheduledExecutorService() throws Exception { ServletServerBuilder serverBuilder = new ServletServerBuilder().scheduledExecutorService(scheduler); ServletAdapter servletAdapter = serverBuilder.buildServletAdapter(); - servletAdapter.doPost(req.getRequestURI().substring(1), request, response); + servletAdapter.doPost(request.getRequestURI().substring(1), request, response); verify(asyncContext).setTimeout(1); From 27a99bc778b79b9e7bb2e3f9caf521c617f77fef Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:51:21 +0300 Subject: [PATCH 08/10] fix[HelloWorldServlet]: example --- .../io/grpc/servlet/examples/helloworld/HelloWorldServlet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example-servlet/src/main/java/io/grpc/servlet/examples/helloworld/HelloWorldServlet.java b/examples/example-servlet/src/main/java/io/grpc/servlet/examples/helloworld/HelloWorldServlet.java index a970c26a119..2f0a5f149b1 100644 --- a/examples/example-servlet/src/main/java/io/grpc/servlet/examples/helloworld/HelloWorldServlet.java +++ b/examples/example-servlet/src/main/java/io/grpc/servlet/examples/helloworld/HelloWorldServlet.java @@ -64,7 +64,7 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { if (ServletAdapter.isGrpc(request)) { - servletAdapter.doPost(request, response); + servletAdapter.doPost("helloworld.Greeter/SayHello", request, response); } else { response.setContentType("text/html"); response.getWriter().println("
Hello non-gRPC client!
"); From 21e48bebb720fff38912be65f11da563c4411c51 Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 20:11:20 +0300 Subject: [PATCH 09/10] fix[ServletServerBuilderTest]: use verify --- .../src/test/java/io/grpc/servlet/ServletServerBuilderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java index 99410143bd0..8f030e0bfdc 100644 --- a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java +++ b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java @@ -78,7 +78,7 @@ public void scheduledExecutorService() throws Exception { ServletServerBuilder serverBuilder = new ServletServerBuilder().scheduledExecutorService(scheduler); ServletAdapter servletAdapter = serverBuilder.buildServletAdapter(); - servletAdapter.doPost(request.getRequestURI().substring(1), request, response); + servletAdapter.doPost(verify(request).getRequestURI().substring(1), request, response); verify(asyncContext).setTimeout(1); From ed0fdbde97a92d85ebbd8ab042550b247b7d264c Mon Sep 17 00:00:00 2001 From: long76 <18124433+long76@users.noreply.github.com> Date: Mon, 9 Dec 2024 20:28:25 +0300 Subject: [PATCH 10/10] fix: use hardcoded method --- .../src/test/java/io/grpc/servlet/ServletServerBuilderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java index 8f030e0bfdc..40f75b97d72 100644 --- a/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java +++ b/servlet/src/test/java/io/grpc/servlet/ServletServerBuilderTest.java @@ -78,7 +78,7 @@ public void scheduledExecutorService() throws Exception { ServletServerBuilder serverBuilder = new ServletServerBuilder().scheduledExecutorService(scheduler); ServletAdapter servletAdapter = serverBuilder.buildServletAdapter(); - servletAdapter.doPost(verify(request).getRequestURI().substring(1), request, response); + servletAdapter.doPost("hello/world", request, response); verify(asyncContext).setTimeout(1);