├── .github └── workflows │ └── maven.yml ├── .gitignore ├── .mvn └── wrapper │ ├── MavenWrapperDownloader.java │ └── maven-wrapper.properties ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── armeria-example ├── armeria-grpc-client │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── exmaple │ │ └── grpc │ │ └── armeria │ │ └── ArmeriaGrpcClient.java ├── armeria-grpc-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── armeria │ │ │ ├── ArmeriaGrpcServer.java │ │ │ └── HelloServiceImpl.java │ │ └── proto │ │ └── hello.proto └── pom.xml ├── chat-example ├── chat-javafx-client │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── chat │ │ └── ChatClient.java ├── chat-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── chat │ │ │ ├── ChatServer.java │ │ │ └── ChatServiceImpl.java │ │ └── proto │ │ └── Chat.proto ├── chat-vaadin-client │ ├── README.md │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── chat │ │ ├── ChatUI.java │ │ └── vaadin │ │ └── MyServlet.java └── pom.xml ├── docker-compose-example ├── README.md └── l4-lb-example.yaml ├── error-handling-example ├── error-handling-client │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── client │ │ └── ErrorHandlingGrpcClient.java ├── error-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── server │ │ │ ├── CustomException.java │ │ │ ├── ErrorGrpcServer.java │ │ │ ├── ErrorServiceImpl.java │ │ │ └── UnknownStatusDescriptionInterceptor.java │ │ └── proto │ │ └── ErrorServices.proto └── pom.xml ├── gradle-kotlin-dsl ├── build.gradle.kts ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── proto │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── proto │ │ └── com │ │ └── example │ │ └── greeting │ │ └── v1 │ │ └── GreetingService.proto ├── services │ ├── greeting-loosely-coupled │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── greeting │ │ │ ├── Application.java │ │ │ └── GreetingServiceImpl.java │ └── greeting │ │ ├── build.gradle.kts │ │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── greeting │ │ ├── Application.java │ │ └── GreetingServiceImpl.java └── settings.gradle.kts ├── jpa-example ├── guestbook-proto │ ├── pom.xml │ └── src │ │ └── main │ │ └── proto │ │ └── GuestbookService.proto ├── guestbook-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── springboot │ │ │ ├── GuestbookEntryDomain.java │ │ │ ├── GuestbookRepository.java │ │ │ ├── GuestbookServer.java │ │ │ └── GuestbookServiceGrpcImpl.java │ │ └── resources │ │ └── application.properties ├── guestbook-ui │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── guestbook │ │ │ │ ├── ApplicationConfig.java │ │ │ │ ├── GuestbookUiApplication.java │ │ │ │ └── GuestbookUiController.java │ │ └── resources │ │ │ ├── application.properties │ │ │ └── templates │ │ │ └── index.html │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── guestbook │ │ └── GuestbookUiApplicationTests.java └── pom.xml ├── kubernetes-lb-example ├── README.md ├── echo-client-lb-api │ ├── .dockerignore │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── client │ │ ├── ClientSideLoadBalancedEchoClient.java │ │ ├── KubernetesNameResolver.java │ │ └── KubernetesNameResolverProvider.java ├── echo-client-lb-dns │ ├── .dockerignore │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── client │ │ └── ClientSideLoadBalancedEchoClient.java ├── echo-client-simple │ ├── .dockerignore │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── client │ │ └── SimpleEchoClient.java ├── echo-server │ ├── .dockerignore │ ├── Dockerfile │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── server │ │ │ └── EchoServer.java │ │ └── proto │ │ └── EchoService.proto ├── kubernetes │ ├── client-side-lb-api │ │ ├── echo-client.yaml │ │ └── echo-server.yaml │ ├── client-side-lb-dns │ │ ├── echo-client.yaml │ │ └── echo-server.yaml │ ├── istio-grpc-web │ │ ├── echo-client.yaml │ │ ├── echo-server-virtualservice.yaml │ │ ├── echo-server.yaml │ │ └── istio-gateway.yaml │ ├── istio-ingress-lb │ │ ├── echo-client.yaml │ │ ├── echo-server.yaml │ │ ├── istio-echo-server-dest.yaml │ │ └── istio-gateway.yaml │ ├── istio-lb │ │ ├── echo-client.yaml │ │ └── echo-server.yaml │ ├── l4-lb │ │ ├── echo-client.yaml │ │ └── echo-server.yaml │ └── linkderd-lb │ │ ├── echo-client.yaml │ │ ├── echo-server.yaml │ │ └── linkerd-grpc.yml ├── nginx │ ├── Dockerfile │ ├── docker-compose.yml │ └── nginx.conf └── pom.xml ├── metadata-context-example ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── grpc │ │ ├── Constant.java │ │ ├── client │ │ ├── AuthClient.java │ │ └── JwtCallCredential.java │ │ └── server │ │ ├── GoodbyeServer.java │ │ ├── GreetingServer.java │ │ ├── JwtClientInterceptor.java │ │ ├── JwtServerInterceptor.java │ │ ├── TraceIdClientInterceptor.java │ │ └── TraceIdServerInterceptor.java │ └── proto │ └── ExampleServices.proto ├── mvnw ├── mvnw.cmd ├── pom.xml ├── rxjava-example ├── pom.xml ├── rxjava-client │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── client │ │ └── RxMetricsClient.java └── rxjava-server │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── grpc │ │ └── server │ │ └── RxMetricsServer.java │ └── proto │ └── Streaming.proto ├── simple-grpc-client-android ├── .gitignore ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── client │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── grpc │ │ │ │ └── client │ │ │ │ └── MainActivity.java │ │ ├── proto │ │ │ └── ExampleServices.proto │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ │ ├── layout │ │ │ └── activity_main.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── client │ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle ├── simple-grpc-client ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── example │ └── grpc │ └── client │ └── MyGrpcClient.java ├── simple-grpc-server ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── grpc │ │ └── server │ │ └── MyGrpcServer.java │ └── proto │ └── ExampleServices.proto ├── springboot-example-lognet ├── .mvn │ └── wrapper │ │ └── maven-wrapper.properties ├── mvnw ├── mvnw.cmd ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── demo │ │ │ ├── DemoApplication.java │ │ │ ├── MyBusinessService.java │ │ │ ├── MyDataRepository.java │ │ │ └── MyMessageService.java │ ├── proto │ │ └── Greeting.proto │ └── resources │ │ ├── application.properties │ │ └── schema.sql │ └── test │ └── java │ └── com │ └── example │ └── demo │ └── DemoApplicationTests.java ├── springboot-example ├── README.md ├── eureka-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── eureka │ │ │ └── EurekaServer.java │ │ └── resources │ │ └── application.properties ├── grpc-client │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── springboot │ │ │ ├── Cmd.java │ │ │ └── GrpcClient.java │ │ └── resources │ │ └── application.properties ├── grpc-echo-proto │ ├── pom.xml │ └── src │ │ └── main │ │ └── proto │ │ └── Echo.proto ├── grpc-server │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── grpc │ │ │ └── springboot │ │ │ ├── EchoServiceImpl.java │ │ │ └── GrpcServer.java │ │ └── resources │ │ └── application.properties └── pom.xml ├── streaming-example ├── pom.xml ├── streaming-client │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── com │ │ └── example │ │ └── grpc │ │ └── client │ │ ├── AverageOnSubscribe.java │ │ ├── MetricsClient.java │ │ └── MetricsRxClient.java └── streaming-server │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── com │ │ └── example │ │ └── grpc │ │ └── server │ │ ├── MetricsServer.java │ │ └── MetricsServiceImpl.java │ └── proto │ └── StreamingExample.proto └── zipkin-prometheus-example ├── pom.xml └── src └── main ├── java └── com │ └── example │ └── grpc │ ├── Constant.java │ ├── client │ └── ZipkinExampleClient.java │ └── server │ ├── GoodbyeServer.java │ ├── GreetingServer.java │ └── PrometheusServer.java └── proto └── ExampleServices.proto /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Java CI 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | push: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-18.04 14 | strategy: 15 | matrix: 16 | java_version: [11, 12] 17 | 18 | steps: 19 | - uses: actions/checkout@v1 20 | - name: Set up JDK 21 | uses: actions/setup-java@v1 22 | with: 23 | java-version: ${{ matrix.java_version }} 24 | - name: Build with Maven 25 | run: ./mvnw -B package verify 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Eclipse template 2 | 3 | .metadata 4 | bin/ 5 | tmp/ 6 | *.tmp 7 | *.bak 8 | *.swp 9 | *~.nib 10 | local.properties 11 | .settings/ 12 | .loadpath 13 | .recommenders 14 | 15 | # Eclipse Core 16 | .project 17 | 18 | # External tool builders 19 | .externalToolBuilders/ 20 | 21 | # Locally stored "Eclipse launch configurations" 22 | *.launch 23 | 24 | # PyDev specific (Python IDE for Eclipse) 25 | *.pydevproject 26 | 27 | # CDT-specific (C/C++ Development Tooling) 28 | .cproject 29 | 30 | # JDT-specific (Eclipse Java Development Tools) 31 | .classpath 32 | 33 | # Java annotation processor (APT) 34 | .factorypath 35 | 36 | # PDT-specific (PHP Development Tools) 37 | .buildpath 38 | 39 | # sbteclipse plugin 40 | .target 41 | 42 | # Tern plugin 43 | .tern-project 44 | 45 | # TeXlipse plugin 46 | .texlipse 47 | 48 | # STS (Spring Tool Suite) 49 | .springBeans 50 | 51 | # Code Recommenders 52 | .recommenders/ 53 | ### NetBeans template 54 | nbproject/private/ 55 | build/ 56 | nbbuild/ 57 | dist/ 58 | nbdist/ 59 | nbactions.xml 60 | .nb-gradle/ 61 | ### Maven template 62 | target/ 63 | pom.xml.tag 64 | pom.xml.releaseBackup 65 | pom.xml.versionsBackup 66 | pom.xml.next 67 | release.properties 68 | dependency-reduced-pom.xml 69 | buildNumber.properties 70 | .mvn/timing.properties 71 | ### JetBrains template 72 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 73 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 74 | 75 | # User-specific stuff: 76 | *.iml 77 | .idea 78 | 79 | ## File-based project format: 80 | *.iws 81 | 82 | ## Plugin-specific files: 83 | 84 | # IntelliJ 85 | /out/ 86 | 87 | # mpeltonen/sbt-idea plugin 88 | .idea_modules/ 89 | 90 | # JIRA plugin 91 | atlassian-ide-plugin.xml 92 | 93 | # Crashlytics plugin (for Android Studio and IntelliJ) 94 | com_crashlytics_export_strings.xml 95 | crashlytics.properties 96 | crashlytics-build.properties 97 | fabric.properties 98 | ### Java template 99 | *.class 100 | 101 | # Mobile Tools for Java (J2ME) 102 | .mtj.tmp/ 103 | 104 | # Package Files # 105 | *.jar 106 | *.war 107 | *.ear 108 | 109 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 110 | hs_err_pid* 111 | ### JDeveloper template 112 | # default application storage directory used by the IDE Performance Cache feature 113 | .data/ 114 | 115 | # used for ADF styles caching 116 | temp/ 117 | 118 | # default output directories 119 | classes/ 120 | deploy/ 121 | javadoc/ 122 | 123 | # lock file, a part of Oracle Credential Store Framework 124 | cwallet.sso.lck 125 | # Created by .ignore support plugin (hsz.mobi) 126 | 127 | .gradle 128 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.1/apache-maven-3.6.1-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.5/maven-wrapper-0.5.5.jar 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to become a contributor and submit your own code 2 | 3 | ## Contributor License Agreements 4 | 5 | We'd love to accept your sample apps and patches! Before we can take them, we 6 | have to jump a couple of legal hurdles. 7 | 8 | Please fill out either the individual or corporate Contributor License Agreement 9 | (CLA). 10 | 11 | * If you are an individual writing original source code and you're sure you 12 | own the intellectual property, then you'll need to sign an [individual CLA] 13 | (https://developers.google.com/open-source/cla/individual). 14 | * If you work for a company that wants to allow you to contribute your work, 15 | then you'll need to sign a [corporate CLA] 16 | (https://developers.google.com/open-source/cla/corporate). 17 | 18 | Follow either of the two links above to access the appropriate CLA and 19 | instructions for how to sign and return it. Once we receive it, we'll be able to 20 | accept your pull requests. 21 | 22 | ## Contributing A Patch 23 | 24 | 1. Submit an issue describing your proposed change to the repo in question. 25 | 1. The repo owner will respond to your issue promptly. 26 | 1. If your proposed change is accepted, and you haven't already done so, sign a 27 | Contributor License Agreement (see details above). 28 | 1. Fork the desired repo, develop and test your code changes. 29 | 1. Ensure that your code adheres to the existing style in the sample to which 30 | you are contributing. Refer to the 31 | [Google Cloud Platform Samples Style Guide] 32 | (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the 33 | recommended coding standards for this organization. 34 | 1. Ensure that your code has an appropriate set of unit tests which all pass. 35 | 1. Submit a pull request. 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gRPC Java Examples 2 | ================== 3 | 4 | This is a collection of Java gRPC examples. 5 | 6 | This is not official Google product. 7 | 8 | [YouTube video](https://www.youtube.com/watch?v=xpmFhTMqWhc) 9 | -------------------------------------------------------------------------------- /armeria-example/armeria-grpc-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | armeria-example 7 | com.example.armeria 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | armeria-grpc-client 14 | 15 | 16 | 17 | ${project.groupId} 18 | armeria-grpc-server 19 | ${project.version} 20 | 21 | 22 | com.linecorp.armeria 23 | armeria-grpc 24 | 0.99.2 25 | 26 | 27 | 28 | 29 | 30 | 31 | kr.motd.maven 32 | os-maven-plugin 33 | 34 | 35 | 36 | 37 | org.xolstice.maven.plugins 38 | protobuf-maven-plugin 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /armeria-example/armeria-grpc-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | armeria-example 7 | com.example.armeria 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | armeria-grpc-server 14 | 15 | 16 | 17 | com.linecorp.armeria 18 | armeria-grpc 19 | 0.99.2 20 | 21 | 22 | io.projectreactor 23 | reactor-core 24 | 3.3.4.RELEASE 25 | 26 | 27 | org.slf4j 28 | slf4j-simple 29 | 1.7.29 30 | runtime 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | kr.motd.maven 39 | os-maven-plugin 40 | 41 | 42 | 43 | 44 | org.xolstice.maven.plugins 45 | protobuf-maven-plugin 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /armeria-example/armeria-grpc-server/src/main/proto/hello.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package example.grpc.hello; 4 | option java_package = "com.example.grpc.armeria"; 5 | 6 | service HelloService { 7 | rpc Hello (HelloRequest) returns (HelloReply) {} 8 | rpc LazyHello (HelloRequest) returns (HelloReply) {} 9 | rpc BlockingHello (HelloRequest) returns (HelloReply) {} 10 | rpc LotsOfReplies (HelloRequest) returns (stream HelloReply) {} 11 | rpc LotsOfGreetings (stream HelloRequest) returns (HelloReply) {} 12 | rpc BidiHello (stream HelloRequest) returns (stream HelloReply) {} 13 | } 14 | 15 | message HelloRequest { 16 | string name = 1; 17 | } 18 | 19 | message HelloReply { 20 | string message = 1; 21 | } 22 | -------------------------------------------------------------------------------- /armeria-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | grpc-demos 7 | com.example 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | com.example.armeria 14 | armeria-example 15 | pom 16 | 17 | 18 | armeria-grpc-server 19 | armeria-grpc-client 20 | 21 | 22 | -------------------------------------------------------------------------------- /chat-example/chat-javafx-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | chat-example 23 | com.example.chat 24 | 1.0-SNAPSHOT 25 | ../pom.xml 26 | 27 | 4.0.0 28 | 29 | chat-javafx-client 30 | 31 | 32 | ${project.groupId} 33 | chat-server 34 | ${project.version} 35 | 36 | 37 | org.openjfx 38 | javafx-graphics 39 | 12.0.1 40 | 41 | 42 | org.openjfx 43 | javafx-controls 44 | 12.0.1 45 | 46 | 47 | 48 | 49 | 50 | 51 | com.zenjava 52 | javafx-maven-plugin 53 | 8.1.4 54 | 55 | com.example.grpc.chat.ChatClient 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /chat-example/chat-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | chat-example 23 | com.example.chat 24 | 1.0-SNAPSHOT 25 | ../pom.xml 26 | 27 | 4.0.0 28 | 29 | chat-server 30 | 31 | 32 | 33 | 34 | kr.motd.maven 35 | os-maven-plugin 36 | 37 | 38 | 39 | 40 | org.xolstice.maven.plugins 41 | protobuf-maven-plugin 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /chat-example/chat-server/src/main/java/com/example/grpc/chat/ChatServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.chat; 18 | 19 | import io.grpc.Server; 20 | import io.grpc.ServerBuilder; 21 | 22 | import java.io.IOException; 23 | 24 | /** 25 | * Created by rayt on 5/16/16. 26 | */ 27 | public class ChatServer { 28 | public static void main(String[] args) throws InterruptedException, IOException { 29 | Server server = ServerBuilder.forPort(9090).addService(new ChatServiceImpl()).build(); 30 | 31 | server.start(); 32 | server.awaitTermination(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /chat-example/chat-server/src/main/java/com/example/grpc/chat/ChatServiceImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.chat; 18 | 19 | import com.google.protobuf.Timestamp; 20 | import io.grpc.stub.StreamObserver; 21 | 22 | import java.util.Collections; 23 | import java.util.LinkedHashSet; 24 | import java.util.List; 25 | import java.util.Set; 26 | import java.util.concurrent.ConcurrentHashMap; 27 | 28 | /** 29 | * Created by rayt on 5/16/16. 30 | */ 31 | public class ChatServiceImpl extends ChatServiceGrpc.ChatServiceImplBase { 32 | // @aiborisov mentioned this needs to be thread safe. It was using non-thread-safe HashSet 33 | private static Set> observers = ConcurrentHashMap.newKeySet(); 34 | // Collections.newSetFromMap(new ConcurrentHashMap<>()); 35 | 36 | @Override 37 | public StreamObserver chat(StreamObserver responseObserver) { 38 | observers.add(responseObserver); 39 | 40 | return new StreamObserver() { 41 | @Override 42 | public void onNext(Chat.ChatMessage value) { 43 | System.out.println(value); 44 | Chat.ChatMessageFromServer message = Chat.ChatMessageFromServer.newBuilder() 45 | .setMessage(value) 46 | .setTimestamp(Timestamp.newBuilder().setSeconds(System.currentTimeMillis() / 1000)) 47 | .build(); 48 | 49 | for (StreamObserver observer : observers) { 50 | observer.onNext(message); 51 | } 52 | } 53 | 54 | @Override 55 | public void onError(Throwable t) { 56 | // do something; 57 | } 58 | 59 | @Override 60 | public void onCompleted() { 61 | observers.remove(responseObserver); 62 | } 63 | }; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /chat-example/chat-server/src/main/proto/Chat.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | syntax = "proto3"; 18 | 19 | import "google/protobuf/timestamp.proto"; 20 | package com.example.grpc.chat; 21 | 22 | message ChatMessage { 23 | string from = 1; 24 | string message = 2; 25 | } 26 | 27 | message ChatMessageFromServer { 28 | google.protobuf.Timestamp timestamp = 1; 29 | ChatMessage message = 2; 30 | } 31 | 32 | service ChatService { 33 | rpc chat(stream ChatMessage) returns (stream ChatMessageFromServer); 34 | } 35 | -------------------------------------------------------------------------------- /chat-example/chat-vaadin-client/README.md: -------------------------------------------------------------------------------- 1 | vaadin-app 2 | ============== 3 | 4 | Template for a simple Vaadin application that only requires a Servlet 3.0 container to run. 5 | 6 | 7 | Workflow 8 | ======== 9 | 10 | To compile the entire project, run "mvn install". 11 | 12 | To run the application, run "mvn jetty:run" and open http://localhost:8080/ . 13 | 14 | To produce a deployable production mode WAR: 15 | - change productionMode to true in the servlet class configuration (nested in the UI class) 16 | - run "mvn clean package" 17 | - test the war file with "mvn jetty:run-war" 18 | 19 | Client-Side compilation 20 | ------------------------- 21 | 22 | The generated maven project is using an automatically generated widgetset by default. 23 | When you add a dependency that needs client-side compilation, the maven plugin will 24 | automatically generate it for you. Your own client-side customisations can be added into 25 | package "client". 26 | 27 | Debugging client side code 28 | - run "mvn vaadin:run-codeserver" on a separate console while the application is running 29 | - activate Super Dev Mode in the debug window of the application 30 | 31 | Developing a theme using the runtime compiler 32 | ------------------------- 33 | 34 | When developing the theme, Vaadin can be configured to compile the SASS based 35 | theme at runtime in the server. This way you can just modify the scss files in 36 | your IDE and reload the browser to see changes. 37 | 38 | To use the runtime compilation, open pom.xml and comment out the compile-theme 39 | goal from vaadin-maven-plugin configuration. To remove a possibly existing 40 | pre-compiled theme, run "mvn clean package" once. 41 | 42 | When using the runtime compiler, running the application in the "run" mode 43 | (rather than in "debug" mode) can speed up consecutive theme compilations 44 | significantly. 45 | 46 | It is highly recommended to disable runtime compilation for production WAR files. 47 | 48 | Using Vaadin pre-releases 49 | ------------------------- 50 | 51 | If Vaadin pre-releases are not enabled by default, use the Maven parameter 52 | "-P vaadin-prerelease" or change the activation default value of the profile in pom.xml . 53 | -------------------------------------------------------------------------------- /chat-example/chat-vaadin-client/src/main/java/com/example/chat/vaadin/MyServlet.java: -------------------------------------------------------------------------------- 1 | package com.example.chat.vaadin; 2 | 3 | import javax.servlet.annotation.WebServlet; 4 | 5 | import com.example.chat.ChatUI; 6 | import com.vaadin.annotations.VaadinServletConfiguration; 7 | import com.vaadin.server.VaadinServlet; 8 | 9 | /** 10 | * 11 | */ 12 | 13 | @WebServlet( 14 | urlPatterns = "/*", 15 | name = "MyServlet", 16 | displayName = "gRPC Vaadin Client", 17 | asyncSupported = true, 18 | loadOnStartup = 1) 19 | @VaadinServletConfiguration(ui = ChatUI.class, productionMode = false) 20 | public class MyServlet extends VaadinServlet { 21 | } 22 | -------------------------------------------------------------------------------- /chat-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | grpc-demos 20 | com.example 21 | 1.0-SNAPSHOT 22 | ../pom.xml 23 | 24 | 4.0.0 25 | 26 | com.example.chat 27 | chat-example 28 | pom 29 | 30 | 31 | chat-server 32 | chat-javafx-client 33 | chat-vaadin-client 34 | 35 | 36 | -------------------------------------------------------------------------------- /docker-compose-example/README.md: -------------------------------------------------------------------------------- 1 | gRPC in Docker Compose 2 | ========================================= 3 | This example uses the container built in the [Kubernetes Load Balancing Example](../kubernetes-lb-example). 4 | 5 | L4 Load Balancing 6 | ----------------- 7 | Use Docker Compose to setup a simple linked containers. However, becareful about L4 load balancing in gRPC. 8 | 9 | gRPC client can connect to the service IP (and with DNS name) directly. 10 | Every time a new connection is opened, it'll be load balanced across 11 | the running server instances. 12 | 13 | Deploy the example: 14 | ``` 15 | $ docker-compose -f l4-lb-example.yaml up 16 | ``` 17 | -------------------------------------------------------------------------------- /docker-compose-example/l4-lb-example.yaml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | echo-server: 4 | image: saturnism/echo-server 5 | echo-client: 6 | image: saturnism/echo-client-simple 7 | links: 8 | - echo-server 9 | environment: 10 | - ECHO_SERVICE_HOST=echo-server 11 | - ECHO_SERVICE_PORT=8080 12 | -------------------------------------------------------------------------------- /error-handling-example/error-handling-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | error-handling-example 23 | com.example.errors 24 | 1.0-SNAPSHOT 25 | ../pom.xml 26 | 27 | 4.0.0 28 | 29 | error-handling-client 30 | 31 | 32 | 33 | ${project.groupId} 34 | error-server 35 | ${project.version} 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /error-handling-example/error-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | error-handling-example 23 | com.example.errors 24 | 1.0-SNAPSHOT 25 | ../pom.xml 26 | 27 | 4.0.0 28 | error-server 29 | 30 | 31 | 32 | 33 | kr.motd.maven 34 | os-maven-plugin 35 | 36 | 37 | 38 | 39 | org.xolstice.maven.plugins 40 | protobuf-maven-plugin 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /error-handling-example/error-server/src/main/java/com/example/grpc/server/CustomException.java: -------------------------------------------------------------------------------- 1 | package com.example.grpc.server; 2 | 3 | /** 4 | * Created by rayt on 6/24/17. 5 | */ 6 | public class CustomException extends Exception { 7 | public CustomException() { 8 | } 9 | 10 | public CustomException(String message) { 11 | super(message); 12 | } 13 | 14 | public CustomException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public CustomException(Throwable cause) { 19 | super(cause); 20 | } 21 | 22 | public CustomException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 23 | super(message, cause, enableSuppression, writableStackTrace); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /error-handling-example/error-server/src/main/java/com/example/grpc/server/ErrorGrpcServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.server; 18 | 19 | import io.grpc.Server; 20 | import io.grpc.ServerBuilder; 21 | import io.grpc.ServerInterceptors; 22 | 23 | import java.io.IOException; 24 | import java.util.Arrays; 25 | 26 | /** 27 | * Created by rayt on 5/16/16. 28 | */ 29 | public class ErrorGrpcServer { 30 | static public void main(String[] args) throws IOException, InterruptedException { 31 | UnknownStatusDescriptionInterceptor unknownStatusDescriptionInterceptor = new UnknownStatusDescriptionInterceptor(Arrays.asList( 32 | IllegalArgumentException.class 33 | )); 34 | Server server = ServerBuilder.forPort(8080) 35 | .addService(ServerInterceptors.intercept(new ErrorServiceImpl(), unknownStatusDescriptionInterceptor)) 36 | .build(); 37 | 38 | System.out.println("Starting server..."); 39 | server.start(); 40 | System.out.println("Server started!"); 41 | server.awaitTermination(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /error-handling-example/error-server/src/main/java/com/example/grpc/server/ErrorServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.grpc.server; 2 | 3 | import com.example.grpc.error.EchoRequest; 4 | import com.example.grpc.error.EchoResponse; 5 | import com.example.grpc.error.ErrorServiceGrpc; 6 | import io.grpc.Context; 7 | import io.grpc.Status; 8 | import io.grpc.stub.StreamObserver; 9 | 10 | import java.util.concurrent.ExecutorService; 11 | import java.util.concurrent.Executors; 12 | import java.util.logging.Level; 13 | import java.util.logging.Logger; 14 | 15 | /** 16 | * Created by rayt on 6/24/17. 17 | */ 18 | public class ErrorServiceImpl extends ErrorServiceGrpc.ErrorServiceImplBase { 19 | private static final Logger logger = Logger.getLogger(ErrorServiceImpl.class.getName()); 20 | private static final ExecutorService CANCELLATION_EXECUTOR = Executors.newCachedThreadPool(); 21 | private static final int SECONDS_TO_WAIT = 5; 22 | 23 | @Override 24 | public void customUnwrapException(EchoRequest request, StreamObserver responseObserver) { 25 | responseObserver.onError(new CustomException()); 26 | } 27 | 28 | @Override 29 | public void customException(EchoRequest request, StreamObserver responseObserver) { 30 | try { 31 | throw new CustomException("Custom exception!"); 32 | } catch (Exception e) { 33 | responseObserver.onError(Status.INTERNAL 34 | .withDescription(e.getMessage()) 35 | .augmentDescription("customException()") 36 | .withCause(e) // This can be attached to the Status locally, but NOT transmitted to the client! 37 | .asRuntimeException()); 38 | } 39 | } 40 | 41 | @Override 42 | public void uncaughtExceptions(EchoRequest request, StreamObserver responseObserver) { 43 | throw new NullPointerException("uncaughtExceptions(): Oops, not caught! What happes in the client?"); 44 | } 45 | 46 | @Override 47 | public void automaticallyWrappedException(EchoRequest request, StreamObserver responseObserver) { 48 | responseObserver.onError(new IllegalArgumentException("This exception message and the stacktrace should automatically propagate to the client")); 49 | } 50 | 51 | @Override 52 | public void deadlineExceeded(EchoRequest request, StreamObserver responseObserver) { 53 | Context context = Context.current(); 54 | 55 | context.addListener(new Context.CancellationListener() { 56 | @Override 57 | public void cancelled(Context context) { 58 | // CancellationCause is TimeoutException if it was exceeding the deadline 59 | logger.log(Level.INFO, "deadlineExceeded(): The call was cancelled.", context.cancellationCause()); 60 | } 61 | }, CANCELLATION_EXECUTOR); 62 | 63 | context.run(() -> { 64 | int secondsElapsed = 0; 65 | while (secondsElapsed < SECONDS_TO_WAIT && !context.isCancelled()) { 66 | try { 67 | Thread.sleep(1000L); 68 | } catch (InterruptedException e) { 69 | } 70 | secondsElapsed++; 71 | } 72 | logger.log(Level.INFO, "deadlineExceeded(): The call ended after ~" + secondsElapsed + " seconds"); 73 | }); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /error-handling-example/error-server/src/main/java/com/example/grpc/server/UnknownStatusDescriptionInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.example.grpc.server; 2 | 3 | import io.grpc.*; 4 | 5 | import java.io.PrintWriter; 6 | import java.io.StringWriter; 7 | import java.util.Collection; 8 | import java.util.HashSet; 9 | import java.util.Set; 10 | 11 | /** 12 | * Created by rayt on 6/24/17. 13 | */ 14 | public class UnknownStatusDescriptionInterceptor implements ServerInterceptor { 15 | // Only Throwable classes listed here will be processed by the interceptor. 16 | // The interceptor will copy the cause's message & stacktrace into Status' description. 17 | private final Set> autowrapThrowables = new HashSet<>(); 18 | 19 | public UnknownStatusDescriptionInterceptor(Collection> autowrapThrowables) { 20 | this.autowrapThrowables.addAll(autowrapThrowables); 21 | } 22 | 23 | @Override 24 | public ServerCall.Listener interceptCall(ServerCall call, Metadata headers, ServerCallHandler next) { 25 | ServerCall wrappedCall = new ForwardingServerCall.SimpleForwardingServerCall(call) { 26 | @Override 27 | public void sendMessage(RespT message) { 28 | super.sendMessage(message); 29 | } 30 | 31 | @Override 32 | public void close(Status status, Metadata trailers) { 33 | System.out.println("Interceptor: " + (status.getCause() == null ? "null" : status.getCause().getClass().getName())); 34 | if (status.getCode() == Status.Code.UNKNOWN 35 | && status.getDescription() == null 36 | && status.getCause() != null 37 | && autowrapThrowables.contains(status.getCause().getClass())) { 38 | Throwable e = status.getCause(); 39 | status = Status.INTERNAL 40 | .withDescription(e.getMessage()) 41 | .augmentDescription(stacktraceToString(e)); 42 | } 43 | super.close(status, trailers); 44 | } 45 | }; 46 | 47 | return next.startCall(wrappedCall, headers); 48 | } 49 | 50 | private String stacktraceToString(Throwable e) { 51 | StringWriter stringWriter = new StringWriter(); 52 | PrintWriter printWriter = new PrintWriter(stringWriter); 53 | e.printStackTrace(printWriter); 54 | return stringWriter.toString(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /error-handling-example/error-server/src/main/proto/ErrorServices.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 1. syntax, package, option 18 | syntax = "proto3"; 19 | 20 | package com.example.grpc.error; 21 | 22 | option java_multiple_files = true; 23 | 24 | message EchoRequest { 25 | string message = 1; 26 | } 27 | 28 | message EchoResponse { 29 | string message = 1; 30 | } 31 | 32 | service ErrorService { 33 | rpc notImplemented(EchoRequest) returns (EchoResponse); 34 | rpc customUnwrapException(EchoRequest) returns (EchoResponse); 35 | rpc customException(EchoRequest) returns (EchoResponse); 36 | rpc uncaughtExceptions(EchoRequest) returns (EchoResponse); 37 | rpc deadlineExceeded(EchoRequest) returns (EchoResponse); 38 | rpc automaticallyWrappedException(EchoRequest) returns (EchoResponse); 39 | } 40 | -------------------------------------------------------------------------------- /error-handling-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 20 | 21 | grpc-demos 22 | com.example 23 | 1.0-SNAPSHOT 24 | ../pom.xml 25 | 26 | 4.0.0 27 | 28 | com.example.errors 29 | error-handling-example 30 | pom 31 | 32 | 33 | error-server 34 | error-handling-client 35 | 36 | 37 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * This is a general purpose Gradle build. 5 | * Learn how to create Gradle builds at https://guides.gradle.org/creating-new-gradle-builds/ 6 | */ 7 | 8 | plugins { 9 | base 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | jcenter() 15 | mavenCentral() 16 | } 17 | } 18 | 19 | subprojects { 20 | group = "com.example" 21 | version = "1.0.0-SNAPSHOT" 22 | } 23 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.3.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/proto/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.gradle.* 2 | 3 | plugins { 4 | idea 5 | `java-library` 6 | id("com.google.protobuf") version "0.8.8" 7 | } 8 | 9 | dependencies { 10 | compile("io.grpc:grpc-netty-shaded:1.20.0") 11 | compile("io.grpc:grpc-protobuf:1.20.0") 12 | compile("io.grpc:grpc-stub:1.20.0") 13 | } 14 | 15 | protobuf { 16 | protoc { 17 | artifact = "com.google.protobuf:protoc:3.7.1" 18 | } 19 | plugins { 20 | id("grpc") { 21 | artifact = "io.grpc:protoc-gen-grpc-java:1.20.0" 22 | } 23 | } 24 | generateProtoTasks { 25 | ofSourceSet("main").forEach { 26 | it.plugins { 27 | // Apply the "grpc" plugin whose spec is defined above, without options. 28 | id("grpc") 29 | } 30 | } 31 | } 32 | } 33 | 34 | idea { 35 | module { 36 | generatedSourceDirs.addAll(listOf( 37 | file("${protobuf.protobuf.generatedFilesBaseDir}/main/grpc"), 38 | file("${protobuf.protobuf.generatedFilesBaseDir}/main/java") 39 | )) 40 | } 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/proto/src/main/proto/com/example/greeting/v1/GreetingService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package com.example.greeting.v1; 4 | 5 | option java_multiple_files = true; 6 | 7 | message GreetingRequest { 8 | string name = 1; 9 | } 10 | 11 | message GreetingResponse { 12 | string greeting = 1; 13 | } 14 | 15 | service GreetingService { 16 | rpc greet(GreetingRequest) returns (GreetingResponse); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/services/greeting-loosely-coupled/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.gradle.* 2 | 3 | plugins { 4 | idea 5 | java 6 | application 7 | id("com.google.protobuf") version "0.8.8" 8 | } 9 | 10 | dependencies { 11 | //compile(project(":proto")) 12 | compile("io.grpc:grpc-netty-shaded:1.20.0") 13 | compile("io.grpc:grpc-protobuf:1.20.0") 14 | compile("io.grpc:grpc-stub:1.20.0") 15 | protobuf(files("${rootDir}/proto/src/main/proto/com/example/greeting/v1")) 16 | } 17 | 18 | application { 19 | mainClassName = "com.example.greeting.Application" 20 | } 21 | 22 | 23 | protobuf { 24 | protoc { 25 | artifact = "com.google.protobuf:protoc:3.7.1" 26 | } 27 | plugins { 28 | id("grpc") { 29 | artifact = "io.grpc:protoc-gen-grpc-java:1.20.0" 30 | } 31 | } 32 | generateProtoTasks { 33 | ofSourceSet("main").forEach { 34 | it.plugins { 35 | // Apply the "grpc" plugin whose spec is defined above, without options. 36 | id("grpc") 37 | } 38 | } 39 | } 40 | } 41 | 42 | idea { 43 | module { 44 | generatedSourceDirs.addAll(listOf( 45 | file("${protobuf.protobuf.generatedFilesBaseDir}/main/grpc"), 46 | file("${protobuf.protobuf.generatedFilesBaseDir}/main/java") 47 | )) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/services/greeting-loosely-coupled/src/main/java/com/example/greeting/Application.java: -------------------------------------------------------------------------------- 1 | package com.example.greeting; 2 | 3 | import io.grpc.Server; 4 | import io.grpc.ServerBuilder; 5 | 6 | import java.io.IOException; 7 | 8 | public class Application { 9 | public static void main(String[] args) throws IOException, InterruptedException { 10 | Server server = ServerBuilder.forPort(8081) 11 | .addService(new GreetingServiceImpl()) 12 | .build(); 13 | 14 | server.start(); 15 | 16 | server.awaitTermination(); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/services/greeting-loosely-coupled/src/main/java/com/example/greeting/GreetingServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.greeting; 2 | 3 | import com.example.greeting.v1.GreetingRequest; 4 | import com.example.greeting.v1.GreetingResponse; 5 | import com.example.greeting.v1.GreetingServiceGrpc; 6 | import io.grpc.stub.StreamObserver; 7 | 8 | public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase { 9 | @Override public void greet(GreetingRequest request, StreamObserver responseObserver) { 10 | responseObserver.onNext(GreetingResponse.newBuilder() 11 | .setGreeting("Hello " + request.getName()) 12 | .build()); 13 | 14 | responseObserver.onCompleted(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/services/greeting/build.gradle.kts: -------------------------------------------------------------------------------- 1 | import com.google.protobuf.gradle.* 2 | 3 | plugins { 4 | idea 5 | java 6 | application 7 | id("com.google.protobuf") version "0.8.8" 8 | } 9 | 10 | dependencies { 11 | compile(project(":proto")) 12 | } 13 | 14 | application { 15 | mainClassName = "com.example.greeting.Application" 16 | } 17 | 18 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/services/greeting/src/main/java/com/example/greeting/Application.java: -------------------------------------------------------------------------------- 1 | package com.example.greeting; 2 | 3 | import io.grpc.Server; 4 | import io.grpc.ServerBuilder; 5 | 6 | import java.io.IOException; 7 | 8 | public class Application { 9 | public static void main(String[] args) throws IOException, InterruptedException { 10 | Server server = ServerBuilder.forPort(8081) 11 | .addService(new GreetingServiceImpl()) 12 | .build(); 13 | 14 | server.start(); 15 | 16 | server.awaitTermination(); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/services/greeting/src/main/java/com/example/greeting/GreetingServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.example.greeting; 2 | 3 | import com.example.greeting.v1.GreetingRequest; 4 | import com.example.greeting.v1.GreetingResponse; 5 | import com.example.greeting.v1.GreetingServiceGrpc; 6 | import io.grpc.stub.StreamObserver; 7 | 8 | public class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase { 9 | @Override public void greet(GreetingRequest request, StreamObserver responseObserver) { 10 | responseObserver.onNext(GreetingResponse.newBuilder() 11 | .setGreeting("Hello " + request.getName()) 12 | .build()); 13 | 14 | responseObserver.onCompleted(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /gradle-kotlin-dsl/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * This file was generated by the Gradle 'init' task. 3 | * 4 | * The settings file is used to specify which projects to include in your build. 5 | * 6 | * Detailed information about configuring a multi-project build in Gradle can be found 7 | * in the user manual at https://docs.gradle.org/5.3.1/userguide/multi_project_builds.html 8 | */ 9 | 10 | rootProject.name = "sample" 11 | 12 | include(":services:greeting", ":services:greeting-loosely-coupled", ":proto") 13 | -------------------------------------------------------------------------------- /jpa-example/guestbook-proto/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jpa-example 7 | com.example.jpa 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | guestbook-proto 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | 19 | kr.motd.maven 20 | os-maven-plugin 21 | 22 | 23 | 24 | 25 | org.xolstice.maven.plugins 26 | protobuf-maven-plugin 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /jpa-example/guestbook-proto/src/main/proto/GuestbookService.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package com.example.guestbook; 4 | 5 | option java_multiple_files = true; 6 | 7 | message AllRequest { 8 | } 9 | 10 | message DeleteRequest { 11 | int64 id = 1; 12 | } 13 | 14 | message FindOneRequest { 15 | int64 id = 1; 16 | } 17 | 18 | message GuestbookEntry { 19 | int64 id = 1; 20 | string username = 2; 21 | string message = 3; 22 | } 23 | 24 | message DeleteResponse { 25 | } 26 | 27 | message AddRequest { 28 | string username = 1; 29 | string message = 2; 30 | } 31 | 32 | message AddResponse { 33 | int64 id = 1; 34 | } 35 | 36 | service GuestbookService { 37 | rpc all(AllRequest) returns (stream GuestbookEntry); 38 | rpc findOne(FindOneRequest) returns (GuestbookEntry); 39 | rpc delete(DeleteRequest) returns (DeleteResponse); 40 | rpc add(AddRequest) returns (AddResponse); 41 | } 42 | -------------------------------------------------------------------------------- /jpa-example/guestbook-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | jpa-example 7 | com.example.jpa 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | guestbook-server 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | 19 | com.example 20 | springboot 21 | 1.0-SNAPSHOT 22 | pom 23 | import 24 | 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-data-jpa 36 | 37 | 38 | org.hsqldb 39 | hsqldb 40 | 41 | 42 | org.springframework.boot 43 | spring-boot-starter-test 44 | test 45 | 46 | 47 | ${project.groupId} 48 | guestbook-proto 49 | ${project.version} 50 | 51 | 52 | com.github.saturnism.spring-boot-starter-grpc 53 | grpc-server-starter 54 | 55 | 56 | 57 | 58 | 59 | 60 | kr.motd.maven 61 | os-maven-plugin 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-maven-plugin 68 | 69 | 70 | 71 | repackage 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /jpa-example/guestbook-server/src/main/java/com/example/grpc/springboot/GuestbookEntryDomain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.springboot; 18 | 19 | import com.example.guestbook.AddRequest; 20 | import com.example.guestbook.GuestbookEntry; 21 | 22 | import javax.persistence.Entity; 23 | import javax.persistence.GeneratedValue; 24 | import javax.persistence.Id; 25 | 26 | /** 27 | * Created by rayt on 6/20/17. 28 | */ 29 | @Entity 30 | public class GuestbookEntryDomain { 31 | @Id 32 | @GeneratedValue 33 | private Long id; 34 | 35 | private String username; 36 | private String message; 37 | 38 | public static GuestbookEntryDomain fromProto(GuestbookEntry proto) { 39 | GuestbookEntryDomain entry = new GuestbookEntryDomain(); 40 | entry.setId(proto.getId()); 41 | entry.setUsername(proto.getUsername()); 42 | entry.setMessage(proto.getMessage()); 43 | return entry; 44 | } 45 | 46 | public static GuestbookEntryDomain fromProto(AddRequest proto) { 47 | GuestbookEntryDomain entry = new GuestbookEntryDomain(); 48 | entry.setUsername(proto.getUsername()); 49 | entry.setMessage(proto.getMessage()); 50 | return entry; 51 | } 52 | 53 | public Long getId() { 54 | return id; 55 | } 56 | 57 | public void setId(Long id) { 58 | this.id = id; 59 | } 60 | 61 | public String getUsername() { 62 | return username; 63 | } 64 | 65 | public void setUsername(String username) { 66 | this.username = username; 67 | } 68 | 69 | public String getMessage() { 70 | return message; 71 | } 72 | 73 | public void setMessage(String message) { 74 | this.message = message; 75 | } 76 | 77 | public GuestbookEntry toProto() { 78 | return GuestbookEntry.newBuilder() 79 | .setId(getId()) 80 | .setUsername(getUsername()) 81 | .setMessage(getMessage()) 82 | .build(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /jpa-example/guestbook-server/src/main/java/com/example/grpc/springboot/GuestbookRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.springboot; 18 | 19 | import org.springframework.data.repository.PagingAndSortingRepository; 20 | import org.springframework.stereotype.Repository; 21 | 22 | /** 23 | * Created by rayt on 6/20/17. 24 | */ 25 | @Repository 26 | public interface GuestbookRepository extends PagingAndSortingRepository { 27 | } 28 | -------------------------------------------------------------------------------- /jpa-example/guestbook-server/src/main/java/com/example/grpc/springboot/GuestbookServer.java: -------------------------------------------------------------------------------- 1 | package com.example.grpc.springboot; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * Created by rayt on 5/17/16. 8 | */ 9 | @SpringBootApplication 10 | public class GuestbookServer { 11 | public static void main(String[] args) { 12 | SpringApplication.run(GuestbookServer.class, args); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /jpa-example/guestbook-server/src/main/java/com/example/grpc/springboot/GuestbookServiceGrpcImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.springboot; 18 | 19 | import com.example.guestbook.*; 20 | import io.grpc.stub.StreamObserver; 21 | import org.springframework.boot.autoconfigure.grpc.server.GrpcService; 22 | 23 | import java.util.Optional; 24 | 25 | /** 26 | * Created by rayt on 6/20/17. 27 | */ 28 | @GrpcService 29 | public class GuestbookServiceGrpcImpl extends GuestbookServiceGrpc.GuestbookServiceImplBase { 30 | private final GuestbookRepository repository; 31 | 32 | public GuestbookServiceGrpcImpl(GuestbookRepository repository) { 33 | this.repository = repository; 34 | } 35 | 36 | @Override 37 | public void all(AllRequest request, StreamObserver responseObserver) { 38 | repository.findAll().forEach(e -> { 39 | responseObserver.onNext(e.toProto()); 40 | }); 41 | responseObserver.onCompleted(); 42 | } 43 | 44 | @Override 45 | public void findOne(FindOneRequest request, StreamObserver responseObserver) { 46 | Optional entry = repository.findById(request.getId()); 47 | entry.map(e -> e.toProto()) 48 | .ifPresent(responseObserver::onNext); 49 | responseObserver.onCompleted(); 50 | } 51 | 52 | @Override 53 | public void delete(DeleteRequest request, StreamObserver responseObserver) { 54 | repository.deleteById(request.getId()); 55 | responseObserver.onNext(DeleteResponse.getDefaultInstance()); 56 | responseObserver.onCompleted(); 57 | } 58 | 59 | @Override 60 | public void add(AddRequest request, StreamObserver responseObserver) { 61 | GuestbookEntryDomain entry = GuestbookEntryDomain.fromProto(request); 62 | entry = repository.save(entry); 63 | responseObserver.onNext(AddResponse.newBuilder() 64 | .setId(entry.getId()) 65 | .build()); 66 | responseObserver.onCompleted(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /jpa-example/guestbook-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=9090 2 | grpc.server.port=${server.port} 3 | spring.application.name=EchoService 4 | eureka.instance.securePortEnabled=false 5 | eureka.instance.nonSecurePort=${grpc.server.port} 6 | -------------------------------------------------------------------------------- /jpa-example/guestbook-ui/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | 7 | jpa-example 8 | com.example.jpa 9 | 1.0-SNAPSHOT 10 | ../pom.xml 11 | 12 | 13 | guestbook-ui 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-actuator 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-thymeleaf 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-tomcat 32 | 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-jetty 38 | 39 | 40 | ${project.groupId} 41 | guestbook-proto 42 | 1.0-SNAPSHOT 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-starter-test 48 | test 49 | 50 | 51 | 52 | 53 | 54 | 55 | com.example 56 | springboot 57 | 1.0-SNAPSHOT 58 | pom 59 | import 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-maven-plugin 69 | 70 | 71 | 72 | repackage 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /jpa-example/guestbook-ui/src/main/java/com/example/guestbook/ApplicationConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.guestbook; 17 | 18 | import io.grpc.Channel; 19 | import io.grpc.ManagedChannelBuilder; 20 | import org.springframework.beans.factory.annotation.Value; 21 | import org.springframework.context.annotation.Bean; 22 | import org.springframework.context.annotation.Configuration; 23 | 24 | /** 25 | * Created by rayt on 5/1/17. 26 | */ 27 | @Configuration 28 | public class ApplicationConfig { 29 | @Value("${guestbook.service.target}") 30 | private String guestbookServiceEndpoint; 31 | 32 | @Bean 33 | Channel channel() { 34 | return ManagedChannelBuilder.forTarget(guestbookServiceEndpoint) 35 | .usePlaintext() 36 | .build(); 37 | } 38 | 39 | @Bean 40 | GuestbookServiceGrpc.GuestbookServiceBlockingStub guestbookServiceBlockingStub(Channel channel) { 41 | return GuestbookServiceGrpc.newBlockingStub(channel); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /jpa-example/guestbook-ui/src/main/java/com/example/guestbook/GuestbookUiApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.guestbook; 17 | 18 | import org.springframework.boot.SpringApplication; 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | 21 | @SpringBootApplication 22 | public class GuestbookUiApplication { 23 | 24 | public static void main(String[] args) { 25 | SpringApplication.run(GuestbookUiApplication.class, args); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /jpa-example/guestbook-ui/src/main/java/com/example/guestbook/GuestbookUiController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 Google Inc. All Rights Reserved. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.example.guestbook; 17 | 18 | import com.google.common.collect.Iterables; 19 | import org.springframework.stereotype.Controller; 20 | import org.springframework.ui.Model; 21 | import org.springframework.web.bind.annotation.GetMapping; 22 | import org.springframework.web.bind.annotation.PostMapping; 23 | import org.springframework.web.bind.annotation.RequestParam; 24 | 25 | import java.util.Iterator; 26 | 27 | /** 28 | * Created by rayt on 5/1/17. 29 | */ 30 | @Controller 31 | public class GuestbookUiController { 32 | private final GuestbookServiceGrpc.GuestbookServiceBlockingStub guestbookService; 33 | 34 | public GuestbookUiController(GuestbookServiceGrpc.GuestbookServiceBlockingStub guestbookService) { 35 | this.guestbookService = guestbookService; 36 | } 37 | 38 | @GetMapping("/") 39 | public String index(Model model) { 40 | 41 | Iterable entries = toIterable(guestbookService.all(AllRequest.getDefaultInstance())); 42 | model.addAttribute("messages", entries); 43 | 44 | return "index"; 45 | } 46 | 47 | @PostMapping("/greet") 48 | public String greet(@RequestParam String name, @RequestParam String message, Model model) { 49 | model.addAttribute("name", name); 50 | if (message != null && !message.trim().isEmpty()) { 51 | guestbookService.add(AddRequest.newBuilder() 52 | .setUsername(name) 53 | .setMessage(message).build()); 54 | } 55 | 56 | return "redirect:/"; 57 | } 58 | 59 | private static Iterable toIterable(final Iterator iterator) { 60 | return new Iterable() { 61 | @Override 62 | public Iterator iterator() { 63 | return iterator; 64 | } 65 | }; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /jpa-example/guestbook-ui/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.application.name=ui 2 | guestbook.service.target=localhost:9090 3 | -------------------------------------------------------------------------------- /jpa-example/guestbook-ui/src/test/java/com/example/guestbook/GuestbookUiApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.example.guestbook; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class GuestbookUiApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /jpa-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | grpc-demos 7 | com.example 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | com.example.jpa 14 | jpa-example 15 | pom 16 | 17 | 18 | guestbook-proto 19 | guestbook-server 20 | guestbook-ui 21 | 22 | 23 | 24 | 25 | jitpack.io 26 | https://jitpack.io 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-api/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | !target/lib 3 | !target/*.jar 4 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-api/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | 3 | COPY target/lib /app/lib 4 | COPY target/echo-client-lb-api-1.0-SNAPSHOT.jar /app/echo-client-lb-api.jar 5 | 6 | EXPOSE 8080 7 | ENTRYPOINT ["java", "-jar", "/app/echo-client-lb-api.jar"] 8 | 9 | 10 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-api/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 4.0.0 22 | echo-client-lb-api 23 | 24 | 1.0-SNAPSHOT 25 | com.example.kubernetes 26 | kubernetes-lb-example 27 | ../pom.xml 28 | 29 | 30 | 31 | com.example.grpc.client.ClientSideLoadBalancedEchoClient 32 | 33 | 34 | 35 | 36 | ${project.groupId} 37 | echo-server 38 | ${project.version} 39 | 40 | 41 | io.fabric8 42 | kubernetes-client 43 | 2.0.5 44 | 45 | 46 | 47 | 48 | 49 | 50 | kr.motd.maven 51 | os-maven-plugin 52 | 53 | 54 | 55 | 56 | maven-jar-plugin 57 | 58 | 59 | maven-dependency-plugin 60 | 61 | 62 | org.xolstice.maven.plugins 63 | protobuf-maven-plugin 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-api/src/main/java/com/example/grpc/client/ClientSideLoadBalancedEchoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.client; 18 | 19 | import com.example.grpc.EchoRequest; 20 | import com.example.grpc.EchoResponse; 21 | import com.example.grpc.EchoServiceGrpc; 22 | import io.grpc.ManagedChannel; 23 | import io.grpc.ManagedChannelBuilder; 24 | import io.grpc.util.RoundRobinLoadBalancerFactory; 25 | 26 | import java.net.InetAddress; 27 | import java.net.UnknownHostException; 28 | import java.util.Random; 29 | import java.util.concurrent.ExecutorService; 30 | import java.util.concurrent.Executors; 31 | 32 | /** 33 | * This example uses client side load balancing. It uses a name resolver to resolve a given service 34 | * name into a list of endpoints. You typically need to get the endpoints from a service registry. 35 | * This example uses DNS as the service registry. I.e., if a DNS entry has multiple A records, 36 | * each A record will used as a possible endpoint. 37 | * 38 | * Finally, this example uses a client side round robin load balancer to distributed the requests. 39 | */ 40 | public class ClientSideLoadBalancedEchoClient { 41 | private static int THREADS = 4; 42 | private static Random RANDOM = new Random(); 43 | 44 | public static void main(String[] args) throws InterruptedException, UnknownHostException { 45 | String target = System.getenv("ECHO_SERVICE_TARGET"); 46 | if (target == null || target.isEmpty()) { 47 | target = "localhost:8080"; 48 | } 49 | final ManagedChannel channel = ManagedChannelBuilder.forTarget(target) 50 | .nameResolverFactory(new KubernetesNameResolverProvider()) // this is on by default 51 | .loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance()) 52 | .usePlaintext(true) 53 | .build(); 54 | 55 | final String self = InetAddress.getLocalHost().getHostName(); 56 | 57 | ExecutorService executorService = Executors.newFixedThreadPool(THREADS); 58 | for (int i = 0; i < THREADS; i++) { 59 | EchoServiceGrpc.EchoServiceBlockingStub stub = EchoServiceGrpc.newBlockingStub(channel); 60 | executorService.submit(() -> { 61 | while (true) { 62 | EchoResponse response = stub.echo(EchoRequest.newBuilder() 63 | .setMessage(self + ": " + Thread.currentThread().getName()) 64 | .build()); 65 | System.out.println(response.getFrom() + " echoed"); 66 | 67 | Thread.sleep(RANDOM.nextInt(700)); 68 | } 69 | }); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-api/src/main/java/com/example/grpc/client/KubernetesNameResolverProvider.java: -------------------------------------------------------------------------------- 1 | package com.example.grpc.client; 2 | 3 | import com.google.common.base.Preconditions; 4 | import io.grpc.Attributes; 5 | import io.grpc.NameResolver; 6 | import io.grpc.NameResolverProvider; 7 | import io.grpc.internal.GrpcUtil; 8 | 9 | import javax.annotation.Nullable; 10 | import java.net.URI; 11 | 12 | /** 13 | * Created by rayt on 6/22/17. 14 | */ 15 | 16 | /** 17 | * Usage: kubernetes:///{namespace}/{service}/{port} 18 | * E.g.: kubernetes:///default/echo-server/8080 19 | */ 20 | public class KubernetesNameResolverProvider extends NameResolverProvider { 21 | public static final String SCHEME = "kubernetes"; 22 | 23 | @Override 24 | protected boolean isAvailable() { 25 | return true; 26 | } 27 | 28 | @Override 29 | protected int priority() { 30 | return 5; 31 | } 32 | 33 | @Nullable 34 | @Override 35 | public NameResolver newNameResolver(URI targetUri, Attributes params) { 36 | if (SCHEME.equals(targetUri.getScheme())) { 37 | String targetPath = Preconditions.checkNotNull(targetUri.getPath(), "targetPath"); 38 | Preconditions.checkArgument(targetPath.startsWith("/"), 39 | "the path component (%s) of the target (%s) must start with '/'", targetPath, targetUri); 40 | 41 | String[] parts = targetPath.split("/"); 42 | if (parts.length != 4) { 43 | throw new IllegalArgumentException("Must be formatted like kubernetes:///{namespace}/{service}/{port}"); 44 | } 45 | 46 | try { 47 | int port = Integer.valueOf(parts[3]); 48 | return new KubernetesNameResolver(parts[1], parts[2], port, params, GrpcUtil.TIMER_SERVICE, 49 | GrpcUtil.SHARED_CHANNEL_EXECUTOR); 50 | } catch (NumberFormatException e) { 51 | throw new IllegalArgumentException("Unable to parse port number", e); 52 | } 53 | } else { 54 | return null; 55 | } 56 | } 57 | 58 | @Override 59 | public String getDefaultScheme() { 60 | return SCHEME; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-dns/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | !target/lib 3 | !target/*.jar 4 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-dns/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | 3 | COPY target/lib /app/lib 4 | COPY target/echo-client-lb-dns-1.0-SNAPSHOT.jar /app/echo-client-lb-dns.jar 5 | 6 | EXPOSE 8080 7 | ENTRYPOINT ["java", "-jar", "/app/echo-client-lb-dns.jar"] 8 | 9 | 10 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-dns/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 4.0.0 22 | echo-client-lb-dns 23 | 24 | 1.0-SNAPSHOT 25 | com.example.kubernetes 26 | kubernetes-lb-example 27 | ../pom.xml 28 | 29 | 30 | 31 | com.example.grpc.client.ClientSideLoadBalancedEchoClient 32 | 33 | 34 | 35 | 36 | ${project.groupId} 37 | echo-server 38 | ${project.version} 39 | 40 | 41 | 42 | 43 | 44 | 45 | kr.motd.maven 46 | os-maven-plugin 47 | 48 | 49 | 50 | 51 | maven-jar-plugin 52 | 53 | 54 | maven-dependency-plugin 55 | 56 | 57 | org.xolstice.maven.plugins 58 | protobuf-maven-plugin 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-lb-dns/src/main/java/com/example/grpc/client/ClientSideLoadBalancedEchoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.client; 18 | 19 | import com.example.grpc.EchoRequest; 20 | import com.example.grpc.EchoResponse; 21 | import com.example.grpc.EchoServiceGrpc; 22 | import io.grpc.ManagedChannel; 23 | import io.grpc.ManagedChannelBuilder; 24 | import io.grpc.internal.DnsNameResolverProvider; 25 | import io.grpc.util.RoundRobinLoadBalancerFactory; 26 | 27 | import java.net.InetAddress; 28 | import java.net.UnknownHostException; 29 | import java.util.Random; 30 | import java.util.concurrent.ExecutorService; 31 | import java.util.concurrent.Executors; 32 | 33 | /** 34 | * This example uses client side load balancing. It uses a name resolver to resolve a given service 35 | * name into a list of endpoints. You typically need to get the endpoints from a service registry. 36 | * This example uses DNS as the service registry. I.e., if a DNS entry has multiple A records, 37 | * each A record will used as a possible endpoint. 38 | * 39 | * Finally, this example uses a client side round robin load balancer to distributed the requests. 40 | */ 41 | public class ClientSideLoadBalancedEchoClient { 42 | private static int THREADS = 4; 43 | private static Random RANDOM = new Random(); 44 | 45 | public static void main(String[] args) throws InterruptedException, UnknownHostException { 46 | String target = System.getenv("ECHO_SERVICE_TARGET"); 47 | if (target == null || target.isEmpty()) { 48 | target = "localhost:8080"; 49 | } 50 | final ManagedChannel channel = ManagedChannelBuilder.forTarget(target) 51 | .nameResolverFactory(new DnsNameResolverProvider()) // this is on by default 52 | .loadBalancerFactory(RoundRobinLoadBalancerFactory.getInstance()) 53 | .usePlaintext(true) 54 | .build(); 55 | 56 | final String self = InetAddress.getLocalHost().getHostName(); 57 | 58 | ExecutorService executorService = Executors.newFixedThreadPool(THREADS); 59 | for (int i = 0; i < THREADS; i++) { 60 | EchoServiceGrpc.EchoServiceBlockingStub stub = EchoServiceGrpc.newBlockingStub(channel); 61 | executorService.submit(() -> { 62 | while (true) { 63 | EchoResponse response = stub.echo(EchoRequest.newBuilder() 64 | .setMessage(self + ": " + Thread.currentThread().getName()) 65 | .build()); 66 | System.out.println(response.getFrom() + " echoed"); 67 | 68 | Thread.sleep(RANDOM.nextInt(700)); 69 | } 70 | }); 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-simple/.dockerignore: -------------------------------------------------------------------------------- 1 | **/* 2 | !target/*.jar 3 | !target/lib 4 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-simple/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | 3 | COPY target/lib /app/lib 4 | COPY target/echo-client-simple-1.0-SNAPSHOT.jar /app/echo-client-simple.jar 5 | 6 | EXPOSE 8080 7 | ENTRYPOINT ["java", "-jar", "/app/echo-client-simple.jar"] 8 | 9 | 10 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-simple/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 4.0.0 22 | echo-client-simple 23 | 24 | 1.0-SNAPSHOT 25 | com.example.kubernetes 26 | kubernetes-lb-example 27 | ../pom.xml 28 | 29 | 30 | 31 | com.example.grpc.client.SimpleEchoClient 32 | 33 | 34 | 35 | 36 | ${project.groupId} 37 | echo-server 38 | ${project.version} 39 | 40 | 41 | 42 | 43 | 44 | 45 | kr.motd.maven 46 | os-maven-plugin 47 | 48 | 49 | 50 | 51 | maven-jar-plugin 52 | 53 | 54 | maven-dependency-plugin 55 | 56 | 57 | org.xolstice.maven.plugins 58 | protobuf-maven-plugin 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-client-simple/src/main/java/com/example/grpc/client/SimpleEchoClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.client; 18 | 19 | import com.example.grpc.EchoRequest; 20 | import com.example.grpc.EchoResponse; 21 | import com.example.grpc.EchoServiceGrpc; 22 | import io.grpc.ManagedChannel; 23 | import io.grpc.ManagedChannelBuilder; 24 | 25 | import java.net.InetAddress; 26 | import java.net.UnknownHostException; 27 | import java.util.Random; 28 | import java.util.concurrent.ExecutorService; 29 | import java.util.concurrent.Executors; 30 | 31 | /** 32 | * This is a simple client that depends on external load balancing, either via a proxy, 33 | * or a L4/L7 load balancer. 34 | */ 35 | public class SimpleEchoClient { 36 | private static int THREADS = 4; 37 | private static Random RANDOM = new Random(); 38 | 39 | public static void main(String[] args) throws UnknownHostException { 40 | String host = System.getenv("ECHO_SERVICE_HOST"); 41 | String port = System.getenv("ECHO_SERVICE_PORT"); 42 | final ManagedChannel channel = ManagedChannelBuilder.forTarget(host + ":" + port) 43 | .usePlaintext() 44 | .build(); 45 | 46 | final String self = InetAddress.getLocalHost().getHostName(); 47 | 48 | ExecutorService executorService = Executors.newFixedThreadPool(THREADS); 49 | for (int i = 0; i < THREADS; i++) { 50 | EchoServiceGrpc.EchoServiceBlockingStub stub = EchoServiceGrpc.newBlockingStub(channel); 51 | executorService.submit(() -> { 52 | while (true) { 53 | try { 54 | EchoResponse response = stub.echo(EchoRequest.newBuilder() 55 | .setMessage(self + ": " + Thread.currentThread().getName()) 56 | .build()); 57 | System.out.println(response.getFrom() + " echoed"); 58 | 59 | Thread.sleep(RANDOM.nextInt(700)); 60 | } catch (Exception e) { 61 | e.printStackTrace(); 62 | } 63 | } 64 | }); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-server/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | !target/lib 3 | !target/*.jar 4 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | 3 | COPY target/lib /app/lib 4 | COPY target/echo-server-1.0-SNAPSHOT.jar /app/echo-server.jar 5 | 6 | EXPOSE 8080 7 | ENTRYPOINT ["java", "-jar", "/app/echo-server.jar"] 8 | 9 | 10 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 4.0.0 22 | echo-server 23 | 24 | 1.0-SNAPSHOT 25 | com.example.kubernetes 26 | kubernetes-lb-example 27 | ../pom.xml 28 | 29 | 30 | 31 | com.example.grpc.server.EchoServer 32 | 33 | 34 | 35 | 36 | 37 | kr.motd.maven 38 | os-maven-plugin 39 | 40 | 41 | 42 | 43 | maven-jar-plugin 44 | 45 | 46 | maven-dependency-plugin 47 | 48 | 49 | org.xolstice.maven.plugins 50 | protobuf-maven-plugin 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-server/src/main/java/com/example/grpc/server/EchoServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.server; 18 | 19 | import com.example.grpc.EchoRequest; 20 | import com.example.grpc.EchoResponse; 21 | import com.example.grpc.EchoServiceGrpc; 22 | import io.grpc.Server; 23 | import io.grpc.ServerBuilder; 24 | import io.grpc.stub.StreamObserver; 25 | 26 | import java.io.IOException; 27 | import java.net.InetAddress; 28 | import java.net.UnknownHostException; 29 | import java.util.logging.Logger; 30 | 31 | /** 32 | * Created by rayt on 5/16/16. 33 | */ 34 | public class EchoServer { 35 | static public void main(String[] args) throws IOException, InterruptedException { 36 | 37 | Server server = ServerBuilder.forPort(8080) 38 | .addService(new EchoServiceImpl()).build(); 39 | 40 | System.out.println("Starting server..."); 41 | server.start(); 42 | System.out.println("Server started!"); 43 | server.awaitTermination(); 44 | } 45 | } 46 | 47 | class EchoServiceImpl extends EchoServiceGrpc.EchoServiceImplBase { 48 | private static Logger LOGGER = Logger.getLogger(EchoServiceImpl.class.getName()); 49 | 50 | @Override 51 | public void echo(EchoRequest request, StreamObserver responseObserver) { 52 | try { 53 | String from = InetAddress.getLocalHost().getHostAddress(); 54 | System.out.println("Received: " + request.getMessage()); 55 | responseObserver.onNext(EchoResponse.newBuilder() 56 | .setFrom(from) 57 | .setMessage(request.getMessage()) 58 | .build()); 59 | responseObserver.onCompleted(); 60 | } catch (UnknownHostException e) { 61 | responseObserver.onError(e); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /kubernetes-lb-example/echo-server/src/main/proto/EchoService.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | syntax = "proto3"; 18 | 19 | package com.example.grpc; 20 | 21 | option java_multiple_files = true; 22 | 23 | message EchoRequest { 24 | string message = 1; 25 | } 26 | 27 | message EchoResponse { 28 | string message = 1; 29 | string from = 2; 30 | } 31 | 32 | service EchoService { 33 | rpc echo(EchoRequest) returns (EchoResponse); 34 | } 35 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/client-side-lb-api/echo-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-client 6 | name: echo-client 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-client 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-client 16 | spec: 17 | containers: 18 | - name: echo-client 19 | image: saturnism/echo-client-lb-api 20 | env: 21 | - name: ECHO_SERVICE_TARGET 22 | value: kubernetes:///default/echo-server/8080 23 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/client-side-lb-api/echo-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-server 6 | name: echo-server 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-server 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-server 16 | spec: 17 | containers: 18 | - name: echo-server 19 | image: saturnism/echo-server 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | labels: 25 | run: echo-server 26 | name: echo-server 27 | spec: 28 | clusterIP: None 29 | ports: 30 | - name: grpc 31 | port: 8080 32 | protocol: TCP 33 | targetPort: 8080 34 | selector: 35 | run: echo-server 36 | type: ClusterIP 37 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/client-side-lb-dns/echo-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-client 6 | name: echo-client 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-client 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-client 16 | spec: 17 | containers: 18 | - name: echo-client 19 | image: saturnism/echo-client-lb-dns 20 | env: 21 | - name: ECHO_SERVICE_TARGET 22 | value: dns:///echo-server:8080 23 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/client-side-lb-dns/echo-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-server 6 | name: echo-server 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-server 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-server 16 | spec: 17 | containers: 18 | - name: echo-server 19 | image: saturnism/echo-server 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | labels: 25 | run: echo-server 26 | name: echo-server 27 | spec: 28 | clusterIP: None 29 | ports: 30 | - name: grpc 31 | port: 8080 32 | protocol: TCP 33 | targetPort: 8080 34 | selector: 35 | run: echo-server 36 | type: ClusterIP 37 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-grpc-web/echo-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-client 6 | name: echo-client 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-client 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-client 16 | spec: 17 | containers: 18 | - name: echo-client 19 | image: saturnism/echo-client-simple 20 | env: 21 | - name: ECHO_SERVICE_HOST 22 | value: echo-server 23 | - name: ECHO_SERVICE_PORT 24 | value: "8080" 25 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-grpc-web/echo-server-virtualservice.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: echo-server 5 | spec: 6 | hosts: 7 | - "*" 8 | gateways: 9 | - grpc-gateway 10 | http: 11 | - match: 12 | - uri: 13 | prefix: /com.example.grpc.EchoService/ 14 | route: 15 | - destination: 16 | host: echo-server 17 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-grpc-web/echo-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-server 6 | name: echo-server 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-server 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-server 16 | spec: 17 | containers: 18 | - name: echo-server 19 | image: saturnism/echo-server 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | labels: 25 | run: echo-server 26 | name: echo-server 27 | spec: 28 | ports: 29 | - name: grpc-web 30 | port: 8080 31 | targetPort: 8080 32 | selector: 33 | run: echo-server 34 | sessionAffinity: None 35 | type: ClusterIP 36 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-grpc-web/istio-gateway.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: Gateway 3 | metadata: 4 | name: grpc-gateway 5 | spec: 6 | selector: 7 | istio: ingressgateway 8 | servers: 9 | - hosts: 10 | - "*" 11 | port: 12 | number: 80 13 | name: http 14 | protocol: HTTP 15 | 16 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-ingress-lb/echo-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-client 6 | name: echo-client 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-client 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-client 16 | spec: 17 | containers: 18 | - name: echo-client 19 | image: saturnism/echo-client-simple 20 | env: 21 | - name: ECHO_SERVICE_HOST 22 | value: echo-server 23 | - name: ECHO_SERVICE_PORT 24 | value: "8080" 25 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-ingress-lb/echo-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-server 6 | name: echo-server 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-server 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-server 16 | spec: 17 | containers: 18 | - name: echo-server 19 | image: saturnism/echo-server 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | labels: 25 | run: echo-server 26 | name: echo-server 27 | spec: 28 | ports: 29 | - name: grpc 30 | port: 8080 31 | targetPort: 8080 32 | selector: 33 | run: echo-server 34 | sessionAffinity: None 35 | type: ClusterIP 36 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-ingress-lb/istio-echo-server-dest.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: echo-server 5 | spec: 6 | hosts: 7 | - "*" 8 | gateways: 9 | - grpc-gateway 10 | http: 11 | - match: 12 | - uri: 13 | prefix: /com.example.grpc.EchoService/ 14 | route: 15 | - destination: 16 | host: echo-server 17 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-ingress-lb/istio-gateway.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: Gateway 3 | metadata: 4 | name: grpc-gateway 5 | spec: 6 | selector: 7 | istio: ingressgateway 8 | servers: 9 | - hosts: 10 | - "*" 11 | port: 12 | number: 80 13 | name: http 14 | protocol: HTTP 15 | 16 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-lb/echo-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-client 6 | name: echo-client 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-client 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-client 16 | spec: 17 | containers: 18 | - name: echo-client 19 | image: saturnism/echo-client-simple 20 | env: 21 | - name: ECHO_SERVICE_HOST 22 | value: echo-server 23 | - name: ECHO_SERVICE_PORT 24 | value: "8080" 25 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/istio-lb/echo-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-server 6 | name: echo-server 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-server 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-server 16 | spec: 17 | containers: 18 | - name: echo-server 19 | image: saturnism/echo-server 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | labels: 25 | run: echo-server 26 | name: echo-server 27 | spec: 28 | ports: 29 | - name: grpc 30 | port: 8080 31 | targetPort: 8080 32 | selector: 33 | run: echo-server 34 | sessionAffinity: None 35 | type: ClusterIP 36 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/l4-lb/echo-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-client 6 | name: echo-client 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-client 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-client 16 | spec: 17 | containers: 18 | - name: echo-client 19 | image: saturnism/echo-client-simple 20 | env: 21 | - name: ECHO_SERVICE_HOST 22 | value: echo-server 23 | - name: ECHO_SERVICE_PORT 24 | value: "8080" 25 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/l4-lb/echo-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-server 6 | name: echo-server 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-server 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-server 16 | spec: 17 | containers: 18 | - name: echo-server 19 | image: saturnism/echo-server 20 | --- 21 | apiVersion: v1 22 | kind: Service 23 | metadata: 24 | labels: 25 | run: echo-server 26 | name: echo-server 27 | spec: 28 | ports: 29 | - name: grpc 30 | port: 8080 31 | targetPort: 8080 32 | selector: 33 | run: echo-server 34 | sessionAffinity: None 35 | type: ClusterIP 36 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/linkderd-lb/echo-client.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-client 6 | name: echo-client 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-client 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-client 16 | spec: 17 | containers: 18 | - name: echo-client 19 | image: saturnism/echo-client-simple 20 | env: 21 | - name: ECHO_SERVICE_HOST 22 | valueFrom: 23 | fieldRef: 24 | fieldPath: spec.nodeName 25 | - name: ECHO_SERVICE_PORT 26 | value: "4140" 27 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/linkderd-lb/echo-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | run: echo-server 6 | name: echo-server 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | run: echo-server 12 | template: 13 | metadata: 14 | labels: 15 | run: echo-server 16 | spec: 17 | containers: 18 | - name: echo-server 19 | image: saturnism/echo-server 20 | ports: 21 | - name: grpc 22 | containerPort: 8080 23 | --- 24 | apiVersion: v1 25 | kind: Service 26 | metadata: 27 | labels: 28 | run: echo-server 29 | name: echo-server 30 | spec: 31 | type: ClusterIP 32 | clusterIP: None 33 | ports: 34 | - name: grpc 35 | port: 8080 36 | targetPort: 8080 37 | selector: 38 | run: echo-server 39 | -------------------------------------------------------------------------------- /kubernetes-lb-example/kubernetes/linkderd-lb/linkerd-grpc.yml: -------------------------------------------------------------------------------- 1 | # runs linkerd in a daemonset, in linker-to-linker mode, routing gRPC requests 2 | # Original: https://github.com/linkerd/linkerd-examples/blob/master/k8s-daemonset/k8s/linkerd-grpc.yml 3 | --- 4 | apiVersion: v1 5 | kind: ConfigMap 6 | metadata: 7 | name: l5d-config 8 | data: 9 | config.yaml: |- 10 | admin: 11 | port: 9990 12 | namers: 13 | - kind: io.l5d.k8s 14 | experimental: true 15 | host: localhost 16 | port: 8001 17 | telemetry: 18 | - kind: io.l5d.prometheus 19 | - kind: io.l5d.recentRequests 20 | sampleRate: 0.25 21 | usage: 22 | orgId: linkerd-daemonset-grpc 23 | routers: 24 | - protocol: h2 25 | label: outgoing 26 | experimental: true 27 | dtab: | 28 | /svc/com.example.grpc.EchoService => /#/io.l5d.k8s/default/grpc/echo-server 29 | identifier: 30 | kind: io.l5d.header.path 31 | segments: 1 32 | servers: 33 | - port: 4140 34 | ip: 0.0.0.0 35 | --- 36 | apiVersion: extensions/v1beta1 37 | kind: DaemonSet 38 | metadata: 39 | labels: 40 | app: l5d 41 | name: l5d 42 | spec: 43 | template: 44 | metadata: 45 | labels: 46 | app: l5d 47 | spec: 48 | volumes: 49 | - name: l5d-config 50 | configMap: 51 | name: "l5d-config" 52 | containers: 53 | - name: l5d 54 | image: buoyantio/linkerd:1.1.0 55 | env: 56 | - name: POD_IP 57 | valueFrom: 58 | fieldRef: 59 | fieldPath: status.podIP 60 | args: 61 | - /io.buoyant/linkerd/config/config.yaml 62 | ports: 63 | - name: outgoing 64 | containerPort: 4140 65 | hostPort: 4140 66 | - name: admin 67 | containerPort: 9990 68 | volumeMounts: 69 | - name: "l5d-config" 70 | mountPath: "/io.buoyant/linkerd/config" 71 | readOnly: true 72 | - name: kubectl 73 | image: buoyantio/kubectl:v1.6.2 74 | args: 75 | - "proxy" 76 | - "-p" 77 | - "8001" 78 | --- 79 | apiVersion: v1 80 | kind: Service 81 | metadata: 82 | name: l5d 83 | spec: 84 | selector: 85 | app: l5d 86 | type: LoadBalancer 87 | ports: 88 | - name: outgoing 89 | port: 4140 90 | - name: incoming 91 | port: 4141 92 | - name: admin 93 | port: 9990 94 | -------------------------------------------------------------------------------- /kubernetes-lb-example/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.15.8 2 | 3 | COPY nginx.conf /etc/nginx/conf.d/default.conf 4 | -------------------------------------------------------------------------------- /kubernetes-lb-example/nginx/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | nginx-grpc: 4 | build: . 5 | ports: 6 | - "8080:80" 7 | command: nginx -g 'daemon off;' 8 | echo-server: 9 | image: saturnism/echo-server:latest 10 | ports: 11 | - "8080" 12 | -------------------------------------------------------------------------------- /kubernetes-lb-example/nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 http2; 3 | 4 | location / { 5 | grpc_pass grpc://echo-server:8080; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /kubernetes-lb-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | grpc-demos 7 | com.example 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | com.example.kubernetes 14 | kubernetes-lb-example 15 | pom 16 | 17 | 18 | saturnism 19 | 20 | 21 | 22 | echo-server 23 | echo-client-simple 24 | echo-client-lb-dns 25 | echo-client-lb-api 26 | 27 | 28 | -------------------------------------------------------------------------------- /metadata-context-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | grpc-demos 23 | com.example 24 | 1.0-SNAPSHOT 25 | ../pom.xml 26 | 27 | 4.0.0 28 | metadata-context-example 29 | 30 | 31 | 32 | 33 | com.auth0 34 | java-jwt 35 | 2.2.0 36 | 37 | 38 | 39 | 40 | 41 | 42 | kr.motd.maven 43 | os-maven-plugin 44 | 45 | 46 | 47 | 48 | org.xolstice.maven.plugins 49 | protobuf-maven-plugin 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/java/com/example/grpc/Constant.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc; 18 | 19 | import io.grpc.Context; 20 | import io.grpc.Metadata; 21 | 22 | import static io.grpc.Metadata.ASCII_STRING_MARSHALLER; 23 | 24 | /** 25 | * Created by rayt on 10/6/16. 26 | */ 27 | public class Constant { 28 | public static final String JWT_SECRET = "ajsdklfsadf"; 29 | 30 | public static final Context.Key USER_ID_CTX_KEY = Context.key("userId"); 31 | public static final Context.Key JWT_CTX_KEY = Context.key("jwt"); 32 | public static final Context.Key TRACE_ID_CTX_KEY = Context.key("traceId"); 33 | public static final Context.Key CLIENT_ID_KEY = Context.key("clientId"); 34 | public static final Metadata.Key CLIENT_ID_MD_KEY = Metadata.Key.of("client-id", ASCII_STRING_MARSHALLER); 35 | 36 | public static final Metadata.Key JWT_METADATA_KEY = Metadata.Key.of("jwt", ASCII_STRING_MARSHALLER); 37 | public static final Metadata.Key TRACE_ID_METADATA_KEY = Metadata.Key.of("traceId", ASCII_STRING_MARSHALLER); 38 | } 39 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/java/com/example/grpc/client/JwtCallCredential.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.client; 18 | 19 | import io.grpc.*; 20 | 21 | import java.util.concurrent.Executor; 22 | 23 | /** 24 | * Created by rayt on 10/6/16. 25 | */ 26 | public class JwtCallCredential extends CallCredentials { 27 | private final String jwt; 28 | 29 | public JwtCallCredential(String jwt) { 30 | this.jwt = jwt; 31 | } 32 | 33 | @Override public void applyRequestMetadata(RequestInfo requestInfo, Executor executor, 34 | MetadataApplier metadataApplier) { 35 | executor.execute(new Runnable() { 36 | @Override public void run() { 37 | try { 38 | Metadata headers = new Metadata(); 39 | Metadata.Key jwtKey = Metadata.Key.of("jwt", Metadata.ASCII_STRING_MARSHALLER); 40 | headers.put(jwtKey, jwt); 41 | metadataApplier.apply(headers); 42 | } catch (Throwable e) { 43 | metadataApplier.fail(Status.UNAUTHENTICATED.withCause(e)); 44 | } 45 | } 46 | }); 47 | } 48 | 49 | @Override public void thisUsesUnstableApi() { 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/java/com/example/grpc/server/GreetingServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.server; 18 | 19 | import com.example.grpc.Constant; 20 | import com.example.grpc.GreetingServiceGrpc; 21 | import com.example.grpc.HelloRequest; 22 | import com.example.grpc.HelloResponse; 23 | import io.grpc.Server; 24 | import io.grpc.ServerBuilder; 25 | import io.grpc.ServerInterceptors; 26 | import io.grpc.stub.StreamObserver; 27 | 28 | import java.io.IOException; 29 | 30 | /** 31 | * Created by rayt on 5/16/16. 32 | */ 33 | public class GreetingServer { 34 | static public void main(String [] args) throws IOException, InterruptedException { 35 | JwtServerInterceptor jwtInterceptor = new JwtServerInterceptor(Constant.JWT_SECRET); 36 | 37 | Server greetingServer = ServerBuilder.forPort(8080) 38 | .addService(ServerInterceptors.intercept(new GreetingServiceImpl(), jwtInterceptor, new TraceIdServerInterceptor())) 39 | .build(); 40 | greetingServer.start(); 41 | 42 | System.out.println("Server started!"); 43 | greetingServer.awaitTermination(); 44 | } 45 | 46 | public static class GreetingServiceImpl extends GreetingServiceGrpc.GreetingServiceImplBase { 47 | @Override 48 | public void greeting(HelloRequest request, StreamObserver responseObserver) { 49 | System.out.println(request); 50 | 51 | String userId = Constant.USER_ID_CTX_KEY.get(); 52 | System.out.println("Greeting Service Trace ID: " + Constant.TRACE_ID_CTX_KEY.get()); 53 | System.out.println("Greeting Service User ID: " + userId); 54 | 55 | String greeting = "Hello there, " + request.getName() + ", your userId is " + userId; 56 | 57 | HelloResponse response = HelloResponse.newBuilder().setGreeting(greeting).build(); 58 | 59 | responseObserver.onNext(response); 60 | responseObserver.onCompleted(); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/java/com/example/grpc/server/JwtClientInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.server; 18 | 19 | import com.example.grpc.Constant; 20 | import io.grpc.*; 21 | 22 | /** 23 | * Created by rayt on 10/6/16. 24 | */ 25 | public class JwtClientInterceptor implements ClientInterceptor { 26 | @Override 27 | public ClientCall interceptCall(MethodDescriptor methodDescriptor, CallOptions callOptions, Channel channel) { 28 | return new ForwardingClientCall.SimpleForwardingClientCall(channel.newCall(methodDescriptor, callOptions)) { 29 | @Override 30 | public void start(Listener responseListener, Metadata headers) { 31 | headers.put(Constant.JWT_METADATA_KEY, Constant.JWT_CTX_KEY.get()); 32 | super.start(responseListener, headers); 33 | } 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/java/com/example/grpc/server/JwtServerInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.server; 18 | 19 | import com.auth0.jwt.JWTVerifier; 20 | import com.auth0.jwt.JWTVerifyException; 21 | import com.auth0.jwt.internal.org.bouncycastle.asn1.cms.MetaData; 22 | import com.example.grpc.Constant; 23 | import io.grpc.*; 24 | 25 | import java.io.IOException; 26 | import java.security.InvalidKeyException; 27 | import java.security.NoSuchAlgorithmException; 28 | import java.security.SignatureException; 29 | import java.util.Map; 30 | 31 | import static io.grpc.Metadata.ASCII_STRING_MARSHALLER; 32 | 33 | /** 34 | * Created by rayt on 10/6/16. 35 | */ 36 | public class JwtServerInterceptor implements ServerInterceptor { 37 | private static final ServerCall.Listener NOOP_LISTENER = new ServerCall.Listener() { 38 | }; 39 | 40 | private final String secret; 41 | private final JWTVerifier verifier; 42 | 43 | public JwtServerInterceptor(String secret) { 44 | this.secret = secret; 45 | this.verifier = new JWTVerifier(secret); 46 | } 47 | 48 | @Override 49 | public ServerCall.Listener interceptCall(ServerCall serverCall, Metadata metadata, ServerCallHandler serverCallHandler) { 50 | String jwt = metadata.get(Constant.JWT_METADATA_KEY); 51 | if (jwt == null) { 52 | serverCall.close(Status.UNAUTHENTICATED.withDescription("JWT Token is missing from Metadata"), metadata); 53 | return NOOP_LISTENER; 54 | } 55 | 56 | Context ctx; 57 | try { 58 | Map verified = verifier.verify(jwt); 59 | ctx = Context.current().withValue(Constant.USER_ID_CTX_KEY, verified.getOrDefault("sub", "anonymous").toString()) 60 | .withValue(Constant.JWT_CTX_KEY, jwt); 61 | } catch (Exception e) { 62 | System.out.println("Verification failed - Unauthenticated!"); 63 | serverCall.close(Status.UNAUTHENTICATED.withDescription(e.getMessage()).withCause(e), metadata); 64 | return NOOP_LISTENER; 65 | } 66 | 67 | return Contexts.interceptCall(ctx, serverCall, metadata, serverCallHandler); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/java/com/example/grpc/server/TraceIdClientInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.server; 18 | 19 | import com.example.grpc.Constant; 20 | import io.grpc.*; 21 | 22 | /** 23 | * Created by rayt on 10/6/16. 24 | */ 25 | public class TraceIdClientInterceptor implements ClientInterceptor { 26 | @Override 27 | public ClientCall interceptCall(MethodDescriptor methodDescriptor, CallOptions callOptions, Channel channel) { 28 | return new ForwardingClientCall.SimpleForwardingClientCall(channel.newCall(methodDescriptor, callOptions)) { 29 | @Override 30 | public void start(Listener responseListener, Metadata headers) { 31 | if (Constant.TRACE_ID_CTX_KEY.get() != null) { 32 | headers.put(Constant.TRACE_ID_METADATA_KEY, Constant.TRACE_ID_CTX_KEY.get()); 33 | } 34 | super.start(responseListener, headers); 35 | } 36 | }; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/java/com/example/grpc/server/TraceIdServerInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.server; 18 | 19 | import com.auth0.jwt.JWTVerifier; 20 | import com.example.grpc.Constant; 21 | import io.grpc.*; 22 | 23 | import java.util.Map; 24 | 25 | /** 26 | * Created by rayt on 10/6/16. 27 | */ 28 | public class TraceIdServerInterceptor implements ServerInterceptor { 29 | @Override 30 | public ServerCall.Listener interceptCall(ServerCall serverCall, Metadata metadata, ServerCallHandler serverCallHandler) { 31 | String traceId = metadata.get(Constant.TRACE_ID_METADATA_KEY); 32 | Context ctx = Context.current().withValue(Constant.TRACE_ID_CTX_KEY, traceId); 33 | 34 | return Contexts.interceptCall(ctx, serverCall, metadata, serverCallHandler); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /metadata-context-example/src/main/proto/ExampleServices.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | // 1. syntax, package, option 18 | syntax = "proto3"; 19 | 20 | package com.example.grpc; 21 | 22 | option java_multiple_files = true; 23 | 24 | enum Sentiment { 25 | HAPPY = 0; 26 | SLEEPY = 1; 27 | ANGRY = 2; 28 | } 29 | 30 | message HelloRequest { 31 | string name = 1; 32 | int64 age = 2; 33 | repeated string hobbies = 3; 34 | map bagOfTricks = 4; 35 | Sentiment sentiment = 5; 36 | } 37 | 38 | message HelloResponse { 39 | string greeting = 1; 40 | } 41 | 42 | message GoodbyeRequest { 43 | string name = 1; 44 | string reason = 2; 45 | } 46 | 47 | message GoodbyeResponse { 48 | string farewell = 1; 49 | } 50 | 51 | enum Language { 52 | EN = 0; 53 | ZH = 1; 54 | ES = 3; 55 | } 56 | 57 | message TranslationRequest { 58 | string message = 1; 59 | Language from = 2; 60 | Language to = 3; 61 | } 62 | 63 | message TranslationResponse { 64 | string message = 1; 65 | } 66 | 67 | // 4. service, unary request/response 68 | service GreetingService { 69 | rpc greeting(HelloRequest) returns (HelloResponse); 70 | rpc secondGreeting(HelloRequest) returns (HelloResponse); 71 | } 72 | 73 | service GoodbyeService { 74 | rpc goodbye(GoodbyeRequest) returns (GoodbyeResponse); 75 | } 76 | 77 | service TranslationService { 78 | rpc translate(TranslationRequest) returns (TranslationResponse); 79 | } 80 | -------------------------------------------------------------------------------- /rxjava-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | grpc-demos 7 | com.example 8 | 1.0-SNAPSHOT 9 | ../pom.xml 10 | 11 | 4.0.0 12 | 13 | com.example.rxjava 14 | rxjava-example 15 | pom 16 | 17 | 18 | rxjava-server 19 | rxjava-client 20 | 21 | 22 | 23 | 24 | jitpack.io 25 | https://jitpack.io 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /rxjava-example/rxjava-client/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | rxjava-example 23 | com.example.rxjava 24 | 1.0-SNAPSHOT 25 | ../pom.xml 26 | 27 | 4.0.0 28 | 29 | rxjava-client 30 | 31 | 32 | com.example.grpc.client.RxMetricsClient 33 | 34 | 35 | 36 | 37 | ${project.groupId} 38 | rxjava-server 39 | ${project.version} 40 | 41 | 42 | 43 | 44 | 45 | 46 | maven-jar-plugin 47 | 48 | 49 | maven-dependency-plugin 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /rxjava-example/rxjava-client/src/main/java/com/example/grpc/client/RxMetricsClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.example.grpc.client; 18 | 19 | import com.example.server.streaming.RxMetricsServiceGrpc; 20 | import com.example.server.streaming.Streaming; 21 | import io.grpc.ManagedChannel; 22 | import io.grpc.ManagedChannelBuilder; 23 | import io.reactivex.Flowable; 24 | 25 | import java.util.concurrent.ExecutionException; 26 | 27 | /** 28 | * Created by rayt on 5/16/16. 29 | */ 30 | public class RxMetricsClient { 31 | public static void main(String[] args) throws InterruptedException, ExecutionException { 32 | ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080).usePlaintext().build(); 33 | 34 | RxMetricsServiceGrpc.RxMetricsServiceStub rxStub = RxMetricsServiceGrpc.newRxStub(channel); 35 | 36 | rxStub.collect(Flowable.fromArray(1,2,3,4,5) 37 | .map(m -> Streaming.Metric.newBuilder().setMetric(m).build())) 38 | .subscribe(System.out::println); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /rxjava-example/rxjava-server/src/main/java/com/example/grpc/server/RxMetricsServer.java: -------------------------------------------------------------------------------- 1 | package com.example.grpc.server; 2 | 3 | import com.example.server.streaming.RxMetricsServiceGrpc; 4 | import com.example.server.streaming.Streaming; 5 | import io.grpc.Server; 6 | import io.grpc.ServerBuilder; 7 | import io.reactivex.Flowable; 8 | import io.reactivex.Single; 9 | 10 | import java.io.IOException; 11 | 12 | 13 | public class RxMetricsServer { 14 | public static void main(String[] args) throws IOException, InterruptedException { 15 | RxMetricsServiceGrpc.MetricsServiceImplBase service = new RxMetricsServiceGrpc.MetricsServiceImplBase() { 16 | 17 | @Override 18 | public Single collect(Flowable request) { 19 | return request.map(m -> m.getMetric()) 20 | .map(m -> new State(m, 1)) 21 | .reduce((a, b) -> new State(a.sum + b.sum, a.count + b.count)) 22 | .map(s -> Streaming.Average.newBuilder().setVal(s.sum / s.count).build()) 23 | .toSingle(); 24 | } 25 | }; 26 | 27 | Server server = ServerBuilder.forPort(8080) 28 | .addService(service) 29 | .build(); 30 | 31 | server.start(); 32 | server.awaitTermination(); 33 | } 34 | 35 | static class State { 36 | protected long sum = 0; 37 | protected long count = 0; 38 | 39 | public State(long sum, long count) { 40 | this.sum = sum; 41 | this.count = count; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /rxjava-example/rxjava-server/src/main/proto/Streaming.proto: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Google, Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | syntax = "proto3"; 18 | 19 | import "google/protobuf/timestamp.proto"; 20 | package com.example.server.streaming; 21 | 22 | message Metric { 23 | google.protobuf.Timestamp timestamp = 1; 24 | int64 metric = 2; 25 | } 26 | 27 | message Average { 28 | double val = 1; 29 | } 30 | 31 | service MetricsService { 32 | rpc collect(stream Metric) returns (Average); 33 | } 34 | -------------------------------------------------------------------------------- /simple-grpc-client-android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/libraries 5 | /.idea/modules.xml 6 | /.idea/workspace.xml 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | -------------------------------------------------------------------------------- /simple-grpc-client-android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /simple-grpc-client-android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'com.google.protobuf' 3 | 4 | android { 5 | compileSdkVersion 28 6 | defaultConfig { 7 | applicationId "com.example.grpc.client" 8 | minSdkVersion 16 9 | targetSdkVersion 28 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | compileOptions { 21 | targetCompatibility 1.8 22 | sourceCompatibility 1.8 23 | } 24 | } 25 | 26 | protobuf { 27 | protoc { 28 | artifact = 'com.google.protobuf:protoc:3.0.0' 29 | } 30 | plugins { 31 | grpc { 32 | artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0-pre2' 33 | } 34 | javalite { 35 | artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0' 36 | } 37 | } 38 | generateProtoTasks { 39 | all()*.plugins { 40 | javalite {} 41 | } 42 | ofNonTest()*.plugins { 43 | grpc { 44 | // Options added to --grpc_out 45 | option 'lite' 46 | } 47 | } 48 | } 49 | } 50 | 51 | dependencies { 52 | implementation fileTree(dir: 'libs', include: ['*.jar']) 53 | implementation 'com.android.support:appcompat-v7:28.0.0-alpha3' 54 | implementation 'com.android.support.constraint:constraint-layout:1.1.2' 55 | testImplementation 'junit:junit:4.12' 56 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 57 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 58 | 59 | // GRPC dependencies 60 | implementation 'javax.annotation:javax.annotation-api:1.2' 61 | implementation 'io.grpc:grpc-protobuf-lite:1.12.0' 62 | implementation 'io.grpc:grpc-okhttp:1.12.0' 63 | implementation 'io.grpc:grpc-stub:1.12.0' 64 | 65 | // rx java 66 | implementation "io.reactivex.rxjava2:rxjava:$rx_java_verstion" 67 | implementation "io.reactivex.rxjava2:rxandroid:$rx_android" 68 | 69 | // dialog library 70 | implementation 'com.github.d-max:spots-dialog:0.7@aar' 71 | } -------------------------------------------------------------------------------- /simple-grpc-client-android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /simple-grpc-client-android/app/src/androidTest/java/com/example/grpc/client/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.grpc.client; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.example.grpc.client", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /simple-grpc-client-android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /simple-grpc-client-android/app/src/main/proto/ExampleServices.proto: -------------------------------------------------------------------------------- 1 | /** 2 | * := created by: Shuza 3 | * := create date: {DATE} 4 | * := (C) CopyRight Shuza 5 | * := www.shuza.ninja 6 | * := shuza.sa@gmail.com 7 | * := Fun : Coffee : Code 8 | **/ 9 | 10 | syntax = "proto3"; 11 | 12 | option java_multiple_files = true; 13 | option java_generic_services = true; 14 | package com.example.learn; 15 | 16 | enum Sentiment { 17 | HAPPY = 0; 18 | SLEEPY = 1; 19 | ANGRY = 2; 20 | } 21 | 22 | message HelloRequest { 23 | string name = 1; 24 | int32 age = 2; 25 | repeated string hobbies = 3; 26 | map bagOfTricks = 4; 27 | Sentiment sentiment = 5; 28 | } 29 | 30 | message HelloResponse { 31 | string greeting = 1; 32 | } 33 | 34 | // 4. service, unary request/response 35 | service GreetingService { 36 | rpc greeting (HelloRequest) returns (HelloResponse); 37 | } -------------------------------------------------------------------------------- /simple-grpc-client-android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /simple-grpc-client-android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 18 | 19 |