## Invoking a Grpc endpoint using the Java-SDK

In this example, you will run a Grpc service and client using Dapr's invoke feature.

## Pre-requisites

* [Dapr CLI](https://docs.dapr.io/getting-started/install-dapr-cli/).
* Java JDK 17 (or greater):
    * [Microsoft JDK 17](https://docs.microsoft.com/en-us/java/openjdk/download#openjdk-17)
    * [Oracle JDK 17](https://www.oracle.com/technetwork/java/javase/downloads/index.html#JDK17)
    * [OpenJDK 17](https://jdk.java.net/17/)
* [Apache Maven](https://maven.apache.org/install.html) version 3.x.

### Checking out the code

Clone this repository:

```sh
git clone https://github.com/dapr/java-sdk.git
cd java-sdk
```

Then build the Maven project:

```sh
# make sure you are in the `java-sdk` directory.
mvn install
```

Get into the examples' directory:
```sh
cd examples
```

### Running the example's service

The first component is the service. It has a simple API with the `SayHello` method. This method will print out each message received from the client. The proto file below contains the description of the HelloWorld service found in the `./proto/examples/helloworld.proto` file:

```text
  service HelloWorld {
    // 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;
  }
```

In the `HelloWorldService.java` file, you will find the `HelloWorldService` class, containing the main method and handling logic. You can see that it extends  `HelloWorldImplBase` automatically generated by proto to implement `sayhello` method.

```java
  static class HelloWorldImpl extends HelloWorldGrpc.HelloWorldImplBase {

    /**
     * Handling of the 'sayHello' method.
     *
     * @param req Request to say something.
     * @return Response with when it was said.
     */
    @Override
    public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
      HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
      responseObserver.onNext(reply);
      responseObserver.onCompleted();
    }
  }
```

Now run the service code:

<!-- STEP
name: Run demo service
expected_stderr_lines:
  - 'INFO: greet to World'
background: true
sleep: 1
-->

```bash
dapr run --app-id hellogrpc --app-port 5000 --app-protocol grpc -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.grpc.HelloWorldService -p 5000
```

<!-- END_STEP -->

The `app-id` argument is used to identify this service in Dapr's runtime. The `app-port` determines which port Dapr's runtime should call into this service.  The `protocol` argument informs Dapr which protocol it should use to invoke the application: `grpc` or `http`(default).

### Running the example's client

The other component is the client. It will add user name to the grpc request and send it to the server. Open the `HelloWorldClient.java` file, it uses the DaprClient's grpc channel and sends request directly to the dapr side car through it, including necessary headers.

```java
private static class HelloWorldClient {
///...
  public static void main(String[] args) throws Exception {
    String user = "World";
    try (DaprClient client = new DaprClientBuilder().build()) {
      HelloWorldGrpc.HelloWorldBlockingStub blockingStub = HelloWorldGrpc.newBlockingStub(client.getGrpcChannel());
      // Adds Dapr interceptors to populate gRPC metadata automatically.
      blockingStub = DaprClientGrpcInterceptors.intercept("hellogrpc", blockingStub);

      logger.info("Will try to greet " + user + " ...");
      try {
        HelloRequest request = HelloRequest.newBuilder().setName(user).build();
        HelloReply response = blockingStub.sayHello(request);
        logger.info("Greeting: " + response.getMessage());
      } catch (StatusRuntimeException e) {
        logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
      }
    }
  }
///...
}
```

Finally, open a new command line terminal and run the client code to send some messages.

<!-- STEP
name: Run demo client
expected_stderr_lines:
  - 'INFO: Will try to greet World ...'
  - 'INFO: Greeting: Hello World'
background: true
sleep: 10
-->

```bash
dapr run --app-id invokegrpc --app-protocol grpc -- java -jar target/dapr-java-sdk-examples-exec.jar io.dapr.examples.invoke.grpc.HelloWorldClient
```

<!-- END_STEP -->

### Cleanup

To stop the apps run (or press CTRL+C):

<!-- STEP
name: Cleanup
-->

```bash
dapr stop --app-id hellogrpc
dapr stop --app-id invokegrpc
```

<!-- END_STEP -->

Thanks for playing.
