Java、MavenでgRPCを試してみる

## 概要
gRPCを体験してみる！
ビルド場所の調整など備忘録です。

## 環境
- Mac
- OpenJDK 11
- Maven
- eclipse 

## pom.xmlの設定
```xml:[pom.xml]
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com</groupId>
  <artifactId>grpc.demo2</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>grpc.demo2</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
  </properties>

  <dependencies>
		<!-- https://mvnrepository.com/artifact/io.grpc/grpc-protobuf -->
		<dependency>
		    <groupId>io.grpc</groupId>
		    <artifactId>grpc-protobuf</artifactId>
		    <version>1.22.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/io.grpc/grpc-netty -->
		<dependency>
		    <groupId>io.grpc</groupId>
		    <artifactId>grpc-netty</artifactId>
		    <version>1.22.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/io.grpc/grpc-stub -->
		<dependency>
		    <groupId>io.grpc</groupId>
		    <artifactId>grpc-stub</artifactId>
		    <version>1.22.1</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
		<dependency>
		    <groupId>com.google.protobuf</groupId>
		    <artifactId>protobuf-java</artifactId>
		    <version>3.9.0</version>
		</dependency>
        <!-- Java9から標準ライブラリから外れたため -->
		<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
		<dependency>
		    <groupId>javax.annotation</groupId>
		    <artifactId>javax.annotation-api</artifactId>
		    <version>1.3.2</version>
		</dependency>
  </dependencies>
 
  <build>
    <defaultGoal>clean generate-sources compile install</defaultGoal>
	<plugins>
		<plugin>
			<groupId>com.github.os72</groupId>
			<artifactId>protoc-jar-maven-plugin</artifactId>
			<version>3.8.0</version>
			<executions>
				<execution>
					<phase>generate-sources</phase>
					<goals>
						<goal>run</goal>
					</goals>
					<configuration>
						<includeMavenTypes>direct</includeMavenTypes>
						
						<inputDirectories>
							<include>src/main/resources</include>
						</inputDirectories>
						
						<outputTargets>
							<outputTarget>
								<type>java</type>
								<outputDirectory>src/main/java</outputDirectory>
							</outputTarget>
							<outputTarget>
								<type>grpc-java</type>
								<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.22.1</pluginArtifact>
								<outputDirectory>src/main/java</outputDirectory>
							</outputTarget>
						</outputTargets>
					</configuration>
				</execution>
			</executions>
		</plugin>	
	</plugins>
  </build>
</project>

```

## protoファイル作成
src/main配下にresourcesフォルダを作り、protoファイルを作成する。

```proto:[helloworld.proto]
syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.example.helloworld";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

```

### ビルド！
上で指定したio.grpc.example.helloworldパッケージとソースができているはずです。


## 動作確認
ではサーバーとクライエントを実装し、動作を確認してみます。

```java:[Server.java]
public class Server {

	public static void main(String[] args) throws Exception {

		int port = 8080;

		io.grpc.Server server = ServerBuilder.forPort(port).addService((BindableService) new GreeterImpl()).build();

		server.start();
		server.awaitTermination();
	}
}

```

```java:[GreeterImpl.java]
public class GreeterImpl extends GreeterGrpc.GreeterImplBase {

	public void sayHello(HelloRequest reqest, StreamObserver<HelloReply> responseObserver) {

		HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + reqest.getName()).build();

		responseObserver.onNext(reply);
		responseObserver.onCompleted();
	}
}
```

```java:[Client.java]
public class Client {
	public static void main(String[] args) {

		String name = "Takeshi";
		int port = 8080;

		ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", port).usePlaintext().build();

		GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);

		HelloRequest request = HelloRequest.newBuilder().setName(name).build();
		HelloReply reply = stub.sayHello(request);

		System.out.println("Reply: " + reply.getMessage());
	}
}
```

Serverを起動後にClientを実行する。

```
Reply: Hello Takeshi
```
無事、Takeshiが返って来ました。


## 参考
[GRPC Project Setup in Java](https://www.youtube.com/watch?v=JFzAe9SvNaU)
[JavaでgRPC導入のためのポイント](https://qiita.com/disc99/items/3fdfe5c1c1170871221a)