The RESTEasy grpc-bridge facility supports exposing Jakarta RESTful Web Services resources to gRPC clients. See the RESTEasy User Guide for a more detailed discussion of the various mechanisms and classes involved.
There are a number of pieces to create, and this maven archetype includes a pom.xml which incorporates the steps necessary to create them.
gRPCtoJakartaREST_archetype takes the GAV of an existing Jakarta RESTful Web Services project, called the target project, and creates a new project which can generate a WAR with a copy of the target project plus all of the pieces needed for a gRPC client to interface with the copy of the target project. We will refer to the generated project as the corresponding gRPC bridge project.
To create a gRPC bridge project from an existing project, the archetype needs several pieces of information:
-
the GAV of the target project
-
the intended GAV of the gRPC bridge project
-
"generate-prefix" parameter: the prefix to use for names of generated classes
-
"generate-package" parameter: the Java package to use for generated classes
-
"resteasy-version" parameter
-
"grpc-bridge-version" parameter
For example,
mvn archetype:generate -B \
-DarchetypeGroupId=dev.resteasy.grpc \
-DarchetypeArtifactId=gRPCtoJakartaREST-archetype \
-DarchetypeVersion=1.0.0.Alpha5 \
-DgroupId=dev.resteasy.examples \
-DartifactId=grpcToRest.example \
-Dversion=1.0.0.Final-SNAPSHOT \
-Dgenerate-prefix=Greet \
-Dgenerate-package=dev.resteasy.example.grpc.greet \
-Dresteasy-version=6.2.4.Final \
-Dgrpc-bridge-version=1.0.0.Alpha2
Note that "grpc-bridge-version" is the version of the RESTEasy project grpc-bridge.
See https://github.com/resteasy/resteasy-examples/grpc-bridge-example for the sample code mentioned here.
The result is a new gRPC bridge maven project named by its artifactId. Its initial contents are
-
pom.xml
-
a web.xml file with suggested builtin Jakarta REST provider configuration
-
an empty beans.xml file
-
a buildjar shell script which can package all of the necessary files in a JAR file
-
a deployjar shell script which can deploy the JAR file [probably needs to be adjusted according to the environment]
Building the gRPC bridge project downloads the contents of the target project and builds all of the generated classes described in the RESTEasy User Guide.
The following parameters are optional:
-
classes: necessary entity / response classes not detected by the heuristic in
dev.resteasy.grpc.bridge.generator.protobuf.JavaToProtobufGenerator
in grpc-bridge -
inWildfly: "true" if and only if the gRPC bridge willl run in a version of WildFly supplied with the grpc subsystem. Defaults to "true".
-
release-type: "snapshot" or "release", determines where the deployjar should deploy to, but that will probably have to be tailored appropriately.
The "classes" parameter has the syntax
(source-directory ':' fully-qualified-name) [',' source-directory ':' fully-qualified-name]*
For example,
export SRC=/home/rsigal/git.grpc.test/restful.example.grpc/restful.example/src/main/java
mvn -Dclasses=${SRC}:jakarta.rest.example.CC7,${SRC}:jakarta.rest.example.CC6 clean install
This will run the java protoc compiler, with the grpc plugin, and the generator classes in the grpc-bridge project, and the bridge project will be populated as follows
-
the src directory will be copied from the target project
-
src/main/proto will hold the
<generate-prefix>.proto
file (generated bydev.resteasy.grpc.bridge.generator.protobuf.JavaToProtobufGenerator
) -
target/generated-sources/protobuf/java will hold
<generate-prefix>_proto.java
, compiled from<generate-prefix>.proto
-
target/generated-sources/protobuf/grpc-java will hold the following generated classes:
A.
<generate-prefix>ServiceGrpc.java
(generated by the gRPC plugin to the protobuf compiler)B.
<generate-prefix>ServiceGrpcImpl.java
(generated bydev.resteasy.grpc.bridge.generator.ServiceGrpcExtender
)C.
<generate-prefix>JavabufTranslator.java
(generated bydev.resteasy.grpc.bridge.generator.protobuf.JavabufTranslatorGenerator
)D.
<generate-prefix>MessageBodyReaderWriter.java
(generated bydev.resteasy.grpc.bridge.generator.protobuf.ReaderWriterGenerator
)E.
<generate-prefix>_Server.java
(generated bydev.resteasy.grpc.bridge.generator.ServerGrpcGenerator
)
The principal output is a WAR in the target directory which can be deployed to WildFly.
If "inWildfly" is set to "false" or the WAR is deployed to some environment other than WildFly with the grpc subsystem, the
class <generate-prefix>_Server
is a Jakarta RESTful Web Services resource that can be used to start up a gRPC server
upon receiving an invocation on path "grpcserver/start".
Once the gRPC server is started, the Jakarta RESTful Web Services resources in the gRPC bridge project (copied from the
target project) can be invoked by an appropriate gRPC client. For some sample client code, see
org.jboss.resteasy.test.grpc.AbstractGrpcToJakartaRESTTest
in RESTEasy's grpc-bridge project or
dev.resteasy.grpc.greet.test.GrpcToJakartaRESTTest
in the arch-test directory in this project.
Note. <generate-prefix>ServiceGrpcImpl
retrieves the org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
that handles the servlet. For this to work, there has to be a Jakarta RESTful Web Services call (as opposed to a gRPC call)
to a resource method in the WAR. In particular, <generate-prefix>_Server.startContext()
, with path
"grpcserver/context", obtains and stores the jakarta.servlet.ServletContext
for the servlet. Once that happens, gRPC calls will succeed.
For example, GrpcToJakartaRESTTest
includes the code
Client client = ClientBuilder.newClient();
Response response = client.target("http: //localhost:8080/GrpcToJakartaRESTTest/grpcToJakartaRest/grpcserver/context").request().get();
Assert.assertEquals(200, response.getStatus());
Alternatively, the call can be made from a browser or by cURL.
gRPCtoJakartaREST-archetype has a built in testing procedure based on the arch-script bash script:
#!/bin/bash
DIR=arch-build
if [ ! -d "$DIR" ]; then
mkdir $DIR
fi
cd $DIR
rm -rf *
# Create grpcToRest.example skeleton bridge project
mvn archetype:generate -B \
-DarchetypeGroupId=dev.resteasy.grpc \
-DarchetypeArtifactId=gRPCtoJakartaREST-archetype \
-DarchetypeVersion=1.0.0.Alpha5 \
-DgroupId=dev.resteasy.examples \
-DartifactId=grpcToRest.example \
-Dversion=1.0.0.Final-SNAPSHOT \
-Dgenerate-prefix=Greet \
-Dgenerate-package=dev.resteasy.example.grpc.greet \
-Dresteasy-version=6.2.4.Final \
-Dgrpc-bridge-version=1.0.0.Alpha2
# Build bridge project
cd grpcToRest.example
mvn install
# Run dev.resteasy.grpc.greet.test.GrpcToJakartaRESTTest, which deploys the bridge project WAR
# to WildFly and makes gRPC invocations on it.
cd ../../arch-test
mvn clean install
Running
mvn clean install
from the main gRPCtoJakartaREST-archetype directory will invoke arch-script.