-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
servlet: Implement gRPC server as a Servlet (#8596)
Full end to end implementation of gRPC server as a Servlet including tests and examples Co-authored-by: Penn (Dapeng) Zhang <zdapeng@google.com> Co-authored-by: Chengyuan Zhang <chengyuanzhang@google.com>
- Loading branch information
1 parent
44847bf
commit 706646f
Showing
29 changed files
with
3,387 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Hello World Example using Servlets | ||
|
||
This example uses Java Servlets instead of Netty for the gRPC server. This example requires `grpc-java` | ||
and `protoc-gen-grpc-java` to already be built. You are strongly encouraged to check out a git release | ||
tag, since these builds will already be available. | ||
|
||
```bash | ||
git checkout v<major>.<minor>.<patch> | ||
``` | ||
Otherwise, you must follow [COMPILING](../../COMPILING.md). | ||
|
||
To build the example, | ||
|
||
1. **[Install gRPC Java library SNAPSHOT locally, including code generation plugin](../../COMPILING.md) (Only need this step for non-released versions, e.g. master HEAD).** | ||
|
||
2. In this directory, build the war file | ||
```bash | ||
$ ../gradlew war | ||
``` | ||
|
||
To run this, deploy the war, now found in `build/libs/example-servlet.war` to your choice of servlet | ||
container. Note that this container must support the Servlet 4.0 spec, for this particular example must | ||
use `javax.servlet` packages instead of the more modern `jakarta.servlet`, though there is a `grpc-servlet-jakarta` | ||
artifact that can be used for Jakarta support. Be sure to enable http/2 support in the servlet container, | ||
or clients will not be able to connect. | ||
|
||
To test that this is working properly, build the HelloWorldClient example and direct it to connect to your | ||
http/2 server. From the parent directory: | ||
|
||
1. Build the executables: | ||
```bash | ||
$ ../gradlew installDist | ||
``` | ||
2. Run the client app, specifying the name to say hello to and the server's address: | ||
```bash | ||
$ ./build/install/examples/bin/hello-world-client World localhost:8080 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
plugins { | ||
// ASSUMES GRADLE 5.6 OR HIGHER. Use plugin version 0.8.10 with earlier gradle versions | ||
id 'com.google.protobuf' version '0.8.17' | ||
// Generate IntelliJ IDEA's .idea & .iml project files | ||
id 'idea' | ||
id 'war' | ||
} | ||
|
||
repositories { | ||
maven { // The google mirror is less flaky than mavenCentral() | ||
url "https://maven-central.storage-download.googleapis.com/maven2/" } | ||
mavenLocal() | ||
} | ||
|
||
sourceCompatibility = 1.8 | ||
targetCompatibility = 1.8 | ||
|
||
def grpcVersion = '1.53.0-SNAPSHOT' // CURRENT_GRPC_VERSION | ||
def protocVersion = '3.21.7' | ||
|
||
dependencies { | ||
implementation "io.grpc:grpc-protobuf:${grpcVersion}", | ||
"io.grpc:grpc-servlet:${grpcVersion}", | ||
"io.grpc:grpc-stub:${grpcVersion}" | ||
|
||
providedImplementation "javax.servlet:javax.servlet-api:4.0.1", | ||
"org.apache.tomcat:annotations-api:6.0.53" | ||
} | ||
|
||
protobuf { | ||
protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" } | ||
plugins { grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" } } | ||
generateProtoTasks { | ||
all()*.plugins { grpc {} } | ||
} | ||
} | ||
|
||
// Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code. | ||
sourceSets { | ||
main { | ||
java { | ||
srcDirs 'build/generated/source/proto/main/grpc' | ||
srcDirs 'build/generated/source/proto/main/java' | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
pluginManagement { | ||
repositories { | ||
maven { // The google mirror is less flaky than mavenCentral() | ||
url "https://maven-central.storage-download.googleapis.com/maven2/" | ||
} | ||
gradlePluginPortal() | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
.../example-servlet/src/main/java/io/grpc/servlet/examples/helloworld/HelloWorldServlet.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
* Copyright 2018 The gRPC Authors | ||
* | ||
* 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.grpc.servlet.examples.helloworld; | ||
|
||
import io.grpc.stub.StreamObserver; | ||
import io.grpc.examples.helloworld.GreeterGrpc; | ||
import io.grpc.examples.helloworld.HelloReply; | ||
import io.grpc.examples.helloworld.HelloRequest; | ||
import io.grpc.servlet.ServletAdapter; | ||
import io.grpc.servlet.ServletServerBuilder; | ||
import java.io.IOException; | ||
import javax.servlet.annotation.WebServlet; | ||
import javax.servlet.http.HttpServlet; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
|
||
/** | ||
* A servlet that hosts a gRPC server over HTTP/2 and shares the resource URI for the normal servlet | ||
* clients over HTTP/1.0+. | ||
* | ||
* <p>For creating a servlet that solely serves gRPC services, do not follow this example, simply | ||
* extend or register a {@link io.grpc.servlet.GrpcServlet} instead. | ||
*/ | ||
@WebServlet(urlPatterns = {"/helloworld.Greeter/SayHello"}, asyncSupported = true) | ||
public class HelloWorldServlet extends HttpServlet { | ||
private static final long serialVersionUID = 1L; | ||
|
||
private final ServletAdapter servletAdapter = | ||
new ServletServerBuilder().addService(new GreeterImpl()).buildServletAdapter(); | ||
|
||
private static final class GreeterImpl extends GreeterGrpc.GreeterImplBase { | ||
GreeterImpl() {} | ||
|
||
@Override | ||
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) { | ||
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build(); | ||
responseObserver.onNext(reply); | ||
responseObserver.onCompleted(); | ||
} | ||
} | ||
|
||
@Override | ||
protected void doGet(HttpServletRequest request, HttpServletResponse response) | ||
throws IOException { | ||
response.setContentType("text/html"); | ||
response.getWriter().println("<p>Hello World!</p>"); | ||
} | ||
|
||
@Override | ||
protected void doPost(HttpServletRequest request, HttpServletResponse response) | ||
throws IOException { | ||
if (ServletAdapter.isGrpc(request)) { | ||
servletAdapter.doPost(request, response); | ||
} else { | ||
response.setContentType("text/html"); | ||
response.getWriter().println("<p>Hello non-gRPC client!</p>"); | ||
} | ||
} | ||
|
||
@Override | ||
public void destroy() { | ||
servletAdapter.destroy(); | ||
super.destroy(); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
examples/example-servlet/src/main/proto/helloworld/helloworld.proto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Copyright 2015 The gRPC Authors | ||
// | ||
// 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. | ||
syntax = "proto3"; | ||
|
||
option java_multiple_files = true; | ||
option java_package = "io.grpc.examples.helloworld"; | ||
option java_outer_classname = "HelloWorldProto"; | ||
option objc_class_prefix = "HLW"; | ||
|
||
package helloworld; | ||
|
||
// The greeting service definition. | ||
service Greeter { | ||
// Sends a greeting | ||
rpc SayHello (HelloRequest) returns (HelloReply) {} | ||
} | ||
|
||
// The request message containing the user's name. | ||
message HelloRequest { | ||
string name = 1; | ||
} | ||
|
||
// The response message containing the greetings | ||
message HelloReply { | ||
string message = 1; | ||
} |
6 changes: 6 additions & 0 deletions
6
examples/example-servlet/src/main/webapp/WEB-INF/glassfish-web.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- Need this file for deployment to GlassFish --> | ||
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" "http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd"> | ||
<glassfish-web-app error-url=""> | ||
<class-loader delegate="false"/> | ||
</glassfish-web-app> |
9 changes: 9 additions & 0 deletions
9
examples/example-servlet/src/main/webapp/WEB-INF/jboss-web.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- Need this file for deployment to WildFly --> | ||
<jboss-web xmlns="http://www.jboss.com/xml/ns/javaee" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation=" | ||
http://www.jboss.com/xml/ns/javaee | ||
http://www.jboss.org/j2ee/schema/jboss-web_5_1.xsd"> | ||
<context-root>/</context-root> | ||
</jboss-web> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.