Skip to content

Commit

Permalink
Update to gRPC documentation for Helidon 4
Browse files Browse the repository at this point in the history
  • Loading branch information
tomas-langer committed Oct 19, 2023
1 parent a39edbe commit 60a1624
Show file tree
Hide file tree
Showing 13 changed files with 66 additions and 1,998 deletions.
2 changes: 1 addition & 1 deletion docs/includes/attributes.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ endif::[]
:config-mapping-javadoc-base-url: {javadoc-base-url}/io.helidon.config.objectmapping
:configurable-javadoc-base-url: {javadoc-base-url}/io.helidon.common.configurable
:faulttolerance-javadoc-base-url: {javadoc-base-url}/io.helidon.faulttolerance
:grpc-server-javadoc-base-url: {javadoc-base-url}/io.helidon.grpc.server
:grpc-server-javadoc-base-url: {javadoc-base-url}/io.helidon.webserver.grpc
:health-javadoc-base-url: {javadoc-base-url}/io.helidon.health.checks
:integration-oci-sdk-cdi-javadoc-base-url: {javadoc-base-url}/io.helidon.integrations.oci.sdk.cdi
:media-jsonp-javadoc-base-url: {javadoc-base-url}/io.helidon.http.media.jsonp
Expand Down
107 changes: 0 additions & 107 deletions docs/includes/grpc-marshalling.adoc

This file was deleted.

4 changes: 2 additions & 2 deletions docs/mp/aot.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ for native image.
|✅ |{nbsp} |Security |{nbsp}
|✅ |{nbsp} |Tracing |{nbsp}
|✅ |{nbsp} |Websocket |Server only.
|✅ |gRPC Server |gRPC Server |Since GraalVM 21.0.0
|✅ |gRPC Server |gRPC Server |{nbsp}
|✅ |{nbsp} |Metrics |{nbsp}
|✅ |gRPC Client |gRPC Client |Since GraalVM 21.0.0
|✅ |gRPC Client |gRPC Client |{nbsp}
|✅ |{nbsp} |Metrics |{nbsp}
|✅ |Scheduling |Scheduling |{nbsp}
|✅ |OCI |OCI Integration |Modules with group id `io.helidon.integrations.oci`
Expand Down
257 changes: 3 additions & 254 deletions docs/mp/grpc/client.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,261 +28,10 @@ include::{rootdir}/includes/mp.adoc[]
== Contents
- <<Overview, Overview>>
- <<Maven Coordinates, Maven Coordinates>>
- <<API, API>>
- <<Configuration, Configuration>>
- <<Usage, Usage>>
- <<Examples, Examples>>
== Overview
Building Java-based gRPC clients using the Helidon MP gRPC APIs is very simple and removes a lot of the boilerplate code typically
associated to more traditional approaches of writing gRPC Java clients. At its simplest, a gRPC Java client can be written using
nothing more than a suitably annotated interface.
include::{rootdir}/includes/dependencies.adoc[]
[source,xml]
----
<dependency>
<groupId>io.helidon.microprofile.grpc</groupId>
<artifactId>helidon-microprofile-grpc-client</artifactId>
</dependency>
----
== API
The following annotations are used to work with Helidon MP gRPC clients:
* `@GrpcChannel` - an annotation used to inject a gRPC channel.
* `@InProcessGrpcChannel` - an annotation used to tell the Helidon MP gRPC API to inject an in-process channel.
* `@GrpcProxy` - an annotation used to mark an injection point for a gRPC service client proxy.
* `@Grpc` - an annotation used to mark a class as representing a gRPC service.
== Configuration
For a gRPC client to connect to a server, it requires a Channel. The Helidon MP gRPC APIs provide a way to inject channels into
CDI beans that require them.
// grpc client is temporarily removed from Helidon
// include::{rootdir}/config/io_helidon_grpc_client_GrpcChannelDescriptor.adoc[leveloffset=1, tag=config]
Channels are configured in the `grpc` section of the Helidon application configuration. The examples below use an `application.yaml`
file but there are many other ways to use and override xref:{rootdir}/mp/config/introduction.adoc[configuration in Helidon]
.General form of a gRPC channels configuration
[source,yaml]
----
grpc:
channels: # <1>
test-server: # <2>
host: localhost # <3>
port: 1408 # <4>
----
<1> Channels are configured in the `channels` section.
<2> Each subsection is the channel name that is then used to refer to this channel in the application code.
<3> Each channel contains a host name.
<4> It also contains a port.
While most client application only connect to a single server, it is possible to configure multiple named channels if the client
needs to connect to multiple servers.
.Multiple gRPC Channels configuration example
[source,yaml]
----
grpc:
channels:
london:
host: london.foo.com
port: 1408
new-york:
host: ny.foo.com
port: 1408
----
The above example shows two channel configurations, one named `london` and the other `new-york`.
=== Configuring TLS
It is also possible to configure a Channel to use TLS if the server is using TLS.
// grpc client is temporarily removed from Helidon
// include::{rootdir}/config/io_helidon_grpc_core_GrpcTlsDescriptor.adoc[leveloffset=3]
.TLS on gRPC Channels configuration example
[source,yaml]
----
grpc:
channels:
test-server:
host: localhost
port: 1408
tls: # <1>
enabled: true # <2>
tls-cert-path: /certs/foo.cert # <3>
tls-key-path: /certs/foo.key # <4>
tls-ca-cert-path: /certs/ca.cert # <5>
----
<1> The `tls` section of the channel configuration is used to configure TLS.
<2> The `enabled` value is used to enable or disable TLS for this channel.
<3> The `tls-cert` value is the location of the TLS certificate file.
<4> The `tls-key` value is the location of the TLS key file.
<5> The `tls-ca-cert` value is the location of the TLS CA certificate file.
The SSL configuration uses the Helidon `Resource` class to locate configured keys and certificates.
In the example above the `tls-cert-path` config key has the `-path` suffix which tells the configuration to load `/certs/foo.cert`
as a file. If `/certs/foo.cert` was a resource on the classpath, the configuration key could have been changed to
`tls-cert-resource-path` to load `/certs/foo.cert` from the classpath. The same applies to the `tls-key` and `tls-ca-cert`
configuration keys. See the `io.helidon.common.configurable.Resource` class for details.
== Usage
=== Using Channels
Once one or more channels have been configured, then they can be used by the client code. The simplest way to use a channel is
to inject it into beans using CDI. The Helidon gRPC client APIs have CDI producers that can provide `io.grpc.Channel` instances.
For example, a class might have an injectable `io.grpc.Channel` field:
.gRPC Channel Injection
[source,java]
----
@Inject // <1>
@GrpcChannel(name = "test-server") // <2>
private Channel channel;
----
<1> The `@Inject` annotation tells CDI to inject the channel.
<2> The `@GrpcChannel` annotation is the qualifier that supplies the Channel name. This is the same name as used in the channel
configuration in the examples provided in the <<Configuration, configuration section>>.
When an instance of the CDI bean with the channel field is instantiated, a channel will be injected into it.
==== The In-Process Channel
If code is running in an application that is executing as part of the Helidon MP gRPC server, there is a special in-process channel
available. This allows code executing on the server to make calls to gRPC services deployed on that server in the same way an
external client does. To inject an in-process channel, a different qualifier annotation is used.
.gRPC in-Process Channel Injection
[source,java]
----
@Inject // <1>
@InProcessGrpcChannel // <2>
private Channel channel;
----
<1> The `@Inject` annotation tells CDI to identify the injectable qualifiers.
<2> The `@InProcessGrpcChannel` is the qualifier that is used to tell the Helidon MP gRPC API to inject an in-process channel.
=== Using the Client Interface in an Application
Now that there is a client interface and a Channel configuration, we can then use these in the client application. The simplest way is
to use the client in a CDI microprofile application.
We can declare a field of the same type as the client service interface in the application class that requires the client.
The field is then annotated so that CDI will inject the client proxy into the field.
[source,java]
.Simple gRPC Service
----
@ApplicationScoped
public class Client {
@Inject // <1>
@GrpcProxy // <2>
@GrpcChannel(name = "test-server") // <3>
private StringService stringService;
}
----
<1> The `@Inject` annotation tells the CDI to inject the client implementation.
<2> The `@GrpcProxy` annotation is used by the CDI container to match the injection point to the gRPC MP APIs provider.
<3> The `@GrpcChannel` annotation identifies the gRPC channel to be used by the client. The name used in the annotation refers to
a channel name in the application configuration.
When the CDI container instantiates instances of the `Client`, it will inject a dynamic proxy into the `stringService` field
and then any code in methods in the `Client` class can call methods on the `StringService` which will be translated to gRPC calls.
In the example above, there is no need to use a `Channel` directly. The correct channel is added to the dynamic client
proxy internally by the Helidon MP gRPC APIs.
=== Building a gRPC Client
There are a few steps to building and using a gRPC client in Helidon MP.
As discussed in the xref:server.adoc#_defining_service_methods[Defining Service methods] section of the xref:server.adoc[Server-Side Services], there are four different types of gRPC method.
* `Unary` - a simple method with at most a single request value and returning at most a single response value.
* `Server Streaming` - a method that takes at most a single request value but may return zero or more response values.
* `Client Streaming` - a request that takes one or more request values and returns at most one response value.
* `Bi-directional Streaming` - a method that can take one or more request values and return zero or more response values.
And as with the server-side APIs, the Helidon MP gRPC client APIs support a number of different method signatures for each of the
different gRPC method types.
==== The Client Service Interface
The next step is to produce an interface with the service methods that the client requires.
For example, suppose we have a simple server side service that has a unary method to convert a string to uppercase.
[source,java]
.Simple gRPC Service
----
@ApplicationScoped
@io.helidon.microprofile.grpc.core.Grpc
public interface StringService {
@io.helidon.microprofile.grpc.core.Unary
public String upper(String s) {
return s == null ? null : s.toUpperCase();
}
}
----
The service has been written using the Helidon MP APIs but could just as easily be a traditional gRPC Java service generated from
Protobuf files. The client API is agnostic of the server side implementation, it only cares about the method types, the request
and response types and the type of Marshaller used to serialize the request and response.
To write a client for the StringService, all that is required is an interface.
[source,java]
.Simple gRPC Service
----
@ApplicationScoped
@io.helidon.microprofile.grpc.core.Grpc
public interface StringService {
@io.helidon.microprofile.grpc.core.Unary
public String upper(String s);
}
----
There is no need to write any code to implement the client. The Helidon MP gRPC APIs will create a dynamic proxy for the interface
using the information from the annotations and method signatures.
The interface in the example above used the same method signature as the server but this does not have to be the case. It
could have used any supported signature for a unary method. For example, it could just have easily been written using the standard
unary method signature:
[source,java]
.Simple gRPC Service
----
@ApplicationScoped
@io.helidon.microprofile.grpc.core.Grpc
public interface StringService {
@io.helidon.microprofile.grpc.core.Unary
public void upper(String s, StreamObserver<String> response);
}
----
We could also have made the client asynchronous by using one of the async method signatures:
[source,java]
.Simple gRPC Service
----
@ApplicationScoped
@io.helidon.microprofile.grpc.core.Grpc
public interface StringService {
@io.helidon.microprofile.grpc.core.Unary
public CompletableFuture<String> upper(String s);
}
----
== Examples
link:{helidon-github-tree-url}/examples/grpc/microprofile/basic-client[Basic gRPC Client] example demonstrates a
simple gRPC client that invokes services from deployed gRPC server applications provided in the
link:{helidon-github-tree-url}/examples/grpc/microprofile/basic-server-implicit[Basic gRPC Server] and
link:{helidon-github-tree-url}/examples/grpc/microprofile/metrics[gRPC Server metrics] examples.
gRPC is temporarily removed in Helidon, please follow issue
https://github.com/helidon-io/helidon/issues/5418
If you require gRPC in Helidon MP, kindly stay with Helidon MP 3.x, until the issue is resolved.
Loading

0 comments on commit 60a1624

Please sign in to comment.