diff --git a/.bazelrc b/.bazelrc new file mode 100644 index 00000000000..53485cb9743 --- /dev/null +++ b/.bazelrc @@ -0,0 +1 @@ +build --cxxopt=-std=c++17 --host_cxxopt=-std=c++17 diff --git a/.gemini/config.yaml b/.gemini/config.yaml new file mode 100644 index 00000000000..71adf793964 --- /dev/null +++ b/.gemini/config.yaml @@ -0,0 +1,13 @@ +have_fun: false +memory_config: + disabled: false +code_review: + disable: false + comment_severity_threshold: MEDIUM + max_review_comments: -1 + pull_request_opened: + help: false + summary: false + code_review: false + include_drafts: false +ignore_patterns: [] diff --git a/.gitattributes b/.gitattributes index 6d0661ec5a4..4343b9bd8ec 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,4 @@ -TestService.java.txt binary -TestServiceLite.java.txt binary -TestDeprecatedService.java.txt binary -TestDeprecatedServiceLite.java.txt binary +TestService.java.txt -text +TestServiceLite.java.txt -text +TestDeprecatedService.java.txt -text +TestDeprecatedServiceLite.java.txt -text diff --git a/.github/lock.yml b/.github/lock.yml deleted file mode 100644 index 119e4840bee..00000000000 --- a/.github/lock.yml +++ /dev/null @@ -1,2 +0,0 @@ -daysUntilLock: 90 -lockComment: false diff --git a/.github/workflows/branch-testing.yml b/.github/workflows/branch-testing.yml new file mode 100644 index 00000000000..ece8ec4cd58 --- /dev/null +++ b/.github/workflows/branch-testing.yml @@ -0,0 +1,41 @@ +name: GitHub Actions Branch Testing + +on: + push: + branches: + - master + - 'v1.*' + schedule: + - cron: '54 19 * * SUN' # weekly at a "random" time + +permissions: + contents: read + +jobs: + arm64: + runs-on: ubuntu-24.04-arm + strategy: + matrix: + jre: [17] + fail-fast: false # Should swap to true if we grow a large matrix + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.jre }} + distribution: 'temurin' + + - name: Gradle cache + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Build + run: ./gradlew -Dorg.gradle.parallel=true -Dorg.gradle.jvmargs='-Xmx1g' -PskipAndroid=true -PskipCodegen=true -PerrorProne=false test + diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml new file mode 100644 index 00000000000..da1e2fed114 --- /dev/null +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -0,0 +1,13 @@ +name: "Validate Gradle Wrapper" +on: [push, pull_request] + +permissions: + contents: read + +jobs: + validation: + name: "Gradle wrapper validation" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: gradle/actions/wrapper-validation@v4 diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml new file mode 100644 index 00000000000..3070a1a2f7c --- /dev/null +++ b/.github/workflows/lock.yml @@ -0,0 +1,20 @@ +name: 'Lock Threads' + +on: + workflow_dispatch: + schedule: + - cron: '37 3 * * *' + +permissions: + issues: write + pull-requests: write + +jobs: + lock: + runs-on: ubuntu-latest + steps: + - uses: dessant/lock-threads@v5 + with: + github-token: ${{ github.token }} + issue-inactive-days: 90 + pr-inactive-days: 90 diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml new file mode 100644 index 00000000000..8793cfb82fe --- /dev/null +++ b/.github/workflows/testing.yml @@ -0,0 +1,110 @@ +name: GitHub Actions Linux Testing + +on: + push: + branches: + - master + - 'v1.*' + pull_request: + schedule: + - cron: '54 19 * * SUN' # weekly at a "random" time + +permissions: + contents: read + +jobs: + tests: + runs-on: ubuntu-latest + strategy: + matrix: + jre: [8, 11, 17, 21] + fail-fast: false # Should swap to true if we grow a large matrix + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: ${{ matrix.jre }} + distribution: 'temurin' + + - name: Gradle cache + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + - name: Maven cache + uses: actions/cache@v4 + with: + path: | + ~/.m2/repository + !~/.m2/repository/io/grpc + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml', 'build.gradle') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Protobuf cache + uses: actions/cache@v4 + with: + path: /tmp/protobuf-cache + key: ${{ runner.os }}-maven-${{ hashFiles('buildscripts/make_dependencies.sh') }} + + - name: Build + run: buildscripts/kokoro/unix.sh + - name: Post Failure Upload Test Reports to Artifacts + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: Test Reports (JRE ${{ matrix.jre }}) + path: | + ./*/build/reports/tests/** + ./*/*/build/reports/tests/** + retention-days: 14 + - name: Check for modified codegen + run: test -z "$(git status --porcelain)" || (git status && echo Error Working directory is not clean. Forget to commit generated files? && false) + + - name: Coveralls + if: matrix.jre == 8 # Upload once, instead of for each job in the matrix + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + run: ./gradlew :grpc-all:coveralls -PskipAndroid=true -x compileJava + - name: Codecov + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + + bazel: + runs-on: ubuntu-latest + strategy: + matrix: + bzlmod: [true, false] + env: + USE_BAZEL_VERSION: 8.7.0 + + steps: + - uses: actions/checkout@v4 + + - name: Check versions match in MODULE.bazel and repositories.bzl + run: | + diff -u <(sed -n '/GRPC_DEPS_START/,/GRPC_DEPS_END/ {/GRPC_DEPS_/! p}' MODULE.bazel) \ + <(sed -n '/GRPC_DEPS_START/,/GRPC_DEPS_END/ {/GRPC_DEPS_/! p}' repositories.bzl) + + - name: Bazel cache + uses: actions/cache@v4 + with: + path: | + ~/.cache/bazel/*/cache + ~/.cache/bazelisk/downloads + key: ${{ runner.os }}-bazel-${{ env.USE_BAZEL_VERSION }}-${{ hashFiles('WORKSPACE', 'repositories.bzl') }} + + - name: Run bazel build + run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }} + + - name: Run bazel test + run: bazelisk test //... --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }} + + - name: Run example bazel build + run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }} --enable_workspace=${{ !matrix.bzlmod }} + working-directory: ./examples diff --git a/.gitignore b/.gitignore index d5693c84508..b078d891adf 100644 --- a/.gitignore +++ b/.gitignore @@ -15,12 +15,14 @@ bazel-genfiles bazel-grpc-java bazel-out bazel-testlogs +MODULE.bazel.lock # IntelliJ IDEA .idea *.iml *.ipr *.iws +.ijwb # Eclipse .classpath @@ -29,9 +31,18 @@ bazel-testlogs .gitignore bin +# VsCode +.vscode + # OS X .DS_Store # Emacs *~ \#*\# + +# ARM tests +qemu-arm-static + +# Temporary output dir for artifacts +mvn-artifacts diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 4a37defdafb..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,65 +0,0 @@ -language: java - -env: - global: - - GRADLE_OPTS=-Xmx512m - - LDFLAGS=-L/tmp/protobuf/lib - - CXXFLAGS=-I/tmp/protobuf/include - - LD_LIBRARY_PATH=/tmp/protobuf/lib - -before_install: - - rm ~/.m2/settings.xml || true # Avoid repository.apache.org, which has QPS limits and is useless - - mkdir -p $HOME/.gradle/caches && - ln -s /tmp/gradle-caches-modules-2 $HOME/.gradle/caches/modules-2 - - mkdir -p $HOME/.gradle && - ln -s /tmp/gradle-wrapper $HOME/.gradle/wrapper - - buildscripts/make_dependencies.sh # build protoc into /tmp/protobuf - - mkdir -p $HOME/.gradle - - echo "checkstyle.ignoreFailures=false" >> $HOME/.gradle/gradle.properties - - echo "failOnWarnings=true" >> $HOME/.gradle/gradle.properties - - echo "errorProne=true" >> $HOME/.gradle/gradle.properties - - echo "skipAndroid=true" >> $HOME/.gradle/gradle.properties - -install: - - ./gradlew assemble syncGeneratedSources publishToMavenLocal - - pushd examples && ./gradlew build && popd - - pushd examples && mvn verify && popd - - pushd examples/example-alts && ../gradlew build && popd - - pushd examples/example-hostname && ../gradlew build && popd - - pushd examples/example-hostname && mvn verify && popd - - pushd examples/example-tls && ../gradlew clean build && popd - - pushd examples/example-xds && ../gradlew build && popd - -before_script: - - test -z "$(git status --porcelain)" || (git status && echo Error Working directory is not clean. Forget to commit generated files? && false) - -script: - - ./gradlew check :grpc-all:jacocoTestReport - -after_success: - # Upload to coveralls once, instead of for each job in the matrix - - if [[ "$TRAVIS_JOB_NUMBER" == *.1 ]]; then ./gradlew :grpc-all:coveralls; fi - - bash <(curl -s https://codecov.io/bash) - -os: - - linux - -dist: xenial - -jdk: - - openjdk8 - - openjdk11 - -notifications: - email: false - -cache: - directories: - - /tmp/protobuf-cache - - /tmp/gradle-caches-modules-2 - - /tmp/gradle-wrapper - -before_cache: - # The lock changes based on folder name; normally $HOME/.gradle/caches/modules-2/modules-2.lock - - rm /tmp/gradle-caches-modules-2/gradle-caches-modules-2.lock - - find $HOME/.gradle/wrapper -not -name "*-all.zip" -and -not -name "*-bin.zip" -delete diff --git a/BUILD.bazel b/BUILD.bazel index 4bf8cdbc9b5..27a99fb62eb 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -12,6 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +load("@com_google_protobuf//bazel:java_proto_library.bzl", "java_proto_library") +load("@rules_java//java:defs.bzl", "java_library", "java_plugin") +load("@rules_jvm_external//:defs.bzl", "artifact") load(":java_grpc_library.bzl", "java_grpc_library") java_proto_library( @@ -32,10 +35,9 @@ java_library( "//api", "//protobuf", "//stub", - "//stub:javax_annotation", - "@com_google_code_findbugs_jsr305//jar", - "@com_google_guava_guava//jar", "@com_google_protobuf//:protobuf_java", + artifact("com.google.code.findbugs:jsr305"), + artifact("com.google.guava:guava"), ], ) @@ -46,8 +48,24 @@ java_library( "//api", "//protobuf-lite", "//stub", - "//stub:javax_annotation", - "@com_google_code_findbugs_jsr305//jar", - "@com_google_guava_guava//jar", + artifact("com.google.code.findbugs:jsr305"), + artifact("com.google.guava:guava"), + ], +) + +java_plugin( + name = "auto_value", + generates_api = 1, + processor_class = "com.google.auto.value.processor.AutoValueProcessor", + deps = [artifact("com.google.auto.value:auto-value")], +) + +java_library( + name = "auto_value_annotations", + exported_plugins = [":auto_value"], + neverlink = 1, + visibility = ["//:__subpackages__"], + exports = [ + artifact("com.google.auto.value:auto-value-annotations"), ], ) diff --git a/COMPILING.md b/COMPILING.md index c37d45bda4b..b7df1319beb 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -15,6 +15,7 @@ Some parts of grpc-java depend on Android. Since many Java developers don't have the Android SDK installed and don't need to run or modify the Android components, the build can skip it. To skip, create the file `/gradle.properties` and add `skipAndroid=true`. +Otherwise, create the file `/gradle.properties` and add `android.useAndroidX=true`. Then, to build, run: ``` @@ -43,11 +44,11 @@ This section is only necessary if you are making changes to the code generation. Most users only need to use `skipCodegen=true` as discussed above. ### Build Protobuf -The codegen plugin is C++ code and requires protobuf 3.12.0 or later. +The codegen plugin is C++ code and requires protobuf 22.5 or later. For Linux, Mac and MinGW: ``` -$ PROTOBUF_VERSION=3.12.0 +$ PROTOBUF_VERSION=22.5 $ curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz $ tar xzf protobuf-all-$PROTOBUF_VERSION.tar.gz $ cd protobuf-$PROTOBUF_VERSION @@ -67,7 +68,7 @@ For Visual C++, please refer to the [Protobuf README](https://github.com/google/ for how to compile Protobuf. gRPC-java assumes a Release build. #### Mac -Some versions of Mac OS X (e.g., 10.10) doesn't have ``/usr/local`` in the +Some versions of Mac OS X (e.g., 10.10) don't have ``/usr/local`` in the default search paths for header files and libraries. It will fail the build of the codegen. To work around this, you will need to set environment variables: ``` @@ -80,16 +81,16 @@ When building on Windows and VC++, you need to specify project properties for Gradle to find protobuf: ``` .\gradlew publishToMavenLocal ^ - -PvcProtobufInclude=C:\path\to\protobuf-3.12.0\src ^ - -PvcProtobufLibs=C:\path\to\protobuf-3.12.0\vsprojects\Release ^ + -PvcProtobufInclude=C:\path\to\protobuf\src ^ + -PvcProtobufLibs=C:\path\to\protobuf\vsprojects\Release ^ -PtargetArch=x86_32 ``` Since specifying those properties every build is bothersome, you can instead create ``\gradle.properties`` with contents like: ``` -vcProtobufInclude=C:\\path\\to\\protobuf-3.12.0\\src -vcProtobufLibs=C:\\path\\to\\protobuf-3.12.0\\vsprojects\\Release +vcProtobufInclude=C:\\path\\to\\protobuf\\src +vcProtobufLibs=C:\\path\\to\\protobuf\\vsprojects\\Release targetArch=x86_32 ``` @@ -131,23 +132,21 @@ of Android SDK being installed is shown at `Android SDK Location` at the same pa The default is `$HOME/Library/Android/sdk` for Mac OS and `$HOME/Android/Sdk` for Linux. You can change this to a custom location. -### Install via Android SDK Manager -Go to [Android SDK](https://developer.android.com/studio) and navigate to __Command line tools only__. -Download and unzip the package for your build machine OS into somewhere easy to find -(e.g., `$HOME/Android/sdk`). This will be your Android SDK home directory. -The Android SDK Manager tool is in `tools/bin/sdkmanager`. - -Run the `sdkmanager` tool: -``` -$ tools/bin/sdkmanager --update -$ tools/bin/sdkmanager "platforms;android-28" -``` -This installs Android SDK 28 into `platforms/android-28` of your Android SDK home directory. -More usage of `sdkmanager` can be found at [Android User Guide](https://developer.android.com/studio/command-line/sdkmanager). - - -After Android SDK is installed, you need to set the `ANDROID_HOME` environment variable to your -Android SDK home directory: -``` -$ export ANDROID_HOME= +### Install via Command line tools only +Go to [Android SDK](https://developer.android.com/studio#command-tools) and +download the commandlinetools package for your build machine OS. Decide where +you want the Android SDK to be stored. `$HOME/Library/Android/sdk` is typical on +Mac OS and `$HOME/Android/Sdk` for Linux. + +```sh +export ANDROID_HOME=$HOME/Android/Sdk # Adjust to your liking +mkdir $HOME/Android +mkdir $ANDROID_HOME +mkdir $ANDROID_HOME/cmdline-tools +unzip -d $ANDROID_HOME/cmdline-tools DOWNLOADS/commandlinetools-*.zip +mv $ANDROID_HOME/cmdline-tools/cmdline-tools $ANDROID_HOME/cmdline-tools/latest +# Android SDK is now ready. Now accept licenses so the build can auto-download packages +$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses + +# Add 'export ANDROID_HOME=$HOME/Android/Sdk' to your .bashrc or equivalent ``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c97ee4d3b39..646a7d986fd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,8 @@ If you are new to github, please start by reading [Pull Request howto](https://h ## Legal requirements In order to protect both you and ourselves, you will need to sign the -[Contributor License Agreement](https://identity.linuxfoundation.org/projects/cncf). +[Contributor License Agreement](https://easycla.lfx.linuxfoundation.org/). When +you make a PR, a CLA bot will provide a link for the process. ## Compiling @@ -29,56 +30,36 @@ style configurations are commonly useful. For IntelliJ 14, copy the style to `~/.IdeaIC14/config/codestyles/`, start IntelliJ, go to File > Settings > Code Style, and set the Scheme to `GoogleStyle`. -## Maintaining clean commit history - -We have few conventions for keeping history clean and making code reviews easier -for reviewers: - -* First line of commit messages should be in format of - - `package-name: summary of change` - - where the summary finishes the sentence: `This commit improves gRPC to ____________.` - - for example: - - `core,netty,interop-testing: add capacitive duractance to turbo encabulators` - -* Every time you receive a feedback on your pull request, push changes that - address it as a separate one or multiple commits with a descriptive commit - message (try avoid using vauge `addressed pr feedback` type of messages). - - Project maintainers are obligated to squash those commits into one when - merging. - -## Running tests - -### Jetty ALPN setup for IntelliJ - -The tests in interop-testing project require jetty-alpn agent running in the background -otherwise they'll fail. Here are instructions on how to setup IntellJ IDEA to enable running -those tests in IDE: - -* Settings -> Build Tools -> Gradle -> Runner -> select Gradle Test Runner -* View -> Tool Windows -> Gradle -> Edit Run Configuration -> Defaults -> JUnit -> Before lauch -> + -> Run Gradle task, enter the task in the build.gradle that sets the javaagent. - -Step 1 must be taken, otherwise by the default JUnit Test Runner running a single test in IDE will trigger all the tests. - ## Guidelines for Pull Requests How to get your contributions merged smoothly and quickly. - Create **small PRs** that are narrowly focused on **addressing a single concern**. We often times receive PRs that are trying to fix several things at a time, but only one fix is considered acceptable, nothing gets merged and both author's & review's time is wasted. Create more PRs to address different concerns and everyone will be happy. -- For speculative changes, consider opening an issue and discussing it first. If you are suggesting a behavioral or API change, consider starting with a [gRFC proposal](https://github.com/grpc/proposal). - -- Provide a good **PR description** as a record of **what** change is being made and **why** it was made. Link to a github issue if it exists. - -- Don't fix code style and formatting unless you are already changing that line to address an issue. PRs with irrelevant changes won't be merged. If you do want to fix formatting or style, do that in a separate PR. - -- Unless your PR is trivial, you should expect there will be reviewer comments that you'll need to address before merging. We expect you to be reasonably responsive to those comments, otherwise the PR will be closed after 2-3 weeks of inactivity. - -- Maintain **clean commit history** and use **meaningful commit messages**. See [maintaining clean commit history](#maintaining-clean-commit-history) for details. - +- For speculative changes, consider opening an issue and discussing it to avoid + wasting time on an inappropriate approach. If you are suggesting a behavioral + or API change, consider starting with a [gRFC + proposal](https://github.com/grpc/proposal). + +- Follow [typical Git commit message](https://cbea.ms/git-commit/#seven-rules) + structure. Have a good **commit description** as a record of **what** and + **why** the change is being made. Link to a GitHub issue if it exists. The + commit description makes a good PR description and is auto-copied by GitHub if + you have a single commit when creating the PR. + + If your change is mostly for a single module (e.g., other module changes are + trivial), prefix your commit summary with the module name changed. Instead of + "Add HTTP/2 faster-than-light support to gRPC Netty" it is more terse as + "netty: Add faster-than-light support". + +- Don't fix code style and formatting unless you are already changing that line + to address an issue. If you do want to fix formatting or style, do that in a + separate PR. + +- Unless your PR is trivial, you should expect there will be reviewer comments + that you'll need to address before merging. Address comments with additional + commits so the reviewer can review just the changes; do not squash reviewed + commits unless the reviewer agrees. PRs are squashed when merging. + - Keep your PR up to date with upstream/master (if there are merge conflicts, we can't really merge your change). - **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on. Also, `./gradlew build` (`gradlew build` on Windows) **must not introduce any new warnings**. diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 338213c6142..5048c7c5aca 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -8,21 +8,28 @@ See [CONTRIBUTING.md](https://github.com/grpc/grpc-community/blob/master/CONTRIB for general contribution guidelines. ## Maintainers (in alphabetical order) -- [creamsoup](https://github.com/creamsoup), Google LLC -- [dapengzhang0](https://github.com/dapengzhang0), Google LLC - [ejona86](https://github.com/ejona86), Google LLC -- [ericgribkoff](https://github.com/ericgribkoff), Google LLC -- [jiangtaoli2016](https://github.com/jiangtaoli2016), Google LLC +- [jdcormie](https://github.com/jdcormie), Google LLC +- [kannanjgithub](https://github.com/kannanjgithub), Google LLC - [ran-su](https://github.com/ran-su), Google LLC -- [sanjaypujare](https://github.com/sanjaypujare), Google LLC -- [srini100](https://github.com/srini100), Google LLC -- [voidzcy](https://github.com/voidzcy), Google LLC +- [sergiitk](https://github.com/sergiitk), Google LLC +- [temawi](https://github.com/temawi), Google LLC +- [YifeiZhuang](https://github.com/YifeiZhuang), Google LLC - [zhangkun83](https://github.com/zhangkun83), Google LLC ## Emeritus Maintainers (in alphabetical order) -- [carl-mastrangelo](https://github.com/carl-mastrangelo), Google LLC -- [jtattermusch](https://github.com/jtattermusch), Google LLC -- [louiscryan](https://github.com/louiscryan), Google LLC -- [nicolasnoble](https://github.com/nicolasnoble), Google LLC -- [nmittler](https://github.com/nmittler), Google LLC -- [zpencer](https://github.com/zpencer), Google LLC +- [carl-mastrangelo](https://github.com/carl-mastrangelo) +- [creamsoup](https://github.com/creamsoup) +- [dapengzhang0](https://github.com/dapengzhang0) +- [ericgribkoff](https://github.com/ericgribkoff) +- [jiangtaoli2016](https://github.com/jiangtaoli2016) +- [jtattermusch](https://github.com/jtattermusch) +- [larry-safran](https://github.com/larry-safran) +- [louiscryan](https://github.com/louiscryan) +- [markb74](https://github.com/markb74) +- [nicolasnoble](https://github.com/nicolasnoble) +- [nmittler](https://github.com/nmittler) +- [sanjaypujare](https://github.com/sanjaypujare) +- [srini100](https://github.com/srini100) +- [voidzcy](https://github.com/voidzcy) +- [zpencer](https://github.com/zpencer) diff --git a/MODULE.bazel b/MODULE.bazel new file mode 100644 index 00000000000..50fd1f95d34 --- /dev/null +++ b/MODULE.bazel @@ -0,0 +1,160 @@ +module( + name = "grpc-java", + version = "1.82.0-SNAPSHOT", # CURRENT_GRPC_VERSION + repo_name = "io_grpc_grpc_java", +) + +# GRPC_DEPS_START +IO_GRPC_GRPC_JAVA_ARTIFACTS = [ + "com.google.android:annotations:4.1.1.4", + "com.google.api.grpc:proto-google-common-protos:2.64.1", + "com.google.auth:google-auth-library-credentials:1.42.1", + "com.google.auth:google-auth-library-oauth2-http:1.42.1", + "com.google.auto.value:auto-value-annotations:1.11.0", + "com.google.auto.value:auto-value:1.11.0", + "com.google.code.findbugs:jsr305:3.0.2", + "com.google.code.gson:gson:2.13.2", + "com.google.errorprone:error_prone_annotations:2.48.0", + "com.google.guava:failureaccess:1.0.1", + "com.google.guava:guava:33.5.0-android", + "com.google.re2j:re2j:1.8", + "com.google.s2a.proto.v2:s2a-proto:0.1.3", + "com.google.truth:truth:1.4.5", + "com.squareup.okhttp:okhttp:2.7.5", + "com.squareup.okio:okio:2.10.0", # 3.0+ needs swapping to -jvm; need work to avoid flag-day + "io.netty:netty-buffer:4.1.133.Final", + "io.netty:netty-codec-http2:4.1.133.Final", + "io.netty:netty-codec-http:4.1.133.Final", + "io.netty:netty-codec-socks:4.1.133.Final", + "io.netty:netty-codec:4.1.133.Final", + "io.netty:netty-common:4.1.133.Final", + "io.netty:netty-handler-proxy:4.1.133.Final", + "io.netty:netty-handler:4.1.133.Final", + "io.netty:netty-resolver:4.1.133.Final", + "io.netty:netty-tcnative-boringssl-static:2.0.75.Final", + "io.netty:netty-tcnative-classes:2.0.75.Final", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.133.Final", + "io.netty:netty-transport-native-unix-common:4.1.133.Final", + "io.netty:netty-transport:4.1.133.Final", + "io.opencensus:opencensus-api:0.31.0", + "io.opencensus:opencensus-contrib-grpc-metrics:0.31.0", + "io.perfmark:perfmark-api:0.27.0", + "junit:junit:4.13.2", + "org.mockito:mockito-core:4.4.0", + "org.checkerframework:checker-qual:3.49.5", + "org.codehaus.mojo:animal-sniffer-annotations:1.27", +] +# GRPC_DEPS_END + +bazel_dep(name = "abseil-cpp", version = "20250512.1") +bazel_dep(name = "bazel_jar_jar", version = "0.1.11.bcr.1") +bazel_dep(name = "bazel_skylib", version = "1.7.1") +bazel_dep(name = "googleapis", version = "0.0.0-20240326-1c8d509c5", repo_name = "com_google_googleapis") +bazel_dep(name = "grpc-proto", version = "0.0.0-20240627-ec30f58.bcr.1", repo_name = "io_grpc_grpc_proto") +bazel_dep(name = "protobuf", version = "33.4", repo_name = "com_google_protobuf") +bazel_dep(name = "rules_cc", version = "0.0.9") +bazel_dep(name = "rules_java", version = "9.1.0") +bazel_dep(name = "rules_jvm_external", version = "6.0") + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + artifacts = IO_GRPC_GRPC_JAVA_ARTIFACTS, + repositories = [ + "https://repo.maven.apache.org/maven2/", + ], + strict_visibility = True, +) +use_repo(maven, "maven") + +maven.override( + coordinates = "com.google.protobuf:protobuf-java", + target = "@com_google_protobuf//:protobuf_java", +) +maven.override( + coordinates = "com.google.protobuf:protobuf-java-util", + target = "@com_google_protobuf//:protobuf_java_util", +) +maven.override( + coordinates = "com.google.protobuf:protobuf-javalite", + target = "@com_google_protobuf//:protobuf_javalite", +) +maven.override( + coordinates = "io.grpc:grpc-alts", + target = "@io_grpc_grpc_java//alts", +) +maven.override( + coordinates = "io.grpc:grpc-api", + target = "@io_grpc_grpc_java//api", +) +maven.override( + coordinates = "io.grpc:grpc-auth", + target = "@io_grpc_grpc_java//auth", +) +maven.override( + coordinates = "io.grpc:grpc-census", + target = "@io_grpc_grpc_java//census", +) +maven.override( + coordinates = "io.grpc:grpc-context", + target = "@io_grpc_grpc_java//context", +) +maven.override( + coordinates = "io.grpc:grpc-core", + target = "@io_grpc_grpc_java//core:core_maven", +) +maven.override( + coordinates = "io.grpc:grpc-googleapis", + target = "@io_grpc_grpc_java//googleapis", +) +maven.override( + coordinates = "io.grpc:grpc-grpclb", + target = "@io_grpc_grpc_java//grpclb", +) +maven.override( + coordinates = "io.grpc:grpc-inprocess", + target = "@io_grpc_grpc_java//inprocess", +) +maven.override( + coordinates = "io.grpc:grpc-netty", + target = "@io_grpc_grpc_java//netty", +) +maven.override( + coordinates = "io.grpc:grpc-netty-shaded", + target = "@io_grpc_grpc_java//netty:shaded_maven", +) +maven.override( + coordinates = "io.grpc:grpc-okhttp", + target = "@io_grpc_grpc_java//okhttp", +) +maven.override( + coordinates = "io.grpc:grpc-protobuf", + target = "@io_grpc_grpc_java//protobuf", +) +maven.override( + coordinates = "io.grpc:grpc-protobuf-lite", + target = "@io_grpc_grpc_java//protobuf-lite", +) +maven.override( + coordinates = "io.grpc:grpc-rls", + target = "@io_grpc_grpc_java//rls", +) +maven.override( + coordinates = "io.grpc:grpc-services", + target = "@io_grpc_grpc_java//services:services_maven", +) +maven.override( + coordinates = "io.grpc:grpc-stub", + target = "@io_grpc_grpc_java//stub", +) +maven.override( + coordinates = "io.grpc:grpc-testing", + target = "@io_grpc_grpc_java//testing", +) +maven.override( + coordinates = "io.grpc:grpc-xds", + target = "@io_grpc_grpc_java//xds:xds_maven", +) +maven.override( + coordinates = "io.grpc:grpc-util", + target = "@io_grpc_grpc_java//util", +) diff --git a/README.md b/README.md index 0a655313be2..8e6620c927e 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,6 @@ gRPC-Java - An RPC library and framework ======================================== -gRPC-Java works with JDK 7. gRPC-Java clients are supported on Android API -levels 14 and up (Ice Cream Sandwich and later). Deploying gRPC servers on an -Android device is not supported. - -TLS usage typically requires using Java 8, or Play Services Dynamic Security -Provider on Android. Please see the [Security Readme](SECURITY.md). - @@ -20,8 +13,29 @@ Provider on Android. Please see the [Security Readme](SECURITY.md).
Homepage:
[![Join the chat at https://gitter.im/grpc/grpc](https://badges.gitter.im/grpc/grpc.svg)](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://travis-ci.org/grpc/grpc-java.svg?branch=master)](https://travis-ci.org/grpc/grpc-java) -[![Coverage Status](https://coveralls.io/repos/grpc/grpc-java/badge.svg?branch=master&service=github)](https://coveralls.io/github/grpc/grpc-java?branch=master) +[![GitHub Actions Linux Testing](https://github.com/grpc/grpc-java/actions/workflows/testing.yml/badge.svg?branch=master)](https://github.com/grpc/grpc-java/actions/workflows/testing.yml?branch=master) +[![Line Coverage Status](https://coveralls.io/repos/grpc/grpc-java/badge.svg?branch=master&service=github)](https://coveralls.io/github/grpc/grpc-java?branch=master) +[![Branch-adjusted Line Coverage Status](https://codecov.io/gh/grpc/grpc-java/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc/grpc-java) + +Supported Platforms +------------------- + +gRPC-Java supports Java 8 and later. Android minSdkVersion 23 (Marshmallow) and +later are supported with [Java 8 language desugaring][android-java-8]. + +TLS usage on Android typically requires Play Services Dynamic Security Provider. +Please see the [Security Readme](SECURITY.md). + +Older Java versions are not directly supported, but a branch remains available +for fixes and releases. See [gRFC P5 JDK Version Support +Policy][P5-jdk-version-support]. + +Java version | gRPC Branch +------------ | ----------- +7 | 1.41.x + +[android-java-8]: https://developer.android.com/studio/write/java8-support#supported_features +[P5-jdk-version-support]: https://github.com/grpc/proposal/blob/master/P5-jdk-version-support.md#proposal Getting Started --------------- @@ -30,8 +44,8 @@ For a guided tour, take a look at the [quick start guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC basics](https://grpc.io/docs/languages/java/basics). -The [examples](https://github.com/grpc/grpc-java/tree/v1.30.0/examples) and the -[Android example](https://github.com/grpc/grpc-java/tree/v1.30.0/examples/android) +The [examples](https://github.com/grpc/grpc-java/tree/v1.81.0/examples) and the +[Android example](https://github.com/grpc/grpc-java/tree/v1.81.0/examples/android) are standalone projects that showcase the usage of gRPC. Download @@ -42,48 +56,45 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`: io.grpc grpc-netty-shaded - 1.30.2 + 1.81.0 + runtime io.grpc grpc-protobuf - 1.30.2 + 1.81.0 io.grpc grpc-stub - 1.30.2 - - - org.apache.tomcat - annotations-api - 6.0.53 - provided + 1.81.0 ``` Or for Gradle with non-Android, add to your dependencies: ```gradle -implementation 'io.grpc:grpc-netty-shaded:1.30.2' -implementation 'io.grpc:grpc-protobuf:1.30.2' -implementation 'io.grpc:grpc-stub:1.30.2' -compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+ +runtimeOnly 'io.grpc:grpc-netty-shaded:1.81.0' +implementation 'io.grpc:grpc-protobuf:1.81.0' +implementation 'io.grpc:grpc-stub:1.81.0' ``` For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and `grpc-protobuf-lite` instead of `grpc-protobuf`: ```gradle -implementation 'io.grpc:grpc-okhttp:1.30.2' -implementation 'io.grpc:grpc-protobuf-lite:1.30.2' -implementation 'io.grpc:grpc-stub:1.30.2' -compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+ +implementation 'io.grpc:grpc-okhttp:1.81.0' +implementation 'io.grpc:grpc-protobuf-lite:1.81.0' +implementation 'io.grpc:grpc-stub:1.81.0' ``` +For [Bazel](https://bazel.build), you can either +[use Maven](https://github.com/bazelbuild/rules_jvm_external) +(with the GAVs from above), or use `@io_grpc_grpc_java//api` et al (see below). + [the JARs]: -https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.30.2 +https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.81.0 Development snapshots are available in [Sonatypes's snapshot -repository](https://oss.sonatype.org/content/repositories/snapshots/). +repository](https://central.sonatype.com/repository/maven-snapshots/). Generated Code -------------- @@ -101,7 +112,7 @@ For protobuf-based codegen integrated with the Maven build system, you can use kr.motd.maven os-maven-plugin - 1.6.2 + 1.7.1 @@ -110,9 +121,9 @@ For protobuf-based codegen integrated with the Maven build system, you can use protobuf-maven-plugin 0.6.1 - com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier} + com.google.protobuf:protoc:3.25.8:exe:${os.detected.classifier} grpc-java - io.grpc:protoc-gen-grpc-java:1.30.2:exe:${os.detected.classifier} + io.grpc:protoc-gen-grpc-java:1.81.0:exe:${os.detected.classifier} @@ -129,20 +140,20 @@ For protobuf-based codegen integrated with the Maven build system, you can use [protobuf-maven-plugin]: https://www.xolstice.org/protobuf-maven-plugin/ -For protobuf-based codegen integrated with the Gradle build system, you can use -[protobuf-gradle-plugin][]: +For non-Android protobuf-based codegen integrated with the Gradle build system, +you can use [protobuf-gradle-plugin][]: ```gradle plugins { - id 'com.google.protobuf' version '0.8.8' + id 'com.google.protobuf' version '0.9.5' } protobuf { protoc { - artifact = "com.google.protobuf:protoc:3.12.0" + artifact = "com.google.protobuf:protoc:3.25.8" } plugins { grpc { - artifact = 'io.grpc:protoc-gen-grpc-java:1.30.2' + artifact = 'io.grpc:protoc-gen-grpc-java:1.81.0' } } generateProtoTasks { @@ -159,7 +170,43 @@ The prebuilt protoc-gen-grpc-java binary uses glibc on Linux. If you are compiling on Alpine Linux, you may want to use the [Alpine grpc-java package][] which uses musl instead. -[Alpine grpc-java package]: https://pkgs.alpinelinux.org/package/edge/testing/x86_64/grpc-java +[Alpine grpc-java package]: https://pkgs.alpinelinux.org/package/edge/community/x86_64/grpc-java + +For Android protobuf-based codegen integrated with the Gradle build system, also +use protobuf-gradle-plugin but specify the 'lite' options: + +```gradle +plugins { + id 'com.google.protobuf' version '0.9.5' +} + +protobuf { + protoc { + artifact = "com.google.protobuf:protoc:3.25.8" + } + plugins { + grpc { + artifact = 'io.grpc:protoc-gen-grpc-java:1.81.0' + } + } + generateProtoTasks { + all().each { task -> + task.builtins { + java { option 'lite' } + } + task.plugins { + grpc { option 'lite' } + } + } + } +} + +``` + +For [Bazel](https://bazel.build), use the [`proto_library`](https://github.com/bazelbuild/rules_proto) +and the [`java_proto_library`](https://bazel.build/reference/be/java#java_proto_library) (no `load()` required) +and `load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")` (from this project), as in +[this example `BUILD.bazel`](https://github.com/grpc/grpc-java/blob/master/examples/BUILD.bazel). API Stability ------------- @@ -210,12 +257,18 @@ wire. The interfaces to it are abstract just enough to allow plugging in of different implementations. Note the transport layer API is considered internal to gRPC and has weaker API guarantees than the core API under package `io.grpc`. -gRPC comes with three Transport implementations: +gRPC comes with multiple Transport implementations: -1. The Netty-based transport is the main transport implementation based on - [Netty](https://netty.io). It is for both the client and the server. -2. The OkHttp-based transport is a lightweight transport based on - [OkHttp](https://square.github.io/okhttp/). It is mainly for use on Android - and is for client only. +1. The Netty-based HTTP/2 transport is the main transport implementation based + on [Netty](https://netty.io). It is not officially supported on Android. + There is a "grpc-netty-shaded" version of this transport. It is generally + preferred over using the Netty-based transport directly as it requires less + dependency management and is easier to upgrade within many applications. +2. The OkHttp-based HTTP/2 transport is a lightweight transport based on + [Okio](https://square.github.io/okio/) and forked low-level parts of + [OkHttp](https://square.github.io/okhttp/). It is mainly for use on Android. 3. The in-process transport is for when a server is in the same process as the - client. It is useful for testing, while also being safe for production use. + client. It is used frequently for testing, while also being safe for + production use. +4. The Binder transport is for Android cross-process communication on a single + device. diff --git a/RELEASING.md b/RELEASING.md index 8d3a8b14fe4..c57829b8c25 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -4,51 +4,32 @@ How to Create a Release of GRPC Java (for Maintainers Only) Build Environments ------------------ We deploy GRPC to Maven Central under the following systems: -- Ubuntu 14.04 with Docker 13.03.0 that runs CentOS 6.9 +- Ubuntu 14.04 with Docker 13.03.0 that runs CentOS 7 - Windows 7 64-bit with Visual Studio - Mac OS X 10.14.6 Other systems may also work, but we haven't verified them. -Prerequisites -------------- - -### Set Up OSSRH Account - -If you haven't deployed artifacts to Maven Central before, you need to setup -your OSSRH (OSS Repository Hosting) account. -- Follow the instructions on [this - page](https://central.sonatype.org/pages/ossrh-guide.html) to set up an - account with OSSRH. - - You only need to create the account, not set up a new project - - Contact a gRPC maintainer to add your account after you have created it. - Common Variables ---------------- Many of the following commands expect release-specific variables to be set. Set them before continuing, and set them again when resuming. ```bash -$ MAJOR=1 MINOR=7 PATCH=0 # Set appropriately for new release -$ VERSION_FILES=( +MAJOR=1 MINOR=7 PATCH=0 # Set appropriately for new release +VERSION_FILES=( + MODULE.bazel build.gradle core/src/main/java/io/grpc/internal/GrpcUtil.java + examples/MODULE.bazel examples/build.gradle examples/pom.xml examples/android/clientcache/app/build.gradle examples/android/helloworld/app/build.gradle examples/android/routeguide/app/build.gradle examples/android/strictmode/app/build.gradle - examples/example-alts/build.gradle - examples/example-gauth/build.gradle - examples/example-gauth/pom.xml - examples/example-jwt-auth/build.gradle - examples/example-jwt-auth/pom.xml - examples/example-hostname/build.gradle - examples/example-hostname/pom.xml - examples/example-tls/build.gradle - examples/example-tls/pom.xml - examples/example-xds/build.gradle + examples/example-*/build.gradle + examples/example-*/pom.xml ) ``` @@ -61,35 +42,34 @@ convention of `v..x`, while the tags include the patch version `v..`. For example, the same branch `v1.7.x` would be used to create all `v1.7` tags (e.g. `v1.7.0`, `v1.7.1`). -1. For `master`, change root build files to the next minor snapshot (e.g. +1. Review the issues in the current release [milestone](https://github.com/grpc/grpc-java/milestones) + for issues that won't make the cut. Check if any of them can be + closed. Be aware of the issues with the [TODO:release blocker][] label. + Consider reaching out to the assignee for the status update. +2. For `master`, change root build files to the next minor snapshot (e.g. ``1.8.0-SNAPSHOT``). ```bash - $ git checkout -b bump-version master + git checkout -b bump-version master # Change version to next minor (and keep -SNAPSHOT) - $ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$((MINOR+1)).0'\1/' \ + sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$((MINOR+1)).0'\1/' \ "${VERSION_FILES[@]}" - $ sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$((MINOR+1)).0/ \ + sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$((MINOR+1)).0/ \ compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt - $ ./gradlew build - $ git commit -a -m "Start $MAJOR.$((MINOR+1)).0 development cycle" + ./gradlew build + git commit -a -m "Start $MAJOR.$((MINOR+1)).0 development cycle" ``` -2. Go through PR review and submit. -3. Create the release branch starting just before your commit and push it to GitHub: +3. Go through PR review and submit. +4. Create the release branch starting just before your commit and push it to GitHub: ```bash - $ git fetch upstream - $ git checkout -b v$MAJOR.$MINOR.x \ - $(git log --pretty=format:%H --grep "^Start $MAJOR.$((MINOR+1)).0 development cycle$" upstream/master)^ - $ git push upstream v$MAJOR.$MINOR.x + git fetch upstream + git checkout -b v$MAJOR.$MINOR.x \ + $(git log --pretty=format:%H --grep "^Start $MAJOR.$((MINOR+1)).0 development cycle" upstream/master)^ + git push upstream v$MAJOR.$MINOR.x ``` -4. Go to [Travis CI settings](https://travis-ci.org/grpc/grpc-java/settings) and - add a _Cron Job_: - * Branch: `v$MAJOR.$MINOR.x` - * Interval: `weekly` - * Options: `Do not run if there has been a build in the last 24h` - * Click _Add_ button -5. Continue with Google-internal steps at go/grpc/java/releasing. +5. Continue with Google-internal steps at go/grpc-java/releasing, but stop + before `Auto releasing using kokoro`. 6. Create a milestone for the next release. 7. Move items out of the release milestone that didn't make the cut. Issues that may be backported should stay in the release milestone. Treat issues with the @@ -97,144 +77,176 @@ would be used to create all `v1.7` tags (e.g. `v1.7.0`, `v1.7.1`). 8. Begin compiling release notes. This produces a starting point: ```bash - $ echo "## gRPC Java $MAJOR.$MINOR.0 Release Notes" && echo && \ - git shortlog "$(git merge-base upstream/v$MAJOR.$((MINOR-1)).x upstream/v$MAJOR.$MINOR.x)"..upstream/v$MAJOR.$MINOR.x | cat && \ + echo "## gRPC Java $MAJOR.$MINOR.0 Release Notes" && echo && \ + git shortlog -e --format='%s (%h)' "$(git merge-base upstream/v$MAJOR.$((MINOR-1)).x upstream/v$MAJOR.$MINOR.x)"..upstream/v$MAJOR.$MINOR.x | cat && \ echo && echo && echo "Backported commits in previous release:" && \ - git cherry -v v$MAJOR.$((MINOR-1)).0 upstream/v$MAJOR.$MINOR.x | grep ^- + git log --oneline "$(git merge-base v$MAJOR.$((MINOR-1)).0 upstream/v$MAJOR.$MINOR.x)"..v$MAJOR.$((MINOR-1)).0^ ``` +[TODO:release blocker]: https://github.com/grpc/grpc-java/issues?q=label%3A%22TODO%3Arelease+blocker%22 +[TODO:backport]: https://github.com/grpc/grpc-java/issues?q=label%3ATODO%3Abackport + Tagging the Release ------------------- 1. Verify there are no open issues in the release milestone. Open issues should - either be deferred or resolved and the fix backported. -2. For vMajor.Minor.x branch, change `README.md` to refer to the next release + either be deferred or resolved and the fix backported. Verify there are no + [TODO:release blocker][] nor [TODO:backport][] issues (open or closed), or + that they are tracking an issue for a different branch. +2. Ensure that the Google-internal steps + at go/grpc-java/releasing#before-tagging-a-release are completed. +3. For vMajor.Minor.x branch, change `README.md` to refer to the next release version. _Also_ update the version numbers for protoc if the protobuf library version was updated since the last release. ```bash - $ git checkout v$MAJOR.$MINOR.x - $ git pull upstream v$MAJOR.$MINOR.x - $ git checkout -b release - # Bump documented versions. Don't forget protobuf version - $ ${EDITOR:-nano -w} README.md - $ ${EDITOR:-nano -w} documentation/android-channel-builder.md - $ ${EDITOR:-nano -w} cronet/README.md - $ git commit -a -m "Update README etc to reference $MAJOR.$MINOR.$PATCH" + git checkout v$MAJOR.$MINOR.x + git pull upstream v$MAJOR.$MINOR.x + git checkout -b release-v$MAJOR.$MINOR.$PATCH + + # Bump documented gRPC versions. + # Also update protoc version to match protobuf version in gradle/libs.versions.toml. + ${EDITOR:-nano -w} README.md + + git commit -a -m "Update README etc to reference $MAJOR.$MINOR.$PATCH" ``` -3. Change root build files to remove "-SNAPSHOT" for the next release version +4. Change root build files to remove "-SNAPSHOT" for the next release version (e.g. `0.7.0`). Commit the result and make a tag: ```bash # Change version to remove -SNAPSHOT - $ sed -i 's/-SNAPSHOT\(.*CURRENT_GRPC_VERSION\)/\1/' "${VERSION_FILES[@]}" - $ sed -i s/-SNAPSHOT// compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt - $ ./gradlew build - $ git commit -a -m "Bump version to $MAJOR.$MINOR.$PATCH" - $ git tag -a v$MAJOR.$MINOR.$PATCH -m "Version $MAJOR.$MINOR.$PATCH" + sed -i 's/-SNAPSHOT\(.*CURRENT_GRPC_VERSION\)/\1/' "${VERSION_FILES[@]}" + sed -i s/-SNAPSHOT// compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt + ./gradlew build + git commit -a -m "Bump version to $MAJOR.$MINOR.$PATCH" + git tag -a v$MAJOR.$MINOR.$PATCH -m "Version $MAJOR.$MINOR.$PATCH" ``` -4. Change root build files to the next snapshot version (e.g. `0.7.1-SNAPSHOT`). +5. Change root build files to the next snapshot version (e.g. `0.7.1-SNAPSHOT`). Commit the result: ```bash # Change version to next patch and add -SNAPSHOT - $ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT'\1/' \ + sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT'\1/' \ "${VERSION_FILES[@]}" - $ sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT/ \ + sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT/ \ compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt - $ ./gradlew build - $ git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT" + ./gradlew build + git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT" + git push -u origin release-v$MAJOR.$MINOR.$PATCH ``` -5. Go through PR review and push the release tag and updated release branch to - GitHub: + Raise a PR and set the base branch of the PR to v$MAJOR.$MINOR.x of the upstream grpc-java repo. +6. Go through PR review and push the release tag and updated release branch to + GitHub (DO NOT click the merge button on the GitHub page): ```bash - $ git checkout v$MAJOR.$MINOR.x - $ git merge --ff-only release - $ git push upstream v$MAJOR.$MINOR.x - $ git push upstream v$MAJOR.$MINOR.$PATCH + git checkout v$MAJOR.$MINOR.x + git merge --ff-only release-v$MAJOR.$MINOR.$PATCH + git push upstream v$MAJOR.$MINOR.x + git push upstream v$MAJOR.$MINOR.$PATCH ``` -6. Close the release milestone. - -Build Artifacts ---------------- - -Trigger build as described in "Auto releasing using kokoro" at -go/grpc/java/releasing. - -It runs three jobs on Kokoro, one on each platform. See their scripts: -`linux_artifacts.sh`, `windows.bat`, and `unix.sh` (called directly for OS X; -called within the Docker environment on Linux). The mvn-artifacts/ outputs of -each script is combined into a single folder and then processed by -`upload_artifacts.sh`, which signs the files and uploads to Sonatype. - -Releasing on Maven Central --------------------------- - -Once all of the artifacts have been pushed to the staging repository, the -repository should have been closed by `upload_artifacts.sh`. Closing triggers -several sanity checks on the repository. If this completes successfully, the -repository can then be `released`, which will begin the process of pushing the -new artifacts to Maven Central (the staging repository will be destroyed in the -process). You can see the complete process for releasing to Maven Central on the -[OSSRH site](https://central.sonatype.org/pages/releasing-the-deployment.html). - -Build interop container image ------------------------------ - -We have containers for each release to detect compatibility regressions with old -releases. Generate one for the new release by following the -[GCR image generation instructions](https://github.com/grpc/grpc/blob/master/tools/interop_matrix/README.md#step-by-step-instructions-for-adding-a-gcr-image-for-a-new-release-for-compatibility-test). - -Update README.md ----------------- -After waiting ~1 day and verifying that the release appears on [Maven -Central](https://search.maven.org/search?q=g:io.grpc), cherry-pick the commit -that updated the README into the master branch and go through review process. - -``` -$ git checkout -b bump-readme master -$ git cherry-pick v$MAJOR.$MINOR.$PATCH^ -``` - -Update version referenced by tutorials --------------------------------------- - -Update the `grpc_java_release_tag` in -[config.yaml](https://github.com/grpc/grpc.io/blob/master/config.yaml) -of the grpc.io repository. - -Notify the Community --------------------- -Finally, document and publicize the release. - -1. Add [Release Notes](https://github.com/grpc/grpc-java/releases) for the new tag. - The description should include any major fixes or features since the last release. - You may choose to add links to bugs, PRs, or commits if appropriate. -2. Post a release announcement to [grpc-io](https://groups.google.com/forum/#!forum/grpc-io) - (`grpc-io@googlegroups.com`). The title should be something that clearly identifies - the release (e.g.`GRPC-Java Released`). - 1. Check if JCenter has picked up the new release (https://jcenter.bintray.com/io/grpc/) - and include its availability in the release announcement email. JCenter should mirror - everything on Maven Central, but users have reported delays. - -Update Hosted Javadoc +7. Close the release milestone. + +8. Trigger build as described in "Auto releasing using kokoro" at + go/grpc-java/releasing. + + It runs three jobs on Kokoro, one on each platform. See their scripts: + `linux_artifacts.sh`, `windows.bat`, and `macos.sh`. The mvn-artifacts/ + outputs of each script is combined into a single folder and then processed + by `upload_artifacts.sh`, which signs the files and uploads to Sonatype. + +9. Once all of the artifacts have been pushed to the staging repository, the + repository should have been closed by `upload_artifacts.sh`. Closing triggers + several sanity checks on the repository. If this completes successfully, the + repository can then be `released`, which will begin the process of pushing + the new artifacts to Maven Central (the staging repository will be destroyed + in the process). You can see the complete process for releasing to Maven + Central on the [OSSRH site](https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#deploying). + +10. We have containers for each release to detect compatibility regressions with + old releases. Generate one for the new release by following the [GCR image + generation instructions][gcr-image]. Summary: + ```bash + # If you haven't previously configured docker: + gcloud auth configure-docker us-docker.pkg.dev + + # In main grpc repo, add the new version to matrix + ${EDITOR:-nano -w} tools/interop_matrix/client_matrix.py + tools/interop_matrix/create_matrix_images.py --git_checkout --release=v$MAJOR.$MINOR.$PATCH \ + --upload_images --language java + docker pull us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH + docker_image=us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH \ + tools/interop_matrix/testcases/java__master + + # Commit the changes + git commit --all -m "[interop] Add grpc-java $MAJOR.$MINOR.$PATCH to client_matrix.py" + + # Create a PR with the `release notes: no` label and run ad-hoc test against your PR + ``` +[gcr-image]: https://github.com/grpc/grpc/blob/master/tools/interop_matrix/README.md#step-by-step-instructions-for-adding-a-gcr-image-for-a-new-release-for-compatibility-test + +11. Update gh-pages with the new Javadoc. Generally the file is on repo1 + 15 minutes after publishing: + + ```bash + git checkout gh-pages + git pull --ff-only upstream gh-pages + rm -r javadoc/ + wget -O grpc-all-javadoc.jar "https://repo1.maven.org/maven2/io/grpc/grpc-all/$MAJOR.$MINOR.$PATCH/grpc-all-$MAJOR.$MINOR.$PATCH-javadoc.jar" + unzip -d javadoc grpc-all-javadoc.jar + patch -p1 < ga.patch + rm grpc-all-javadoc.jar + rm -r javadoc/META-INF/ + git add -A javadoc + git commit -m "Javadoc for $MAJOR.$MINOR.$PATCH" + git push upstream gh-pages + ``` + + Verify the current version is [live on grpc.io](https://grpc.io/grpc-java/javadoc/). + +12. Add [Release Notes](https://github.com/grpc/grpc-java/releases) for the new tag. + *Make sure that any backports are reflected in the release notes.* + +13. Notify the Community. Post a release announcement to + [grpc-io](https://groups.google.com/forum/#!forum/grpc-io) + (`grpc-io@googlegroups.com`) with the title `gRPC-Java v$MAJOR.$MINOR.$PATCH + Released`. The email content should link to the GitHub release notes and + include a copy of them. + +14. Update README.md. Cherry-pick the commit that updated the README.md into the + master branch. + + ```bash + git checkout -b bump-readme master + git cherry-pick v$MAJOR.$MINOR.$PATCH^ + git push --set-upstream origin bump-readme + ``` + + Create a PR and go through the review process + +15. Update version referenced by tutorials. Update `params.grpc_vers.java` in + [config.yaml](https://github.com/grpc/grpc.io/blob/master/config.yaml) of + the grpc.io repository. Create a PR and go through the review process. + +Post-release upgrades --------------------- +Upgrade dependencies after the release so they can be well-tested before the +next release. -Now we need to update gh-pages with the new Javadoc: +Upgrade the Gradle plugins in `settings.gradle` and the Gradle version in +`gradle/wrapper/gradle-wrapper.properties`. Make sure to read the release notes +for each dependency upgraded. Test by doing a regular build. + +Upgrade the regular dependencies in `gradle/libs.versions.toml`, except for +Netty and netty-tcnative. To find available upgrades: ```bash -git checkout gh-pages -git pull --ff-only -rm -r javadoc/ -wget -O grpc-all-javadoc.jar "http://search.maven.org/remotecontent?filepath=io/grpc/grpc-all/$MAJOR.$MINOR.$PATCH/grpc-all-$MAJOR.$MINOR.$PATCH-javadoc.jar" -unzip -d javadoc grpc-all-javadoc.jar -patch -p1 < ga.patch -rm grpc-all-javadoc.jar -rm -r javadoc/META-INF/ -git add -A javadoc -git commit -m "Javadoc for $MAJOR.$MINOR.$PATCH" +./gradlew checkForUpdates ``` -Push gh-pages to the main repository and verify the current version is [live -on grpc.io](https://grpc.io/grpc-java/javadoc/). +Test by doing a regular build. For each step, if a dependency cannot be +upgraded, add a comment. Create issues in other projects for breakages, and in +gRPC for things that will need a migration effort. + +When happy with the dependency upgrades, update the versions in `MODULE.bazel`, +`repositories.bzl`, and the various `pom.xml` and `build.gradle` files in +`examples/`. diff --git a/SECURITY.md b/SECURITY.md index 45d75542bb4..e710ceaabe1 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,6 +1,16 @@ +# Security Policy + +For information on gRPC Security Policy and reporting potentional security +issues, please see [gRPC CVE Process][]. + +[gRPC CVE Process]: https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md + # Authentication -gRPC supports a number of different mechanisms for asserting identity between an client and server. This document provides code samples demonstrating how to provide SSL/TLS encryption support and identity assertions in Java, as well as passing OAuth2 tokens to services that support it. +gRPC supports a number of different mechanisms for asserting identity between an +client and server. This document provides code samples demonstrating how to +provide SSL/TLS encryption support and identity assertions in Java, as well as +passing OAuth2 tokens to services that support it. # Transport Security (TLS) @@ -15,25 +25,28 @@ BoringSSL](#tls-with-netty-tcnative-on-boringssl). ## TLS on Android On Android we recommend the use of the [Play Services Dynamic Security -Provider](https://www.appfoundry.be/blog/2014/11/18/Google-Play-Services-Dynamic-Security-Provider/) -to ensure your application has an up-to-date OpenSSL library with the necessary -cipher-suites and a reliable ALPN implementation. This requires [updating the -security provider at -runtime](https://developer.android.com/training/articles/security-gms-provider.html). +Provider][] to ensure your application has an up-to-date OpenSSL library with +the necessary cipher-suites and a reliable ALPN implementation. This requires +[updating the security provider at runtime][config-psdsp]. Although ALPN mostly works on newer Android releases (especially since 5.0), there are bugs and discovered security vulnerabilities that are only fixed by upgrading the security provider. Thus, we recommend using the Play Service Dynamic Security Provider for all Android versions. -*Note: The Dynamic Security Provider must be installed **before** creating a gRPC OkHttp channel. gRPC's OkHttpProtocolNegotiator statically initializes the security protocol(s) available to gRPC, which means that changes to the security provider after the first channel is created will not be picked up by gRPC.* +*Note: The Dynamic Security Provider must be installed **before** creating a +gRPC OkHttp channel. gRPC statically initializes the security protocol(s) +available, which means that changes to the security provider after the first +channel is created will not be noticed by gRPC.* + +[Play Services Dynamic Security Provider]: https://www.appfoundry.be/blog/2014/11/18/Google-Play-Services-Dynamic-Security-Provider/ +[config-psdsp]: https://developer.android.com/training/articles/security-gms-provider.html ### Bundling Conscrypt If depending on Play Services is not an option for your app, then you may bundle [Conscrypt](https://conscrypt.org) with your application. Binaries are available -on [Maven -Central](https://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.conscrypt%20a%3Aconscrypt-android). +on [Maven Central][conscrypt-maven]. Like the Play Services Dynamic Security Provider, you must still "install" Conscrypt before use. @@ -46,16 +59,22 @@ import java.security.Security; Security.insertProviderAt(Conscrypt.newProvider(), 1); ``` +[conscrypt-maven]: https://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.conscrypt%20a%3Aconscrypt-android + ## TLS on non-Android -JDK versions prior to Java 9 do not support ALPN and are either missing AES GCM -support or have 2% the performance of OpenSSL. +OpenJDK versions prior to Java 8u252 do not support ALPN. Java 8 has 10% the +performance of OpenSSL. We recommend most users use grpc-netty-shaded, which includes netty-tcnative on BoringSSL. It includes pre-built libraries for 64 bit Windows, OS X, and 64 bit Linux. For 32 bit Windows, Conscrypt is an option. For all other platforms, Java 9+ is required. +For users of xDS management protocol, the grpc-netty-shaded transport is +particularly appropriate since it is already used internally for the xDS +protocol and is a runtime dependency of grpc-xds. + For users of grpc-netty we recommend [netty-tcnative with BoringSSL](#tls-with-netty-tcnative-on-boringssl), although using the built-in JDK support in Java 9+, [Conscrypt](#tls-with-conscrypt), and [netty-tcnative @@ -65,7 +84,7 @@ with OpenSSL](#tls-with-netty-tcnative-on-openssl) are other valid options. [Apache Tomcat's tcnative](https://tomcat.apache.org/native-doc/) and is a JNI wrapper around OpenSSL/BoringSSL/LibreSSL. -We recommend BoringSSL for its simplicitly and low occurrence of security +We recommend BoringSSL for its simplicity and low occurrence of security vulnerabilities relative to OpenSSL. BoringSSL is used by Conscrypt as well. ### TLS with netty-tcnative on BoringSSL @@ -151,7 +170,7 @@ the dependency. kr.motd.maven os-maven-plugin - 1.6.2 + 1.7.1 @@ -232,45 +251,9 @@ import java.security.Security; ... // Somewhere in main() -Security.insertProviderAt( - Conscrypt.newProviderBuilder().provideTrustManager(false).build(), 1); +Security.insertProviderAt(Conscrypt.newProvider(), 1); ``` -Note: according to [Conscrypt Implementation Notes](https://github.com/google/conscrypt/blob/2.4.0/IMPLEMENTATION_NOTES.md#hostname-verification), -its default `HostnameVerifier` on OpenJDK always fails. This can be worked -around by disabling its default `TrustManager` implementation as shown above. - -### TLS with Jetty ALPN - -**Please do not use Jetty ALPN** - -gRPC historically supported Jetty ALPN for ALPN on Java 8. While functional, it -suffers from poor performance and breakages when the JRE is upgraded. -When mis-matched to the JRE version, it can also produce unpredictable errors -that are hard to diagnose. When using it, it became common practice that any -time we saw a TLS failure that made no sense we would blame a Jetty ALPN/JRE -version mismatch and we were overwhelmingly correct. The Jetty ALPN agent makes -it much easier to use, but we still strongly discourage Jetty ALPN's use. - -When using Jetty ALPN with Java 8, realize that performance will be 2-10% that -of the other options due to a slow AES GCM implementation in Java. - -#### Configuring Jetty ALPN in Web Containers - -Some web containers, such as [Jetty](https://www.eclipse.org/jetty/documentation/current/jetty-classloading.html) restrict access to server classes for web applications. A gRPC client running within such a container must be properly configured to allow access to the ALPN classes. In Jetty, this is done by including a `WEB-INF/jetty-env.xml` file containing the following: - -```xml - - - - - - - - -org.eclipse.jetty.alpn. - - -``` ## Enabling TLS on a server To use TLS on the server, a certificate chain and private key need to be @@ -278,35 +261,36 @@ specified in PEM format. The standard TLS port is 443, but we use 8443 below to avoid needing extra permissions from the OS. ```java -Server server = ServerBuilder.forPort(8443) - // Enable TLS - .useTransportSecurity(certChainFile, privateKeyFile) +ServerCredentials creds = TlsServerCredentials.create(certChainFile, privateKeyFile); +Server server = Grpc.newServerBuilderForPort(8443, creds) .addService(serviceImplementation) - .build(); -server.start(); + .build() + .start(); ``` If the issuing certificate authority is not known to the client then a properly -configured SslContext or SSLSocketFactory should be provided to the -NettyChannelBuilder or OkHttpChannelBuilder, respectively. +configured trust manager should be provided to TlsChannelCredentials and used to +construct the channel. ## Mutual TLS [Mutual authentication][] (or "client-side authentication") configuration is similar to the server by providing truststores, a client certificate and private key to the client channel. The server must also be configured to request a certificate from clients, as well as truststores for which client certificates it should allow. ```java -Server server = NettyServerBuilder.forPort(8443) - .sslContext(GrpcSslContexts.forServer(certChainFile, privateKeyFile) - .trustManager(clientCAsFile) - .clientAuth(ClientAuth.REQUIRE) - .build()); +ServerCredentials creds = TlsServerCredentials.newBuilder() + .keyManager(certChainFile, privateKeyFile) + .trustManager(clientCAsFile) + .clientAuth(TlsServerCredentials.ClientAuth.REQUIRE) + .build(); ``` -Negotiated client certificates are available in the SSLSession, which is found in the `TRANSPORT_ATTR_SSL_SESSION` attribute of Grpc. A server interceptor can provide details in the current Context. +Negotiated client certificates are available in the SSLSession, which is found +in the `Grpc.TRANSPORT_ATTR_SSL_SESSION` attribute of the call. A server +interceptor can provide details in the current Context. ```java -// The application uses this in its handlers -public final static Context.Key SSL_SESSION_CONTEXT = Context.key("SSLSession"); +// The application uses this in its handlers. +public static final Context.Key SECURITY_INFO = Context.key("my.security.Info"); @Override public ServerCall.Listener interceptCall(ServerCall call, @@ -315,8 +299,12 @@ public ServerCall.Listener interceptCall(ServerCall subproject.javadoc.classpath }) @@ -44,24 +51,18 @@ javadoc { continue; } source subproject.javadoc.source - options.links subproject.javadoc.options.links.toArray(new String[0]) + options.linksOffline.addAll subproject.javadoc.options.linksOffline } } -task jacocoMerge(type: JacocoMerge) { - dependsOn(subprojects.jacocoTestReport.dependsOn) +tasks.named("jacocoTestReport").configure { mustRunAfter(subprojects.jacocoTestReport.mustRunAfter) - destinationFile = file("${buildDir}/jacoco/test.exec") - executionData = files(subprojects.jacocoTestReport.executionData) + mustRunAfter(project(':grpc-interop-testing').jacocoTestReport.mustRunAfter) + executionData.from files(subprojects.jacocoTestReport.executionData) .plus(project(':grpc-interop-testing').jacocoTestReport.executionData) - .filter { f -> f.exists() } -} - -jacocoTestReport { - dependsOn(jacocoMerge) reports { - xml.enabled = true - html.enabled = true + xml.required = true + html.required = true } subprojects.each { subproject -> @@ -75,4 +76,4 @@ coveralls { sourceDirs = subprojects.sourceSets.main.allSource.srcDirs.flatten() } -tasks.coveralls { dependsOn(jacocoTestReport) } +tasks.named("coveralls").configure { dependsOn tasks.named("jacocoTestReport") } diff --git a/alts/BUILD.bazel b/alts/BUILD.bazel index cf67059fa07..f29df303fbe 100644 --- a/alts/BUILD.bazel +++ b/alts/BUILD.bazel @@ -1,4 +1,7 @@ -load("@rules_proto//proto:defs.bzl", "proto_library") +load("@com_google_protobuf//bazel:java_proto_library.bzl", "java_proto_library") +load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") +load("@rules_java//java:defs.bzl", "java_library") +load("@rules_jvm_external//:defs.bzl", "artifact") load("//:java_grpc_library.bzl", "java_grpc_library") java_library( @@ -11,19 +14,18 @@ java_library( ":handshaker_java_proto", "//api", "//core:internal", - "//grpclb", "//netty", "//stub", - "@com_google_code_findbugs_jsr305//jar", - "@com_google_guava_guava//jar", - "@com_google_j2objc_j2objc_annotations//jar", "@com_google_protobuf//:protobuf_java", "@com_google_protobuf//:protobuf_java_util", - "@io_netty_netty_buffer//jar", - "@io_netty_netty_codec//jar", - "@io_netty_netty_common//jar", - "@io_netty_netty_handler//jar", - "@io_netty_netty_transport//jar", + artifact("com.google.code.findbugs:jsr305"), + artifact("com.google.errorprone:error_prone_annotations"), + artifact("com.google.guava:guava"), + artifact("io.netty:netty-buffer"), + artifact("io.netty:netty-codec"), + artifact("io.netty:netty-common"), + artifact("io.netty:netty-handler"), + artifact("io.netty:netty-transport"), ], ) @@ -36,18 +38,17 @@ java_library( deps = [ ":alts_internal", ":handshaker_java_grpc", + ":handshaker_java_proto", "//api", "//auth", "//core:internal", "//netty", - "@com_google_auth_google_auth_library_oauth2_http//jar", - "@com_google_code_findbugs_jsr305//jar", - "@com_google_guava_guava//jar", - "@com_google_j2objc_j2objc_annotations//jar", - "@io_netty_netty_common//jar", - "@io_netty_netty_handler//jar", - "@io_netty_netty_transport//jar", - "@org_apache_commons_commons_lang3//jar", + artifact("com.google.auth:google-auth-library-oauth2-http"), + artifact("com.google.code.findbugs:jsr305"), + artifact("com.google.guava:guava"), + artifact("io.netty:netty-common"), + artifact("io.netty:netty-handler"), + artifact("io.netty:netty-transport"), ], ) diff --git a/alts/build.gradle b/alts/build.gradle index 9a04f0dd090..c206a37bcef 100644 --- a/alts/build.gradle +++ b/alts/build.gradle @@ -2,77 +2,78 @@ plugins { id "java-library" id "maven-publish" - id "com.github.johnrengelman.shadow" id "com.google.protobuf" + id "com.gradleup.shadow" id "ru.vyarus.animalsniffer" } description = "gRPC: ALTS" -sourceCompatibility = 1.7 -targetCompatibility = 1.7 - dependencies { - api project(':grpc-core') + api project(':grpc-api') implementation project(':grpc-auth'), - project(':grpc-grpclb'), + project(':grpc-core'), + project(":grpc-context"), // Override google-auth dependency with our newer version project(':grpc-protobuf'), project(':grpc-stub'), - libraries.lang, - libraries.protobuf, - libraries.conscrypt + libraries.protobuf.java, + libraries.conscrypt, + libraries.google.auth.oauth2Http def nettyDependency = implementation project(':grpc-netty') - implementation (libraries.google_auth_oauth2_http) { - // prefer our own versions instead of google-auth-oauth2-http's dependency - exclude group: 'com.google.guava', module: 'guava' - // we'll always be more up-to-date - exclude group: 'io.grpc', module: 'grpc-context' - } - guavaDependency 'implementation' - compileOnly libraries.javax_annotation shadow configurations.implementation.getDependencies().minus(nettyDependency) shadow project(path: ':grpc-netty-shaded', configuration: 'shadow') testImplementation project(':grpc-testing'), + testFixtures(project(':grpc-core')), + project(':grpc-inprocess'), project(':grpc-testing-proto'), libraries.guava, libraries.junit, - libraries.mockito, + libraries.mockito.core, libraries.truth - testImplementation (libraries.guava_testlib) { - exclude group: 'junit', module: 'junit' + testImplementation libraries.guava.testlib + testRuntimeOnly libraries.netty.tcnative, + libraries.netty.tcnative.classes + testRuntimeOnly (libraries.netty.transport.epoll) { + artifact { + classifier = "linux-x86_64" + } + } + signature (libraries.signature.java) { + artifact { + extension = "signature" + } } - testRuntimeOnly libraries.netty_tcnative, - libraries.netty_epoll - signature 'org.codehaus.mojo.signature:java17:1.0@signature' } configureProtoCompilation() import net.ltgt.gradle.errorprone.CheckSeverity -[compileJava, compileTestJava].each() { - // protobuf calls valueof. Will be fixed in next release (google/protobuf#4046) - it.options.compilerArgs += [ - "-Xlint:-deprecation" - ] +[tasks.named("compileJava"), tasks.named("compileTestJava")]*.configure { // ALTS returns a lot of futures that we mostly don't care about. - it.options.errorprone.check("FutureReturnValueIgnored", CheckSeverity.OFF) + options.errorprone.check("FutureReturnValueIgnored", CheckSeverity.OFF) } -javadoc { exclude 'io/grpc/alts/internal/**' } +tasks.named("javadoc").configure { + exclude 'io/grpc/alts/internal/**' + exclude 'io/grpc/alts/Internal*' +} -jar { - // Must use a different classifier to avoid conflicting with shadowJar - classifier = 'original' +tasks.named("jar").configure { + // Must use a different archiveClassifier to avoid conflicting with shadowJar + archiveClassifier = 'original' + manifest { + attributes('Automatic-Module-Name': 'io.grpc.alts') + } } // We want to use grpc-netty-shaded instead of grpc-netty. But we also want our // source to work with Bazel, so we rewrite the code as part of the build. -shadowJar { - classifier = null +tasks.named("shadowJar").configure { + archiveClassifier = null dependencies { exclude(dependency {true}) } @@ -83,8 +84,7 @@ shadowJar { publishing { publications { maven(MavenPublication) { - // use shadowJar and remove the original Jar - artifact shadowJar + // We want this to throw an exception if it isn't working def originalJar = artifacts.find { dep -> dep.classifier == 'original'} artifacts.remove(originalJar) @@ -94,8 +94,7 @@ publishing { def dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('groupId', dep.group) dependencyNode.appendNode('artifactId', dep.name) - def version = (dep.name == 'grpc-netty-shaded') ? '[' + dep.version + ']' : dep.version - dependencyNode.appendNode('version', version) + dependencyNode.appendNode('version', dep.version) dependencyNode.appendNode('scope', 'compile') } asNode().dependencies[0].replaceNode(dependenciesNode) diff --git a/alts/src/generated/main/grpc/io/grpc/alts/internal/HandshakerServiceGrpc.java b/alts/src/generated/main/grpc/io/grpc/alts/internal/HandshakerServiceGrpc.java index 9f68246d9e0..07e4256eb75 100644 --- a/alts/src/generated/main/grpc/io/grpc/alts/internal/HandshakerServiceGrpc.java +++ b/alts/src/generated/main/grpc/io/grpc/alts/internal/HandshakerServiceGrpc.java @@ -1,30 +1,15 @@ package io.grpc.alts.internal; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** */ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/gcp/handshaker.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class HandshakerServiceGrpc { private HandshakerServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.gcp.HandshakerService"; + public static final java.lang.String SERVICE_NAME = "grpc.gcp.HandshakerService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public HandshakerServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new HandshakerServiceBlockingV2Stub(channel, callOptions); + } + }; + return HandshakerServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -104,7 +104,7 @@ public HandshakerServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.Call /** */ - public static abstract class HandshakerServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
@@ -116,27 +116,28 @@ public static abstract class HandshakerServiceImplBase implements io.grpc.Bindab
      * response before sending next request.
      * 
*/ - public io.grpc.stub.StreamObserver doHandshake( + default io.grpc.stub.StreamObserver doHandshake( io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getDoHandshakeMethod(), responseObserver); + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getDoHandshakeMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service HandshakerService. + */ + public static abstract class HandshakerServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getDoHandshakeMethod(), - asyncBidiStreamingCall( - new MethodHandlers< - io.grpc.alts.internal.HandshakerReq, - io.grpc.alts.internal.HandshakerResp>( - this, METHODID_DO_HANDSHAKE))) - .build(); + return HandshakerServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service HandshakerService. */ - public static final class HandshakerServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class HandshakerServiceStub + extends io.grpc.stub.AbstractAsyncStub { private HandshakerServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -160,14 +161,50 @@ protected HandshakerServiceStub build( */ public io.grpc.stub.StreamObserver doHandshake( io.grpc.stub.StreamObserver responseObserver) { - return asyncBidiStreamingCall( + return io.grpc.stub.ClientCalls.asyncBidiStreamingCall( getChannel().newCall(getDoHandshakeMethod(), getCallOptions()), responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service HandshakerService. + */ + public static final class HandshakerServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private HandshakerServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected HandshakerServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new HandshakerServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * Handshaker service accepts a stream of handshaker request, returning a
+     * stream of handshaker response. Client is expected to send exactly one
+     * message with either client_start or server_start followed by one or more
+     * messages with next. Each time client sends a request, the handshaker
+     * service expects to respond. Client does not have to wait for service's
+     * response before sending next request.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + doHandshake() { + return io.grpc.stub.ClientCalls.blockingBidiStreamingCall( + getChannel(), getDoHandshakeMethod(), getCallOptions()); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service HandshakerService. */ - public static final class HandshakerServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class HandshakerServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private HandshakerServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -181,8 +218,10 @@ protected HandshakerServiceBlockingStub build( } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service HandshakerService. */ - public static final class HandshakerServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class HandshakerServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private HandshakerServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -202,10 +241,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final HandshakerServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(HandshakerServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -233,6 +272,18 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getDoHandshakeMethod(), + io.grpc.stub.ServerCalls.asyncBidiStreamingCall( + new MethodHandlers< + io.grpc.alts.internal.HandshakerReq, + io.grpc.alts.internal.HandshakerResp>( + service, METHODID_DO_HANDSHAKE))) + .build(); + } + private static abstract class HandshakerServiceBaseDescriptorSupplier implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier { HandshakerServiceBaseDescriptorSupplier() {} @@ -256,9 +307,9 @@ private static final class HandshakerServiceFileDescriptorSupplier private static final class HandshakerServiceMethodDescriptorSupplier extends HandshakerServiceBaseDescriptorSupplier implements io.grpc.protobuf.ProtoMethodDescriptorSupplier { - private final String methodName; + private final java.lang.String methodName; - HandshakerServiceMethodDescriptorSupplier(String methodName) { + HandshakerServiceMethodDescriptorSupplier(java.lang.String methodName) { this.methodName = methodName; } diff --git a/alts/src/main/java/io/grpc/alts/AltsChannelBuilder.java b/alts/src/main/java/io/grpc/alts/AltsChannelBuilder.java index 5a774daaa6b..ca33f8b00b9 100644 --- a/alts/src/main/java/io/grpc/alts/AltsChannelBuilder.java +++ b/alts/src/main/java/io/grpc/alts/AltsChannelBuilder.java @@ -17,45 +17,28 @@ package io.grpc.alts; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import io.grpc.CallOptions; -import io.grpc.Channel; -import io.grpc.ClientCall; -import io.grpc.ClientInterceptor; import io.grpc.ExperimentalApi; -import io.grpc.ForwardingChannelBuilder; +import io.grpc.ForwardingChannelBuilder2; import io.grpc.ManagedChannel; import io.grpc.ManagedChannelBuilder; -import io.grpc.MethodDescriptor; -import io.grpc.Status; -import io.grpc.alts.internal.AltsProtocolNegotiator.ClientAltsProtocolNegotiatorFactory; import io.grpc.internal.GrpcUtil; -import io.grpc.internal.ObjectPool; -import io.grpc.internal.SharedResourcePool; import io.grpc.netty.InternalNettyChannelBuilder; import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator; import io.grpc.netty.NettyChannelBuilder; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.annotation.Nullable; /** * ALTS version of {@code ManagedChannelBuilder}. This class sets up a secure and authenticated - * commmunication between two cloud VMs using ALTS. + * communication between two cloud VMs using ALTS. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151") -public final class AltsChannelBuilder extends ForwardingChannelBuilder { - - private static final Logger logger = Logger.getLogger(AltsChannelBuilder.class.getName()); +public final class AltsChannelBuilder extends ForwardingChannelBuilder2 { private final NettyChannelBuilder delegate; - private final ImmutableList.Builder targetServiceAccountsBuilder = - ImmutableList.builder(); - private ObjectPool handshakerChannelPool = - SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL); - private boolean enableUntrustedAlts; + private final AltsChannelCredentials.Builder credentialsBuilder = + new AltsChannelCredentials.Builder(); /** "Overrides" the static method in {@link ManagedChannelBuilder}. */ - public static final AltsChannelBuilder forTarget(String target) { + public static AltsChannelBuilder forTarget(String target) { return new AltsChannelBuilder(target); } @@ -73,7 +56,7 @@ private AltsChannelBuilder(String target) { * service account in the handshaker result. Otherwise, the handshake fails. */ public AltsChannelBuilder addTargetServiceAccount(String targetServiceAccount) { - targetServiceAccountsBuilder.add(targetServiceAccount); + credentialsBuilder.addTargetServiceAccount(targetServiceAccount); return this; } @@ -82,17 +65,13 @@ public AltsChannelBuilder addTargetServiceAccount(String targetServiceAccount) { * is running on Google Cloud Platform. */ public AltsChannelBuilder enableUntrustedAltsForTesting() { - enableUntrustedAlts = true; + credentialsBuilder.enableUntrustedAltsForTesting(); return this; } /** Sets a new handshaker service address for testing. */ public AltsChannelBuilder setHandshakerAddressForTesting(String handshakerAddress) { - // Instead of using the default shared channel to the handshaker service, create a separate - // resource to the test address. - handshakerChannelPool = - SharedResourcePool.forResource( - HandshakerServiceChannel.getHandshakerChannelForTesting(handshakerAddress)); + credentialsBuilder.setHandshakerAddressForTesting(handshakerAddress); return this; } @@ -103,22 +82,9 @@ protected NettyChannelBuilder delegate() { @Override public ManagedChannel build() { - if (!CheckGcpEnvironment.isOnGcp()) { - if (enableUntrustedAlts) { - logger.log( - Level.WARNING, - "Untrusted ALTS mode is enabled and we cannot guarantee the trustworthiness of the " - + "ALTS handshaker service"); - } else { - Status status = - Status.INTERNAL.withDescription("ALTS is only allowed to run on Google Cloud Platform"); - delegate().intercept(new FailingClientInterceptor(status)); - } - } InternalNettyChannelBuilder.setProtocolNegotiatorFactory( delegate(), - new ClientAltsProtocolNegotiatorFactory( - targetServiceAccountsBuilder.build(), handshakerChannelPool)); + credentialsBuilder.buildProtocolNegotiatorFactory()); return delegate().build(); } @@ -126,24 +92,6 @@ public ManagedChannel build() { @VisibleForTesting @Nullable ProtocolNegotiator getProtocolNegotiatorForTest() { - return new ClientAltsProtocolNegotiatorFactory( - targetServiceAccountsBuilder.build(), handshakerChannelPool) - .buildProtocolNegotiator(); - } - - /** An implementation of {@link ClientInterceptor} that fails each call. */ - static final class FailingClientInterceptor implements ClientInterceptor { - - private final Status status; - - public FailingClientInterceptor(Status status) { - this.status = status; - } - - @Override - public ClientCall interceptCall( - MethodDescriptor method, CallOptions callOptions, Channel next) { - return new FailingClientCall<>(status); - } + return credentialsBuilder.buildProtocolNegotiatorFactory().newNegotiator(); } } diff --git a/alts/src/main/java/io/grpc/alts/AltsChannelCredentials.java b/alts/src/main/java/io/grpc/alts/AltsChannelCredentials.java new file mode 100644 index 00000000000..e12344f73d7 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/AltsChannelCredentials.java @@ -0,0 +1,159 @@ +/* + * Copyright 2020 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import com.google.common.collect.ImmutableList; +import io.grpc.Channel; +import io.grpc.ChannelCredentials; +import io.grpc.ExperimentalApi; +import io.grpc.Status; +import io.grpc.alts.internal.AltsProtocolNegotiator.ClientAltsProtocolNegotiatorFactory; +import io.grpc.internal.ObjectPool; +import io.grpc.internal.SharedResourcePool; +import io.grpc.netty.GrpcHttp2ConnectionHandler; +import io.grpc.netty.InternalNettyChannelCredentials; +import io.grpc.netty.InternalProtocolNegotiator; +import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerAdapter; +import io.netty.channel.ChannelHandlerContext; +import io.netty.util.AsciiString; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Provides secure and authenticated communication between two cloud VMs using ALTS. + */ +@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151") +public final class AltsChannelCredentials { + private static final Logger logger = Logger.getLogger(AltsChannelCredentials.class.getName()); + + private AltsChannelCredentials() {} + + public static ChannelCredentials create() { + return newBuilder().build(); + } + + public static Builder newBuilder() { + return new Builder(); + } + + @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151") + public static final class Builder { + private final ImmutableList.Builder targetServiceAccountsBuilder = + ImmutableList.builder(); + private ObjectPool handshakerChannelPool = + SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL); + private boolean enableUntrustedAlts; + + /** + * Adds an expected target service accounts. One of the added service accounts should match peer + * service account in the handshaker result. Otherwise, the handshake fails. + */ + public Builder addTargetServiceAccount(String targetServiceAccount) { + targetServiceAccountsBuilder.add(targetServiceAccount); + return this; + } + + /** + * Enables untrusted ALTS for testing. If this function is called, we will not check whether + * ALTS is running on Google Cloud Platform. + */ + public Builder enableUntrustedAltsForTesting() { + enableUntrustedAlts = true; + return this; + } + + /** Sets a new handshaker service address for testing. */ + public Builder setHandshakerAddressForTesting(String handshakerAddress) { + // Instead of using the default shared channel to the handshaker service, create a separate + // resource to the test address. + handshakerChannelPool = + SharedResourcePool.forResource( + HandshakerServiceChannel.getHandshakerChannelForTesting(handshakerAddress)); + return this; + } + + public ChannelCredentials build() { + return InternalNettyChannelCredentials.create(buildProtocolNegotiatorFactory()); + } + + InternalProtocolNegotiator.ClientFactory buildProtocolNegotiatorFactory() { + if (!InternalCheckGcpEnvironment.isOnGcp()) { + if (enableUntrustedAlts) { + logger.log( + Level.WARNING, + "Untrusted ALTS mode is enabled and we cannot guarantee the trustworthiness of the " + + "ALTS handshaker service"); + } else { + Status status = Status.INTERNAL.withDescription( + "ALTS is only allowed to run on Google Cloud Platform"); + return new FailingProtocolNegotiatorFactory(status); + } + } + + return new ClientAltsProtocolNegotiatorFactory( + targetServiceAccountsBuilder.build(), handshakerChannelPool); + } + } + + private static final class FailingProtocolNegotiatorFactory + implements InternalProtocolNegotiator.ClientFactory { + private final Status status; + + public FailingProtocolNegotiatorFactory(Status status) { + this.status = status; + } + + @Override + public ProtocolNegotiator newNegotiator() { + return new FailingProtocolNegotiator(status); + } + + @Override + public int getDefaultPort() { + return 443; + } + } + + private static final AsciiString SCHEME = AsciiString.of("https"); + + static final class FailingProtocolNegotiator implements ProtocolNegotiator { + private final Status status; + + public FailingProtocolNegotiator(Status status) { + this.status = status; + } + + @Override + public AsciiString scheme() { + return SCHEME; + } + + @Override + public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) { + return new ChannelHandlerAdapter() { + @Override public void handlerAdded(ChannelHandlerContext ctx) { + ctx.fireExceptionCaught(status.asRuntimeException()); + } + }; + } + + @Override + public void close() {} + } +} diff --git a/alts/src/main/java/io/grpc/alts/AltsContext.java b/alts/src/main/java/io/grpc/alts/AltsContext.java new file mode 100644 index 00000000000..7680de4160e --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/AltsContext.java @@ -0,0 +1,91 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import io.grpc.ExperimentalApi; +import io.grpc.alts.internal.AltsInternalContext; +import io.grpc.alts.internal.HandshakerResult; +import io.grpc.alts.internal.Identity; + +/** {@code AltsContext} contains security-related information on the ALTS channel. */ +@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7864") +public final class AltsContext { + + private final AltsInternalContext wrapped; + + AltsContext(AltsInternalContext wrapped) { + this.wrapped = wrapped; + } + + /** + * Creates an {@code AltsContext} for testing purposes. + * @param peerServiceAccount the peer service account of the to be created {@code AltsContext} + * @param localServiceAccount the local service account of the to be created {@code AltsContext} + * @return the created {@code AltsContext} + */ + public static AltsContext createTestInstance(String peerServiceAccount, + String localServiceAccount) { + return new AltsContext(new AltsInternalContext(HandshakerResult.newBuilder() + .setPeerIdentity(Identity.newBuilder().setServiceAccount(peerServiceAccount).build()) + .setLocalIdentity(Identity.newBuilder().setServiceAccount(localServiceAccount).build()) + .build())); + } + + /** + * Get security level. + * + * @return the context's security level. + */ + public SecurityLevel getSecurityLevel() { + switch (wrapped.getSecurityLevel()) { + case SECURITY_NONE: + return SecurityLevel.SECURITY_NONE; + case INTEGRITY_ONLY: + return SecurityLevel.INTEGRITY_ONLY; + case INTEGRITY_AND_PRIVACY: + return SecurityLevel.INTEGRITY_AND_PRIVACY; + default: + return SecurityLevel.UNKNOWN; + } + } + + /** + * Get peer service account. + * + * @return the context's peer service account. + */ + public String getPeerServiceAccount() { + return wrapped.getPeerServiceAccount(); + } + + /** + * Get local service account. + * + * @return the context's local service account. + */ + public String getLocalServiceAccount() { + return wrapped.getLocalServiceAccount(); + } + + /** SecurityLevel of the ALTS channel. */ + public enum SecurityLevel { + UNKNOWN, + SECURITY_NONE, + INTEGRITY_ONLY, + INTEGRITY_AND_PRIVACY, + } +} diff --git a/alts/src/main/java/io/grpc/alts/AltsContextUtil.java b/alts/src/main/java/io/grpc/alts/AltsContextUtil.java new file mode 100644 index 00000000000..f45179bbd91 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/AltsContextUtil.java @@ -0,0 +1,99 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import io.grpc.Attributes; +import io.grpc.ClientCall; +import io.grpc.ExperimentalApi; +import io.grpc.ServerCall; +import io.grpc.alts.internal.AltsInternalContext; +import io.grpc.alts.internal.AltsProtocolNegotiator; + +/** Utility class for {@link AltsContext}. */ +@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7864") +public final class AltsContextUtil { + + private AltsContextUtil() {} + + /** + * Creates an {@link AltsContext} from ALTS context information in the {@link ServerCall}. + * + * @param call the {@link ServerCall} containing the ALTS information + * @return the created {@link AltsContext} + * @throws IllegalArgumentException if the {@link ServerCall} has no ALTS information. + */ + public static AltsContext createFrom(ServerCall call) { + return createFrom(call.getAttributes()); + } + + /** + * Creates an {@link AltsContext} from ALTS context information in the {@link ClientCall}. + * + * @param call the {@link ClientCall} containing the ALTS information + * @return the created {@link AltsContext} + * @throws IllegalArgumentException if the {@link ClientCall} has no ALTS information. + */ + public static AltsContext createFrom(ClientCall call) { + return createFrom(call.getAttributes()); + } + + /** + * Creates an {@link AltsContext} from ALTS context information in the {@link Attributes}. + * + * @param attributes the {@link Attributes} containing the ALTS information + * @return the created {@link AltsContext} + * @throws IllegalArgumentException if the {@link Attributes} has no ALTS information. + */ + public static AltsContext createFrom(Attributes attributes) { + Object authContext = attributes.get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY); + if (!(authContext instanceof AltsInternalContext)) { + throw new IllegalArgumentException("No ALTS context information found"); + } + return new AltsContext((AltsInternalContext) authContext); + } + + /** + * Checks if the {@link ServerCall} contains ALTS information. + * + * @param call the {@link ServerCall} to check + * @return true, if the {@link ServerCall} contains ALTS information and false otherwise. + */ + public static boolean check(ServerCall call) { + return check(call.getAttributes()); + } + + /** + * Checks if the {@link ClientCall} contains ALTS information. + * + * @param call the {@link ClientCall} to check + * @return true, if the {@link ClientCall} contains ALTS information and false otherwise. + */ + public static boolean check(ClientCall call) { + return check(call.getAttributes()); + } + + /** + * Checks if the {@link Attributes} contains ALTS information. + * + * @param attributes the {@link Attributes} to check + * @return true, if the {@link Attributes} contains ALTS information and false otherwise. + */ + public static boolean check(Attributes attributes) { + Object authContext = attributes.get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY); + return authContext instanceof AltsInternalContext; + } +} diff --git a/alts/src/main/java/io/grpc/alts/AltsServerBuilder.java b/alts/src/main/java/io/grpc/alts/AltsServerBuilder.java index fdda8caac6e..e307fd1c63a 100644 --- a/alts/src/main/java/io/grpc/alts/AltsServerBuilder.java +++ b/alts/src/main/java/io/grpc/alts/AltsServerBuilder.java @@ -17,45 +17,32 @@ package io.grpc.alts; import io.grpc.BindableService; -import io.grpc.Channel; import io.grpc.CompressorRegistry; import io.grpc.DecompressorRegistry; import io.grpc.ExperimentalApi; +import io.grpc.ForwardingServerBuilder; import io.grpc.HandlerRegistry; -import io.grpc.Metadata; import io.grpc.Server; import io.grpc.ServerBuilder; -import io.grpc.ServerCall; -import io.grpc.ServerCall.Listener; -import io.grpc.ServerCallHandler; import io.grpc.ServerInterceptor; import io.grpc.ServerServiceDefinition; -import io.grpc.ServerStreamTracer.Factory; +import io.grpc.ServerStreamTracer; import io.grpc.ServerTransportFilter; -import io.grpc.Status; -import io.grpc.alts.internal.AltsProtocolNegotiator; -import io.grpc.internal.ObjectPool; -import io.grpc.internal.SharedResourcePool; import io.grpc.netty.NettyServerBuilder; import java.io.File; import java.net.InetSocketAddress; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; /** * gRPC secure server builder used for ALTS. This class adds on the necessary ALTS support to create * a production server on Google Cloud Platform. */ @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151") -public final class AltsServerBuilder extends ServerBuilder { - - private static final Logger logger = Logger.getLogger(AltsServerBuilder.class.getName()); +public final class AltsServerBuilder extends ForwardingServerBuilder { private final NettyServerBuilder delegate; - private ObjectPool handshakerChannelPool = - SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL); - private boolean enableUntrustedAlts; + private final AltsServerCredentials.Builder credentialsBuilder = + new AltsServerCredentials.Builder(); private AltsServerBuilder(NettyServerBuilder nettyDelegate) { this.delegate = nettyDelegate; @@ -72,20 +59,21 @@ public static AltsServerBuilder forPort(int port) { * is running on Google Cloud Platform. */ public AltsServerBuilder enableUntrustedAltsForTesting() { - enableUntrustedAlts = true; + credentialsBuilder.enableUntrustedAltsForTesting(); return this; } /** Sets a new handshaker service address for testing. */ public AltsServerBuilder setHandshakerAddressForTesting(String handshakerAddress) { - // Instead of using the default shared channel to the handshaker service, create a separate - // resource to the test address. - handshakerChannelPool = - SharedResourcePool.forResource( - HandshakerServiceChannel.getHandshakerChannelForTesting(handshakerAddress)); + credentialsBuilder.setHandshakerAddressForTesting(handshakerAddress); return this; } + @Override + protected ServerBuilder delegate() { + return delegate; + } + /** {@inheritDoc} */ @Override public AltsServerBuilder handshakeTimeout(long timeout, TimeUnit unit) { @@ -102,7 +90,7 @@ public AltsServerBuilder directExecutor() { /** {@inheritDoc} */ @Override - public AltsServerBuilder addStreamTracerFactory(Factory factory) { + public AltsServerBuilder addStreamTracerFactory(ServerStreamTracer.Factory factory) { delegate.addStreamTracerFactory(factory); return this; } @@ -172,40 +160,7 @@ public AltsServerBuilder intercept(ServerInterceptor interceptor) { /** {@inheritDoc} */ @Override public Server build() { - if (!CheckGcpEnvironment.isOnGcp()) { - if (enableUntrustedAlts) { - logger.log( - Level.WARNING, - "Untrusted ALTS mode is enabled and we cannot guarantee the trustworthiness of the " - + "ALTS handshaker service"); - } else { - Status status = - Status.INTERNAL.withDescription("ALTS is only allowed to run on Google Cloud Platform"); - delegate.intercept(new FailingServerInterceptor(status)); - } - } - - delegate.protocolNegotiator( - AltsProtocolNegotiator.serverAltsProtocolNegotiator(handshakerChannelPool)); + delegate.protocolNegotiator(credentialsBuilder.buildProtocolNegotiator()); return delegate.build(); } - - /** An implementation of {@link ServerInterceptor} that fails each call. */ - static final class FailingServerInterceptor implements ServerInterceptor { - - private final Status status; - - public FailingServerInterceptor(Status status) { - this.status = status; - } - - @Override - public Listener interceptCall( - ServerCall serverCall, - Metadata metadata, - ServerCallHandler nextHandler) { - serverCall.close(status, new Metadata()); - return new Listener() {}; - } - } } diff --git a/alts/src/main/java/io/grpc/alts/AltsServerCredentials.java b/alts/src/main/java/io/grpc/alts/AltsServerCredentials.java new file mode 100644 index 00000000000..36dc9f6a4ae --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/AltsServerCredentials.java @@ -0,0 +1,95 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import io.grpc.Channel; +import io.grpc.ExperimentalApi; +import io.grpc.ServerCredentials; +import io.grpc.Status; +import io.grpc.alts.internal.AltsProtocolNegotiator; +import io.grpc.internal.ObjectPool; +import io.grpc.internal.SharedResourcePool; +import io.grpc.netty.InternalNettyServerCredentials; +import io.grpc.netty.InternalProtocolNegotiator; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * gRPC secure server builder used for ALTS. This class adds on the necessary ALTS support to create + * a production server on Google Cloud Platform. + */ +@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151") +public final class AltsServerCredentials { + private static final Logger logger = Logger.getLogger(AltsServerCredentials.class.getName()); + + private AltsServerCredentials() {} + + public static ServerCredentials create() { + return newBuilder().build(); + } + + public static Builder newBuilder() { + return new Builder(); + } + + @ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151") + public static final class Builder { + private ObjectPool handshakerChannelPool = + SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL); + private boolean enableUntrustedAlts; + + /** + * Enables untrusted ALTS for testing. If this function is called, we will not check whether + * ALTS is running on Google Cloud Platform. + */ + public Builder enableUntrustedAltsForTesting() { + enableUntrustedAlts = true; + return this; + } + + /** Sets a new handshaker service address for testing. */ + public Builder setHandshakerAddressForTesting(String handshakerAddress) { + // Instead of using the default shared channel to the handshaker service, create a separate + // resource to the test address. + handshakerChannelPool = + SharedResourcePool.forResource( + HandshakerServiceChannel.getHandshakerChannelForTesting(handshakerAddress)); + return this; + } + + public ServerCredentials build() { + return InternalNettyServerCredentials.create(buildProtocolNegotiator()); + } + + InternalProtocolNegotiator.ProtocolNegotiator buildProtocolNegotiator() { + if (!InternalCheckGcpEnvironment.isOnGcp()) { + if (enableUntrustedAlts) { + logger.log( + Level.WARNING, + "Untrusted ALTS mode is enabled and we cannot guarantee the trustworthiness of the " + + "ALTS handshaker service"); + } else { + Status status = Status.INTERNAL.withDescription( + "ALTS is only allowed to run on Google Cloud Platform"); + return new AltsChannelCredentials.FailingProtocolNegotiator(status); + } + } + + return AltsProtocolNegotiator.serverAltsProtocolNegotiator(handshakerChannelPool); + } + } +} diff --git a/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java b/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java index 72341afa552..53e45105d9b 100644 --- a/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java +++ b/alts/src/main/java/io/grpc/alts/AuthorizationUtil.java @@ -18,7 +18,7 @@ import io.grpc.ServerCall; import io.grpc.Status; -import io.grpc.alts.internal.AltsAuthContext; +import io.grpc.alts.internal.AltsInternalContext; import io.grpc.alts.internal.AltsProtocolNegotiator; import java.util.Collection; @@ -34,8 +34,8 @@ private AuthorizationUtil() {} */ public static Status clientAuthorizationCheck( ServerCall call, Collection expectedServiceAccounts) { - AltsAuthContext altsContext = - (AltsAuthContext) call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY); + AltsInternalContext altsContext = + (AltsInternalContext) call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY); if (altsContext == null) { return Status.PERMISSION_DENIED.withDescription("Peer ALTS AuthContext not found"); } diff --git a/alts/src/main/java/io/grpc/alts/CallCredentialsInterceptor.java b/alts/src/main/java/io/grpc/alts/CallCredentialsInterceptor.java deleted file mode 100644 index b1ab948f765..00000000000 --- a/alts/src/main/java/io/grpc/alts/CallCredentialsInterceptor.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2019 The gRPC Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.grpc.alts; - -import io.grpc.CallCredentials; -import io.grpc.CallOptions; -import io.grpc.Channel; -import io.grpc.ClientCall; -import io.grpc.ClientInterceptor; -import io.grpc.MethodDescriptor; -import io.grpc.Status; -import javax.annotation.Nullable; - -/** An implementation of {@link ClientInterceptor} that adds call credentials on each call. */ -final class CallCredentialsInterceptor implements ClientInterceptor { - - @Nullable private final CallCredentials credentials; - private final Status status; - - public CallCredentialsInterceptor(@Nullable CallCredentials credentials, Status status) { - this.credentials = credentials; - this.status = status; - } - - @Override - public ClientCall interceptCall( - MethodDescriptor method, CallOptions callOptions, Channel next) { - if (!status.isOk()) { - return new FailingClientCall<>(status); - } - return next.newCall(method, callOptions.withCallCredentials(credentials)); - } -} diff --git a/alts/src/main/java/io/grpc/alts/CheckGcpEnvironment.java b/alts/src/main/java/io/grpc/alts/CheckGcpEnvironment.java deleted file mode 100644 index 1533415f6b0..00000000000 --- a/alts/src/main/java/io/grpc/alts/CheckGcpEnvironment.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2018 The gRPC Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.grpc.alts; - -import static java.nio.charset.StandardCharsets.UTF_8; - -import com.google.common.annotations.VisibleForTesting; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.logging.Level; -import java.util.logging.Logger; -import org.apache.commons.lang3.SystemUtils; - -/** Class for checking if the system is running on Google Cloud Platform (GCP). */ -final class CheckGcpEnvironment { - - private static final Logger logger = Logger.getLogger(CheckGcpEnvironment.class.getName()); - private static final String DMI_PRODUCT_NAME = "/sys/class/dmi/id/product_name"; - private static final String WINDOWS_COMMAND = "powershell.exe"; - private static Boolean cachedResult = null; - - // Construct me not! - private CheckGcpEnvironment() {} - - static synchronized boolean isOnGcp() { - if (cachedResult == null) { - cachedResult = isRunningOnGcp(); - } - return cachedResult; - } - - @VisibleForTesting - static boolean checkProductNameOnLinux(BufferedReader reader) throws IOException { - String name = reader.readLine().trim(); - return name.equals("Google") || name.equals("Google Compute Engine"); - } - - @VisibleForTesting - static boolean checkBiosDataOnWindows(BufferedReader reader) throws IOException { - String line; - while ((line = reader.readLine()) != null) { - if (line.startsWith("Manufacturer")) { - String name = line.substring(line.indexOf(':') + 1).trim(); - return name.equals("Google"); - } - } - return false; - } - - private static boolean isRunningOnGcp() { - try { - if (SystemUtils.IS_OS_LINUX) { - // Checks GCE residency on Linux platform. - return checkProductNameOnLinux(Files.newBufferedReader(Paths.get(DMI_PRODUCT_NAME), UTF_8)); - } else if (SystemUtils.IS_OS_WINDOWS) { - // Checks GCE residency on Windows platform. - Process p = - new ProcessBuilder() - .command(WINDOWS_COMMAND, "Get-WmiObject", "-Class", "Win32_BIOS") - .start(); - return checkBiosDataOnWindows( - new BufferedReader(new InputStreamReader(p.getInputStream(), UTF_8))); - } - } catch (IOException e) { - logger.log(Level.WARNING, "Fail to read platform information: ", e); - return false; - } - // Platforms other than Linux and Windows are not supported. - return false; - } -} diff --git a/alts/src/main/java/io/grpc/alts/ComputeEngineChannelBuilder.java b/alts/src/main/java/io/grpc/alts/ComputeEngineChannelBuilder.java index d9eaba8cc7c..b5ee6a8d362 100644 --- a/alts/src/main/java/io/grpc/alts/ComputeEngineChannelBuilder.java +++ b/alts/src/main/java/io/grpc/alts/ComputeEngineChannelBuilder.java @@ -16,23 +16,10 @@ package io.grpc.alts; -import com.google.auth.oauth2.ComputeEngineCredentials; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import io.grpc.CallCredentials; import io.grpc.ForwardingChannelBuilder; import io.grpc.ManagedChannelBuilder; -import io.grpc.Status; -import io.grpc.alts.internal.AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory; -import io.grpc.auth.MoreCallCredentials; import io.grpc.internal.GrpcUtil; -import io.grpc.internal.SharedResourcePool; -import io.grpc.netty.GrpcSslContexts; -import io.grpc.netty.InternalNettyChannelBuilder; -import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator; import io.grpc.netty.NettyChannelBuilder; -import io.netty.handler.ssl.SslContext; -import javax.net.ssl.SSLException; /** * {@code ManagedChannelBuilder} for Google Compute Engine. This class sets up a secure channel @@ -44,31 +31,11 @@ public final class ComputeEngineChannelBuilder private final NettyChannelBuilder delegate; private ComputeEngineChannelBuilder(String target) { - delegate = NettyChannelBuilder.forTarget(target); - SslContext sslContext; - try { - sslContext = GrpcSslContexts.forClient().build(); - } catch (SSLException e) { - throw new RuntimeException(e); - } - InternalNettyChannelBuilder.setProtocolNegotiatorFactory( - delegate(), - new GoogleDefaultProtocolNegotiatorFactory( - /* targetServiceAccounts= */ ImmutableList.of(), - SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL), - sslContext)); - CallCredentials credentials = MoreCallCredentials.from(ComputeEngineCredentials.create()); - Status status = Status.OK; - if (!CheckGcpEnvironment.isOnGcp()) { - status = - Status.INTERNAL.withDescription( - "Compute Engine Credentials can only be used on Google Cloud Platform"); - } - delegate().intercept(new CallCredentialsInterceptor(credentials, status)); + delegate = NettyChannelBuilder.forTarget(target, ComputeEngineChannelCredentials.create()); } /** "Overrides" the static method in {@link ManagedChannelBuilder}. */ - public static final ComputeEngineChannelBuilder forTarget(String target) { + public static ComputeEngineChannelBuilder forTarget(String target) { return new ComputeEngineChannelBuilder(target); } @@ -78,22 +45,8 @@ public static ComputeEngineChannelBuilder forAddress(String name, int port) { } @Override + @SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI. protected NettyChannelBuilder delegate() { return delegate; } - - @VisibleForTesting - ProtocolNegotiator getProtocolNegotiatorForTest() { - SslContext sslContext; - try { - sslContext = GrpcSslContexts.forClient().build(); - } catch (SSLException e) { - throw new RuntimeException(e); - } - return new GoogleDefaultProtocolNegotiatorFactory( - /* targetServiceAccounts= */ ImmutableList.of(), - SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL), - sslContext) - .buildProtocolNegotiator(); - } } diff --git a/alts/src/main/java/io/grpc/alts/ComputeEngineChannelCredentials.java b/alts/src/main/java/io/grpc/alts/ComputeEngineChannelCredentials.java new file mode 100644 index 00000000000..518642a675d --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/ComputeEngineChannelCredentials.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import com.google.auth.oauth2.ComputeEngineCredentials; +import com.google.common.collect.ImmutableList; +import io.grpc.CallCredentials; +import io.grpc.ChannelCredentials; +import io.grpc.CompositeChannelCredentials; +import io.grpc.Status; +import io.grpc.alts.internal.AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory; +import io.grpc.auth.MoreCallCredentials; +import io.grpc.internal.SharedResourcePool; +import io.grpc.netty.GrpcSslContexts; +import io.grpc.netty.InternalNettyChannelCredentials; +import io.grpc.netty.InternalProtocolNegotiator; +import io.netty.handler.ssl.SslContext; +import javax.net.ssl.SSLException; + +/** + * Credentials appropriate to contact Google services when running on Google Compute Engine. This + * class sets up a secure channel using ALTS if applicable and using TLS as fallback. It is a subset + * of the functionality provided by {@link GoogleDefaultChannelCredentials}. + */ +public final class ComputeEngineChannelCredentials { + private ComputeEngineChannelCredentials() {} + + /** + * Creates credentials for Google Compute Engine. This class sets up a secure channel using ALTS + * if applicable and using TLS as fallback. + */ + public static ChannelCredentials create() { + ChannelCredentials nettyCredentials = + InternalNettyChannelCredentials.create(createClientFactory()); + CallCredentials callCredentials; + if (InternalCheckGcpEnvironment.isOnGcp()) { + callCredentials = MoreCallCredentials.from(ComputeEngineCredentials.create()); + } else { + callCredentials = new FailingCallCredentials( + Status.INTERNAL.withDescription( + "Compute Engine Credentials can only be used on Google Cloud Platform")); + } + return CompositeChannelCredentials.create(nettyCredentials, callCredentials); + } + + private static InternalProtocolNegotiator.ClientFactory createClientFactory() { + SslContext sslContext; + try { + sslContext = GrpcSslContexts.forClient().build(); + } catch (SSLException e) { + throw new RuntimeException(e); + } + return new GoogleDefaultProtocolNegotiatorFactory( + /* targetServiceAccounts= */ ImmutableList.of(), + SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL), + sslContext); + } +} diff --git a/alts/src/main/java/io/grpc/alts/DualCallCredentials.java b/alts/src/main/java/io/grpc/alts/DualCallCredentials.java new file mode 100644 index 00000000000..08104712e65 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/DualCallCredentials.java @@ -0,0 +1,46 @@ +/* + * Copyright 2024 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import io.grpc.CallCredentials; +import java.util.concurrent.Executor; + +/** + * {@code CallCredentials} that will pick the right credentials based on whether the established + * connection is ALTS or TLS. + */ +final class DualCallCredentials extends CallCredentials { + private final CallCredentials tlsCallCredentials; + private final CallCredentials altsCallCredentials; + + public DualCallCredentials(CallCredentials tlsCallCreds, CallCredentials altsCallCreds) { + tlsCallCredentials = tlsCallCreds; + altsCallCredentials = altsCallCreds; + } + + @Override + public void applyRequestMetadata( + CallCredentials.RequestInfo requestInfo, + Executor appExecutor, + CallCredentials.MetadataApplier applier) { + if (AltsContextUtil.check(requestInfo.getTransportAttrs())) { + altsCallCredentials.applyRequestMetadata(requestInfo, appExecutor, applier); + } else { + tlsCallCredentials.applyRequestMetadata(requestInfo, appExecutor, applier); + } + } +} diff --git a/alts/src/main/java/io/grpc/alts/FailingCallCredentials.java b/alts/src/main/java/io/grpc/alts/FailingCallCredentials.java new file mode 100644 index 00000000000..3c59c5b6d09 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/FailingCallCredentials.java @@ -0,0 +1,41 @@ +/* + * Copyright 2020 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import com.google.common.base.Preconditions; +import io.grpc.CallCredentials; +import io.grpc.Status; +import java.util.concurrent.Executor; + +/** + * {@code CallCredentials} that always fail the RPC. + */ +final class FailingCallCredentials extends CallCredentials { + private final Status status; + + public FailingCallCredentials(Status status) { + this.status = Preconditions.checkNotNull(status, "status"); + } + + @Override + public void applyRequestMetadata( + CallCredentials.RequestInfo requestInfo, + Executor appExecutor, + CallCredentials.MetadataApplier applier) { + applier.fail(status); + } +} diff --git a/alts/src/main/java/io/grpc/alts/GoogleDefaultChannelBuilder.java b/alts/src/main/java/io/grpc/alts/GoogleDefaultChannelBuilder.java index 39bd4163726..c78b94417c4 100644 --- a/alts/src/main/java/io/grpc/alts/GoogleDefaultChannelBuilder.java +++ b/alts/src/main/java/io/grpc/alts/GoogleDefaultChannelBuilder.java @@ -16,25 +16,10 @@ package io.grpc.alts; -import com.google.auth.oauth2.GoogleCredentials; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import io.grpc.CallCredentials; import io.grpc.ForwardingChannelBuilder; import io.grpc.ManagedChannelBuilder; -import io.grpc.Status; -import io.grpc.alts.internal.AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory; -import io.grpc.auth.MoreCallCredentials; import io.grpc.internal.GrpcUtil; -import io.grpc.internal.SharedResourcePool; -import io.grpc.netty.GrpcSslContexts; -import io.grpc.netty.InternalNettyChannelBuilder; -import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator; import io.grpc.netty.NettyChannelBuilder; -import io.netty.handler.ssl.SslContext; -import java.io.IOException; -import javax.annotation.Nullable; -import javax.net.ssl.SSLException; /** * Google default version of {@code ManagedChannelBuilder}. This class sets up a secure channel @@ -46,34 +31,11 @@ public final class GoogleDefaultChannelBuilder private final NettyChannelBuilder delegate; private GoogleDefaultChannelBuilder(String target) { - delegate = NettyChannelBuilder.forTarget(target); - SslContext sslContext; - try { - sslContext = GrpcSslContexts.forClient().build(); - } catch (SSLException e) { - throw new RuntimeException(e); - } - InternalNettyChannelBuilder.setProtocolNegotiatorFactory( - delegate(), - new GoogleDefaultProtocolNegotiatorFactory( - /* targetServiceAccounts= */ ImmutableList.of(), - SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL), - sslContext)); - @Nullable CallCredentials credentials = null; - Status status = Status.OK; - try { - credentials = MoreCallCredentials.from(GoogleCredentials.getApplicationDefault()); - } catch (IOException e) { - status = - Status.UNAUTHENTICATED - .withDescription("Failed to get Google default credentials") - .withCause(e); - } - delegate().intercept(new CallCredentialsInterceptor(credentials, status)); + delegate = NettyChannelBuilder.forTarget(target, GoogleDefaultChannelCredentials.create()); } /** "Overrides" the static method in {@link ManagedChannelBuilder}. */ - public static final GoogleDefaultChannelBuilder forTarget(String target) { + public static GoogleDefaultChannelBuilder forTarget(String target) { return new GoogleDefaultChannelBuilder(target); } @@ -83,22 +45,8 @@ public static GoogleDefaultChannelBuilder forAddress(String name, int port) { } @Override + @SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI. protected NettyChannelBuilder delegate() { return delegate; } - - @VisibleForTesting - ProtocolNegotiator getProtocolNegotiatorForTest() { - SslContext sslContext; - try { - sslContext = GrpcSslContexts.forClient().build(); - } catch (SSLException e) { - throw new RuntimeException(e); - } - return new GoogleDefaultProtocolNegotiatorFactory( - /* targetServiceAccounts= */ ImmutableList.of(), - SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL), - sslContext) - .buildProtocolNegotiator(); - } } diff --git a/alts/src/main/java/io/grpc/alts/GoogleDefaultChannelCredentials.java b/alts/src/main/java/io/grpc/alts/GoogleDefaultChannelCredentials.java new file mode 100644 index 00000000000..1b5880120a4 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/GoogleDefaultChannelCredentials.java @@ -0,0 +1,118 @@ +/* + * Copyright 2020 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import com.google.auth.oauth2.GoogleCredentials; +import com.google.common.collect.ImmutableList; +import io.grpc.CallCredentials; +import io.grpc.ChannelCredentials; +import io.grpc.CompositeChannelCredentials; +import io.grpc.Status; +import io.grpc.alts.internal.AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory; +import io.grpc.auth.MoreCallCredentials; +import io.grpc.internal.SharedResourcePool; +import io.grpc.netty.GrpcSslContexts; +import io.grpc.netty.InternalNettyChannelCredentials; +import io.grpc.netty.InternalProtocolNegotiator; +import io.netty.handler.ssl.SslContext; +import java.io.IOException; +import javax.net.ssl.SSLException; + +/** + * Credentials appropriate to contact Google services. This class sets up a secure channel using + * ALTS if applicable and uses TLS as fallback. + */ +public final class GoogleDefaultChannelCredentials { + private GoogleDefaultChannelCredentials() {} + + /** + * Creates Google default credentials uses a secure channel with ALTS if applicable and uses TLS + * as fallback. + */ + public static ChannelCredentials create() { + return newBuilder().build(); + } + + /** + * Returns a new instance of {@link Builder}. + * + * @since 1.43.0 + */ + public static Builder newBuilder() { + return new Builder(); + } + + /** + * Builder for {@link GoogleDefaultChannelCredentials} instances. + * + * @since 1.43.0 + */ + public static final class Builder { + private CallCredentials callCredentials; + private CallCredentials altsCallCredentials; + + private Builder() {} + + /** Constructs GoogleDefaultChannelCredentials with a given call credential. */ + public Builder callCredentials(CallCredentials callCreds) { + callCredentials = callCreds; + return this; + } + + /** Constructs GoogleDefaultChannelCredentials with an ALTS-specific call credential. */ + public Builder altsCallCredentials(CallCredentials callCreds) { + altsCallCredentials = callCreds; + return this; + } + + /** Builds a GoogleDefaultChannelCredentials instance. */ + public ChannelCredentials build() { + ChannelCredentials nettyCredentials = + InternalNettyChannelCredentials.create(createClientFactory()); + CallCredentials tlsCallCreds = callCredentials; + if (tlsCallCreds == null) { + try { + tlsCallCreds = MoreCallCredentials.from(GoogleCredentials.getApplicationDefault()); + } catch (IOException e) { + tlsCallCreds = + new FailingCallCredentials( + Status.UNAUTHENTICATED + .withDescription("Failed to get Google default credentials") + .withCause(e)); + } + } + CallCredentials callCreds = + altsCallCredentials == null + ? tlsCallCreds + : new DualCallCredentials(tlsCallCreds, altsCallCredentials); + return CompositeChannelCredentials.create(nettyCredentials, callCreds); + } + + private static InternalProtocolNegotiator.ClientFactory createClientFactory() { + SslContext sslContext; + try { + sslContext = GrpcSslContexts.forClient().build(); + } catch (SSLException e) { + throw new RuntimeException(e); + } + return new GoogleDefaultProtocolNegotiatorFactory( + /* targetServiceAccounts= */ ImmutableList.of(), + SharedResourcePool.forResource(HandshakerServiceChannel.SHARED_HANDSHAKER_CHANNEL), + sslContext); + } + } +} diff --git a/alts/src/main/java/io/grpc/alts/HandshakerServiceChannel.java b/alts/src/main/java/io/grpc/alts/HandshakerServiceChannel.java index 169afe3078c..5e32d22d901 100644 --- a/alts/src/main/java/io/grpc/alts/HandshakerServiceChannel.java +++ b/alts/src/main/java/io/grpc/alts/HandshakerServiceChannel.java @@ -21,12 +21,14 @@ import io.grpc.ClientCall; import io.grpc.ManagedChannel; import io.grpc.MethodDescriptor; +import io.grpc.internal.GrpcUtil; import io.grpc.internal.SharedResourceHolder.Resource; import io.grpc.netty.NettyChannelBuilder; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.util.concurrent.DefaultThreadFactory; +import java.net.InetSocketAddress; import java.util.concurrent.TimeUnit; /** @@ -35,15 +37,37 @@ * application will have at most one connection to the handshaker service. */ final class HandshakerServiceChannel { + // Port 8080 is necessary for ALTS handshake. + private static final int ALTS_PORT = 8080; + private static final String DEFAULT_TARGET = "metadata.google.internal.:8080"; static final Resource SHARED_HANDSHAKER_CHANNEL = - new ChannelResource("metadata.google.internal.:8080"); - + new ChannelResource(getHandshakerTarget(System.getenv("GCE_METADATA_HOST"))); + + /** + * Returns handshaker target. When GCE_METADATA_HOST is provided, it might contain port which we + * will discard and use ALTS_PORT instead. + */ + static String getHandshakerTarget(String envValue) { + if (envValue == null || envValue.isEmpty()) { + return DEFAULT_TARGET; + } + String host = envValue; + int portIndex = host.lastIndexOf(':'); + if (portIndex != -1) { + host = host.substring(0, portIndex); // Discard port if specified + } + return host + ":" + ALTS_PORT; // Utilize ALTS port in all cases + } + /** Returns a resource of handshaker service channel for testing only. */ static Resource getHandshakerChannelForTesting(String handshakerAddress) { return new ChannelResource(handshakerAddress); } + private static final boolean EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS = + GrpcUtil.getFlag("GRPC_EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS", false); + private static class ChannelResource implements Resource { private final String target; @@ -56,12 +80,16 @@ public Channel create() { /* Use its own event loop thread pool to avoid blocking. */ EventLoopGroup eventGroup = new NioEventLoopGroup(1, new DefaultThreadFactory("handshaker pool", true)); - ManagedChannel channel = NettyChannelBuilder.forTarget(target) - .channelType(NioSocketChannel.class) + NettyChannelBuilder channelBuilder = + NettyChannelBuilder.forTarget(target) + .channelType(NioSocketChannel.class, InetSocketAddress.class) .directExecutor() .eventLoopGroup(eventGroup) - .usePlaintext() - .build(); + .usePlaintext(); + if (EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS) { + channelBuilder.keepAliveTime(10, TimeUnit.MINUTES).keepAliveTimeout(10, TimeUnit.SECONDS); + } + ManagedChannel channel = channelBuilder.build(); return new EventLoopHoldingChannel(channel, eventGroup); } diff --git a/alts/src/main/java/io/grpc/alts/InternalCheckGcpEnvironment.java b/alts/src/main/java/io/grpc/alts/InternalCheckGcpEnvironment.java new file mode 100644 index 00000000000..aae4a45d530 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/InternalCheckGcpEnvironment.java @@ -0,0 +1,97 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.common.annotations.VisibleForTesting; +import io.grpc.Internal; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Class for checking if the system is running on Google Cloud Platform (GCP). This is intended for + * usage internal to the gRPC team. If you *really* think you need to use this, contact the gRPC + * team first. + */ +@Internal +public final class InternalCheckGcpEnvironment { + + private static final Logger logger = + Logger.getLogger(InternalCheckGcpEnvironment.class.getName()); + private static final String WINDOWS_COMMAND = "powershell.exe"; + private static Boolean cachedResult = null; + + // Construct me not! + private InternalCheckGcpEnvironment() {} + + /** Returns {@code true} if currently running on Google Cloud Platform (GCP). */ + public static synchronized boolean isOnGcp() { + if (cachedResult == null) { + cachedResult = isRunningOnGcp(); + } + return cachedResult; + } + + @VisibleForTesting + static boolean checkProductNameOnLinux(BufferedReader reader) throws IOException { + String name = reader.readLine().trim(); + return name.equals("Google") || name.equals("Google Compute Engine"); + } + + @VisibleForTesting + static boolean checkBiosDataOnWindows(BufferedReader reader) throws IOException { + String line; + while ((line = reader.readLine()) != null) { + if (line.startsWith("Manufacturer")) { + String name = line.substring(line.indexOf(':') + 1).trim(); + return name.equals("Google"); + } + } + return false; + } + + private static boolean isRunningOnGcp() { + String osName = System.getProperty("os.name").toLowerCase(Locale.ENGLISH); + try { + if (osName.startsWith("linux")) { + // Checks GCE residency on Linux platform. + return checkProductNameOnLinux( + Files.newBufferedReader(Paths.get("/sys/class/dmi/id/product_name"), UTF_8)); + } else if (osName.startsWith("windows")) { + // Checks GCE residency on Windows platform. + Process p = + new ProcessBuilder() + .command(WINDOWS_COMMAND, "Get-WmiObject", "-Class", "Win32_BIOS") + .start(); + return checkBiosDataOnWindows( + new BufferedReader(new InputStreamReader(p.getInputStream(), UTF_8))); + } + } catch (IOException e) { + logger.log(Level.WARNING, "Fail to read platform information: ", e); + return false; + } + // Platforms other than Linux and Windows are not supported. + return false; + } +} diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsAuthContext.java b/alts/src/main/java/io/grpc/alts/internal/AltsAuthContext.java deleted file mode 100644 index b35d4faf98d..00000000000 --- a/alts/src/main/java/io/grpc/alts/internal/AltsAuthContext.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2018 The gRPC Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.grpc.alts.internal; - -import com.google.common.annotations.VisibleForTesting; -import java.util.Map; - -/** AltsAuthContext contains security-related context information about an ALTs connection. */ -public final class AltsAuthContext { - final AltsContext context; - - /** Create a new AltsAuthContext. */ - public AltsAuthContext(HandshakerResult result) { - context = - AltsContext.newBuilder() - .setApplicationProtocol(result.getApplicationProtocol()) - .setRecordProtocol(result.getRecordProtocol()) - // TODO: Set security level based on the handshaker result. - .setSecurityLevel(SecurityLevel.INTEGRITY_AND_PRIVACY) - .setPeerServiceAccount(result.getPeerIdentity().getServiceAccount()) - .setLocalServiceAccount(result.getLocalIdentity().getServiceAccount()) - .setPeerRpcVersions(result.getPeerRpcVersions()) - .putAllPeerAttributes(result.getPeerIdentity().getAttributes()) - .build(); - } - - @VisibleForTesting - public static AltsAuthContext getDefaultInstance() { - return new AltsAuthContext(HandshakerResult.newBuilder().build()); - } - - /** - * Get application protocol. - * - * @return the context's application protocol. - */ - public String getApplicationProtocol() { - return context.getApplicationProtocol(); - } - - /** - * Get negotiated record protocol. - * - * @return the context's negotiated record protocol. - */ - public String getRecordProtocol() { - return context.getRecordProtocol(); - } - - /** - * Get security level. - * - * @return the context's security level. - */ - public SecurityLevel getSecurityLevel() { - return context.getSecurityLevel(); - } - - /** - * Get peer service account. - * - * @return the context's peer service account. - */ - public String getPeerServiceAccount() { - return context.getPeerServiceAccount(); - } - - /** - * Get local service account. - * - * @return the context's local service account. - */ - public String getLocalServiceAccount() { - return context.getLocalServiceAccount(); - } - - /** - * Get peer RPC versions. - * - * @return the context's peer RPC versions. - */ - public RpcProtocolVersions getPeerRpcVersions() { - return context.getPeerRpcVersions(); - } - - /** - * Get peer attributes. - * - * @return the context's peer attributes. - */ - public Map getPeerAttributes() { - return context.getPeerAttributes(); - } -} diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsChannelCrypter.java b/alts/src/main/java/io/grpc/alts/internal/AltsChannelCrypter.java index e47433ff034..5e4c6fec301 100644 --- a/alts/src/main/java/io/grpc/alts/internal/AltsChannelCrypter.java +++ b/alts/src/main/java/io/grpc/alts/internal/AltsChannelCrypter.java @@ -17,10 +17,10 @@ package io.grpc.alts.internal; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Verify.verify; import com.google.common.annotations.VisibleForTesting; import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.util.List; @@ -56,72 +56,61 @@ static int getCounterLength() { @Override public void encrypt(ByteBuf outBuf, List plainBufs) throws GeneralSecurityException { - byte[] tempArr = new byte[outBuf.writableBytes()]; - - // Copy plaintext into tempArr. - { - ByteBuf tempBuf = Unpooled.wrappedBuffer(tempArr, 0, tempArr.length - TAG_LENGTH); - tempBuf.resetWriterIndex(); - for (ByteBuf plainBuf : plainBufs) { - tempBuf.writeBytes(plainBuf); - } + checkArgument(outBuf.nioBufferCount() == 1); + // Copy plaintext buffers into outBuf for in-place encryption on single direct buffer. + ByteBuf plainBuf = outBuf.slice(outBuf.writerIndex(), outBuf.writableBytes()); + plainBuf.writerIndex(0); + for (ByteBuf inBuf : plainBufs) { + plainBuf.writeBytes(inBuf); } - // Encrypt into tempArr. - { - ByteBuffer out = ByteBuffer.wrap(tempArr); - ByteBuffer plain = ByteBuffer.wrap(tempArr, 0, tempArr.length - TAG_LENGTH); - - byte[] counter = incrementOutCounter(); - aeadCrypter.encrypt(out, plain, counter); - } - outBuf.writeBytes(tempArr); + verify(outBuf.writableBytes() == plainBuf.readableBytes() + TAG_LENGTH); + ByteBuffer out = outBuf.internalNioBuffer(outBuf.writerIndex(), outBuf.writableBytes()); + ByteBuffer plain = out.duplicate(); + plain.limit(out.limit() - TAG_LENGTH); + + byte[] counter = incrementOutCounter(); + int outPosition = out.position(); + aeadCrypter.encrypt(out, plain, counter); + int bytesWritten = out.position() - outPosition; + outBuf.writerIndex(outBuf.writerIndex() + bytesWritten); + verify(!outBuf.isWritable()); } @Override - public void decrypt(ByteBuf outBuf, ByteBuf tagBuf, List ciphertextBufs) + public void decrypt(ByteBuf out, ByteBuf tag, List ciphertextBufs) throws GeneralSecurityException { - // There is enough space for the ciphertext including the tag in outBuf. - byte[] tempArr = new byte[outBuf.writableBytes()]; - - // Copy ciphertext and tag into tempArr. - { - ByteBuf tempBuf = Unpooled.wrappedBuffer(tempArr); - tempBuf.resetWriterIndex(); - for (ByteBuf ciphertextBuf : ciphertextBufs) { - tempBuf.writeBytes(ciphertextBuf); - } - tempBuf.writeBytes(tagBuf); - } - decryptInternal(outBuf, tempArr); - } + ByteBuf cipherTextAndTag = out.slice(out.writerIndex(), out.writableBytes()); + cipherTextAndTag.writerIndex(0); - @Override - public void decrypt( - ByteBuf outBuf, ByteBuf ciphertextAndTagDirect) throws GeneralSecurityException { - byte[] tempArr = new byte[ciphertextAndTagDirect.readableBytes()]; - - // Copy ciphertext and tag into tempArr. - { - ByteBuf tempBuf = Unpooled.wrappedBuffer(tempArr); - tempBuf.resetWriterIndex(); - tempBuf.writeBytes(ciphertextAndTagDirect); + for (ByteBuf inBuf : ciphertextBufs) { + cipherTextAndTag.writeBytes(inBuf); } + cipherTextAndTag.writeBytes(tag); - decryptInternal(outBuf, tempArr); + decrypt(out, cipherTextAndTag); } - private void decryptInternal(ByteBuf outBuf, byte[] tempArr) throws GeneralSecurityException { - // Perform in-place decryption on tempArr. - { - ByteBuffer ciphertextAndTag = ByteBuffer.wrap(tempArr); - ByteBuffer out = ByteBuffer.wrap(tempArr); - byte[] counter = incrementInCounter(); - aeadCrypter.decrypt(out, ciphertextAndTag, counter); - } - - outBuf.writeBytes(tempArr, 0, tempArr.length - TAG_LENGTH); + @Override + public void decrypt(ByteBuf out, ByteBuf ciphertextAndTag) throws GeneralSecurityException { + int bytesRead = ciphertextAndTag.readableBytes(); + checkArgument(bytesRead == out.writableBytes()); + + checkArgument(out.nioBufferCount() == 1); + ByteBuffer outBuffer = out.internalNioBuffer(out.writerIndex(), out.writableBytes()); + + checkArgument(ciphertextAndTag.nioBufferCount() == 1); + ByteBuffer ciphertextAndTagBuffer = + ciphertextAndTag.nioBuffer(ciphertextAndTag.readerIndex(), bytesRead); + + byte[] counter = incrementInCounter(); + int outPosition = outBuffer.position(); + aeadCrypter.decrypt(outBuffer, ciphertextAndTagBuffer, counter); + int bytesWritten = outBuffer.position() - outPosition; + out.writerIndex(out.writerIndex() + bytesWritten); + ciphertextAndTag.readerIndex(out.readerIndex() + bytesRead); + verify(out.writableBytes() == TAG_LENGTH); } @Override diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsFraming.java b/alts/src/main/java/io/grpc/alts/internal/AltsFraming.java index d243d95f4ab..2571f937225 100644 --- a/alts/src/main/java/io/grpc/alts/internal/AltsFraming.java +++ b/alts/src/main/java/io/grpc/alts/internal/AltsFraming.java @@ -17,6 +17,7 @@ package io.grpc.alts.internal; import com.google.common.base.Preconditions; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.GeneralSecurityException; @@ -63,10 +64,10 @@ static ByteBuffer toFrame(ByteBuffer input, int dataSize) throws GeneralSecurity } Producer producer = new Producer(); ByteBuffer inputAlias = input.duplicate(); - inputAlias.limit(input.position() + dataSize); + ((Buffer) inputAlias).limit(input.position() + dataSize); producer.readBytes(inputAlias); producer.flush(); - input.position(inputAlias.position()); + ((Buffer) input).position(inputAlias.position()); ByteBuffer output = producer.getRawFrame(); return output; } @@ -166,10 +167,10 @@ void flush() throws GeneralSecurityException { int frameLength = buffer.position() + getFrameSuffixLength(); // Set the limit and move to the start. - buffer.flip(); + ((Buffer) buffer).flip(); // Advance the limit to allow a crypto suffix. - buffer.limit(buffer.limit() + getFrameSuffixLength()); + ((Buffer) buffer).limit(buffer.limit() + getFrameSuffixLength()); // Write the data length and the message type. int dataLength = frameLength - FRAME_LENGTH_HEADER_SIZE; @@ -178,17 +179,17 @@ void flush() throws GeneralSecurityException { buffer.putInt(MESSAGE_TYPE); // Move the position back to 0, the frame is ready. - buffer.position(0); + ((Buffer) buffer).position(0); isComplete = true; } /** Resets the state, preparing to construct a new frame. Must be called between frames. */ private void reset() { - buffer.clear(); + ((Buffer) buffer).clear(); // Save some space for framing, we'll fill that in later. - buffer.position(getFramePrefixLength()); - buffer.limit(buffer.limit() - getFrameSuffixLength()); + ((Buffer) buffer).position(getFramePrefixLength()); + ((Buffer) buffer).limit(buffer.limit() - getFrameSuffixLength()); isComplete = false; } @@ -279,7 +280,7 @@ public boolean readBytes(ByteBuffer input) throws GeneralSecurityException { // internal buffer is large enough. if (buffer.position() == FRAME_LENGTH_HEADER_SIZE && input.hasRemaining()) { ByteBuffer bufferAlias = buffer.duplicate(); - bufferAlias.flip(); + ((Buffer) bufferAlias).flip(); bufferAlias.order(ByteOrder.LITTLE_ENDIAN); int dataLength = bufferAlias.getInt(); if (dataLength < FRAME_MESSAGE_TYPE_HEADER_SIZE || dataLength > MAX_DATA_LENGTH) { @@ -292,7 +293,7 @@ public boolean readBytes(ByteBuffer input) throws GeneralSecurityException { buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(dataLength); } - buffer.limit(frameLength); + ((Buffer) buffer).limit(frameLength); } // TODO: Similarly extract and check message type. @@ -300,7 +301,7 @@ public boolean readBytes(ByteBuffer input) throws GeneralSecurityException { // Read the remaining data into the internal buffer. copy(buffer, input); if (!buffer.hasRemaining()) { - buffer.flip(); + ((Buffer) buffer).flip(); isComplete = true; } return isComplete; @@ -323,7 +324,7 @@ public boolean isComplete() { /** Resets the state, preparing to parse a new frame. Must be called between frames. */ private void reset() { - buffer.clear(); + ((Buffer) buffer).clear(); isComplete = false; } @@ -356,9 +357,9 @@ private static void copy(ByteBuffer dst, ByteBuffer src) { } else { int count = Math.min(dst.remaining(), src.remaining()); ByteBuffer slice = src.slice(); - slice.limit(count); + ((Buffer) slice).limit(count); dst.put(slice); - src.position(src.position() + count); + ((Buffer) src).position(src.position() + count); } } } diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java b/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java index 083ad056789..9eb07f3e86d 100644 --- a/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java +++ b/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerClient.java @@ -20,18 +20,17 @@ import com.google.common.base.Preconditions; import com.google.common.base.Strings; import com.google.protobuf.ByteString; +import io.grpc.ChannelLogger; +import io.grpc.ChannelLogger.ChannelLogLevel; import io.grpc.Status; import io.grpc.alts.internal.HandshakerServiceGrpc.HandshakerServiceStub; import java.io.IOException; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; -import java.util.logging.Level; -import java.util.logging.Logger; /** An API for conducting handshakes via ALTS handshaker service. */ class AltsHandshakerClient { - private static final Logger logger = Logger.getLogger(AltsHandshakerClient.class.getName()); - private static final String APPLICATION_PROTOCOL = "grpc"; private static final String RECORD_PROTOCOL = "ALTSRP_GCM_AES128_REKEY"; private static final int KEY_LENGTH = AltsChannelCrypter.getKeyLength(); @@ -40,17 +39,22 @@ class AltsHandshakerClient { private final AltsHandshakerOptions handshakerOptions; private HandshakerResult result; private HandshakerStatus status; + private final ChannelLogger logger; /** Starts a new handshake interacting with the handshaker service. */ - AltsHandshakerClient(HandshakerServiceStub stub, AltsHandshakerOptions options) { + AltsHandshakerClient( + HandshakerServiceStub stub, AltsHandshakerOptions options, ChannelLogger logger) { handshakerStub = new AltsHandshakerStub(stub); handshakerOptions = options; + this.logger = logger; } @VisibleForTesting - AltsHandshakerClient(AltsHandshakerStub handshakerStub, AltsHandshakerOptions options) { + AltsHandshakerClient( + AltsHandshakerStub handshakerStub, AltsHandshakerOptions options, ChannelLogger logger) { this.handshakerStub = handshakerStub; handshakerOptions = options; + this.logger = logger; } static String getApplicationProtocol() { @@ -153,7 +157,7 @@ private void handleResponse(HandshakerResp resp) throws GeneralSecurityException } if (status.getCode() != Status.Code.OK.value()) { String error = "Handshaker service error: " + status.getDetails(); - logger.log(Level.INFO, error); + logger.log(ChannelLogLevel.DEBUG, error); close(); throw new GeneralSecurityException(error); } @@ -172,7 +176,9 @@ public ByteBuffer startClientHandshake() throws GeneralSecurityException { setStartClientFields(req); HandshakerResp resp; try { + logger.log(ChannelLogLevel.DEBUG, "Send ALTS handshake request to upstream"); resp = handshakerStub.send(req.build()); + logger.log(ChannelLogLevel.DEBUG, "Receive ALTS handshake response from upstream"); } catch (IOException | InterruptedException e) { throw new GeneralSecurityException(e); } @@ -199,7 +205,7 @@ public ByteBuffer startServerHandshake(ByteBuffer inBytes) throws GeneralSecurit throw new GeneralSecurityException(e); } handleResponse(resp); - inBytes.position(inBytes.position() + resp.getBytesConsumed()); + ((Buffer) inBytes).position(inBytes.position() + resp.getBytesConsumed()); return resp.getOutFrames().asReadOnlyByteBuffer(); } @@ -222,12 +228,14 @@ public ByteBuffer next(ByteBuffer inBytes) throws GeneralSecurityException { .build()); HandshakerResp resp; try { + logger.log(ChannelLogLevel.DEBUG, "Send ALTS handshake request to upstream"); resp = handshakerStub.send(req.build()); + logger.log(ChannelLogLevel.DEBUG, "Receive ALTS handshake response from upstream"); } catch (IOException | InterruptedException e) { throw new GeneralSecurityException(e); } handleResponse(resp); - inBytes.position(inBytes.position() + resp.getBytesConsumed()); + ((Buffer) inBytes).position(inBytes.position() + resp.getBytesConsumed()); return resp.getOutFrames().asReadOnlyByteBuffer(); } diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerStub.java b/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerStub.java index d8da4061cc5..6c2748dcc9c 100644 --- a/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerStub.java +++ b/alts/src/main/java/io/grpc/alts/internal/AltsHandshakerStub.java @@ -16,6 +16,8 @@ package io.grpc.alts.internal; +import static java.util.concurrent.TimeUnit.SECONDS; + import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import io.grpc.alts.internal.HandshakerServiceGrpc.HandshakerServiceStub; @@ -27,23 +29,27 @@ /** An interface to the ALTS handshaker service. */ class AltsHandshakerStub { private final StreamObserver reader = new Reader(); - private final StreamObserver writer; + private StreamObserver writer; + private final HandshakerServiceStub serviceStub; private final ArrayBlockingQueue> responseQueue = new ArrayBlockingQueue<>(1); - private final AtomicReference exceptionMessage = new AtomicReference<>(); + private final AtomicReference exceptionMessage = new AtomicReference<>(); + + private static final long HANDSHAKE_RPC_DEADLINE_SECS = 20; AltsHandshakerStub(HandshakerServiceStub serviceStub) { - this.writer = serviceStub.doHandshake(this.reader); + this.serviceStub = serviceStub; } @VisibleForTesting AltsHandshakerStub() { - writer = null; + serviceStub = null; } @VisibleForTesting AltsHandshakerStub(StreamObserver writer) { this.writer = writer; + serviceStub = null; } @VisibleForTesting @@ -53,28 +59,45 @@ StreamObserver getReaderForTest() { /** Send a handshaker request and return the handshaker response. */ public HandshakerResp send(HandshakerReq req) throws InterruptedException, IOException { + createWriterIfNull(); maybeThrowIoException(); if (!responseQueue.isEmpty()) { throw new IOException("Received an unexpected response."); } + writer.onNext(req); Optional result = responseQueue.take(); - if (!result.isPresent()) { - maybeThrowIoException(); + if (result.isPresent()) { + return result.get(); + } + + if (exceptionMessage.get() != null) { + throw new IOException(exceptionMessage.get().info, exceptionMessage.get().throwable); + } else { + throw new IOException("No handshaker response received"); + } + } + + /** Create a new writer if the writer is null. */ + private void createWriterIfNull() { + if (writer == null) { + writer = + serviceStub.withDeadlineAfter(HANDSHAKE_RPC_DEADLINE_SECS, SECONDS).doHandshake(reader); } - return result.get(); } /** Throw exception if there is an outstanding exception. */ private void maybeThrowIoException() throws IOException { if (exceptionMessage.get() != null) { - throw new IOException(exceptionMessage.get()); + throw new IOException(exceptionMessage.get().info, exceptionMessage.get().throwable); } } /** Close the connection. */ public void close() { - writer.onCompleted(); + if (writer != null) { + writer.onCompleted(); + } } private class Reader implements StreamObserver { @@ -85,7 +108,7 @@ public void onNext(HandshakerResp resp) { AltsHandshakerStub.this.responseQueue.add(Optional.of(resp)); } catch (IllegalStateException e) { AltsHandshakerStub.this.exceptionMessage.compareAndSet( - null, "Received an unexpected response."); + null, new ThrowableInfo(e, "Received an unexpected response.")); AltsHandshakerStub.this.close(); } } @@ -94,7 +117,7 @@ public void onNext(HandshakerResp resp) { @Override public void onError(Throwable t) { AltsHandshakerStub.this.exceptionMessage.compareAndSet( - null, "Received a terminating error: " + t.toString()); + null, new ThrowableInfo(t, "Received a terminating error.")); // Trigger the release of any blocked send. Optional result = Optional.absent(); AltsHandshakerStub.this.responseQueue.offer(result); @@ -103,10 +126,22 @@ public void onError(Throwable t) { /** Receive the closing message from the server. */ @Override public void onCompleted() { - AltsHandshakerStub.this.exceptionMessage.compareAndSet(null, "Response stream closed."); + AltsHandshakerStub.this.exceptionMessage.compareAndSet( + null, new ThrowableInfo(null, "Response stream closed.")); // Trigger the release of any blocked send. Optional result = Optional.absent(); AltsHandshakerStub.this.responseQueue.offer(result); } } + + private static class ThrowableInfo { + + private final Throwable throwable; + private final String info; + + private ThrowableInfo(Throwable throwable, String info) { + this.throwable = throwable; + this.info = info; + } + } } diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsInternalContext.java b/alts/src/main/java/io/grpc/alts/internal/AltsInternalContext.java new file mode 100644 index 00000000000..a70c67b2933 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/internal/AltsInternalContext.java @@ -0,0 +1,108 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts.internal; + +import com.google.common.annotations.VisibleForTesting; +import java.util.Map; + +/** AltsInternalContext contains security-related context information about an ALTs connection. */ +public final class AltsInternalContext { + final AltsContext context; + + /** Create a new AltsInternalContext. */ + public AltsInternalContext(HandshakerResult result) { + context = + AltsContext.newBuilder() + .setApplicationProtocol(result.getApplicationProtocol()) + .setRecordProtocol(result.getRecordProtocol()) + // TODO: Set security level based on the handshaker result. + .setSecurityLevel(SecurityLevel.INTEGRITY_AND_PRIVACY) + .setPeerServiceAccount(result.getPeerIdentity().getServiceAccount()) + .setLocalServiceAccount(result.getLocalIdentity().getServiceAccount()) + .setPeerRpcVersions(result.getPeerRpcVersions()) + .putAllPeerAttributes(result.getPeerIdentity().getAttributesMap()) + .build(); + } + + @VisibleForTesting + public static AltsInternalContext getDefaultInstance() { + return new AltsInternalContext(HandshakerResult.newBuilder().build()); + } + + /** + * Get application protocol. + * + * @return the context's application protocol. + */ + public String getApplicationProtocol() { + return context.getApplicationProtocol(); + } + + /** + * Get negotiated record protocol. + * + * @return the context's negotiated record protocol. + */ + public String getRecordProtocol() { + return context.getRecordProtocol(); + } + + /** + * Get security level. + * + * @return the context's security level. + */ + public SecurityLevel getSecurityLevel() { + return context.getSecurityLevel(); + } + + /** + * Get peer service account. + * + * @return the context's peer service account. + */ + public String getPeerServiceAccount() { + return context.getPeerServiceAccount(); + } + + /** + * Get local service account. + * + * @return the context's local service account. + */ + public String getLocalServiceAccount() { + return context.getLocalServiceAccount(); + } + + /** + * Get peer RPC versions. + * + * @return the context's peer RPC versions. + */ + public RpcProtocolVersions getPeerRpcVersions() { + return context.getPeerRpcVersions(); + } + + /** + * Get peer attributes. + * + * @return the context's peer attributes. + */ + public Map getPeerAttributes() { + return context.getPeerAttributesMap(); + } +} diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java index c5adbd73766..9c51cf6a053 100644 --- a/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java +++ b/alts/src/main/java/io/grpc/alts/internal/AltsProtocolNegotiator.java @@ -23,24 +23,26 @@ import com.google.protobuf.Any; import io.grpc.Attributes; import io.grpc.Channel; +import io.grpc.ChannelLogger; import io.grpc.Grpc; import io.grpc.InternalChannelz.OtherSecurity; import io.grpc.InternalChannelz.Security; import io.grpc.SecurityLevel; import io.grpc.Status; import io.grpc.alts.internal.RpcProtocolVersionsUtil.RpcVersionsCheckResult; -import io.grpc.grpclb.GrpclbConstants; import io.grpc.internal.ObjectPool; import io.grpc.netty.GrpcHttp2ConnectionHandler; -import io.grpc.netty.InternalNettyChannelBuilder; -import io.grpc.netty.InternalNettyChannelBuilder.ProtocolNegotiatorFactory; +import io.grpc.netty.InternalProtocolNegotiator; import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator; import io.grpc.netty.InternalProtocolNegotiators; import io.netty.channel.ChannelHandler; import io.netty.handler.ssl.SslContext; import io.netty.util.AsciiString; +import java.net.URI; +import java.net.URISyntaxException; import java.security.GeneralSecurityException; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Nullable; @@ -52,36 +54,54 @@ public final class AltsProtocolNegotiator { private static final Logger logger = Logger.getLogger(AltsProtocolNegotiator.class.getName()); + static final String ALTS_MAX_CONCURRENT_HANDSHAKES_ENV_VARIABLE = + "GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES"; + @VisibleForTesting static final int DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES = 32; + private static final AsyncSemaphore handshakeSemaphore = + new AsyncSemaphore(getAltsMaxConcurrentHandshakes()); + @Grpc.TransportAttr - public static final Attributes.Key TSI_PEER_KEY = Attributes.Key.create("TSI_PEER"); + public static final Attributes.Key TSI_PEER_KEY = + Attributes.Key.create("internal:TSI_PEER"); @Grpc.TransportAttr public static final Attributes.Key AUTH_CONTEXT_KEY = - Attributes.Key.create("AUTH_CONTEXT_KEY"); + Attributes.Key.create("internal:AUTH_CONTEXT_KEY"); private static final AsciiString SCHEME = AsciiString.of("https"); + private static final String DIRECT_PATH_SERVICE_CFE_CLUSTER_PREFIX = "google_cfe_"; + private static final String CFE_CLUSTER_RESOURCE_NAME_PREFIX = + "/envoy.config.cluster.v3.Cluster/google_cfe_"; + private static final String CFE_CLUSTER_AUTHORITY_NAME = + "traffic-director-c2p.xds.googleapis.com"; + /** * ClientAltsProtocolNegotiatorFactory is a factory for doing client side negotiation of an ALTS * channel. */ public static final class ClientAltsProtocolNegotiatorFactory - implements InternalNettyChannelBuilder.ProtocolNegotiatorFactory { + implements InternalProtocolNegotiator.ClientFactory { private final ImmutableList targetServiceAccounts; - private final LazyChannel lazyHandshakerChannel; + private final ObjectPool handshakerChannelPool; public ClientAltsProtocolNegotiatorFactory( List targetServiceAccounts, ObjectPool handshakerChannelPool) { this.targetServiceAccounts = ImmutableList.copyOf(targetServiceAccounts); - this.lazyHandshakerChannel = new LazyChannel(handshakerChannelPool); + this.handshakerChannelPool = checkNotNull(handshakerChannelPool, "handshakerChannelPool"); } @Override - public ProtocolNegotiator buildProtocolNegotiator() { + public ProtocolNegotiator newNegotiator() { return new ClientAltsProtocolNegotiator( - new ClientTsiHandshakerFactory(targetServiceAccounts, lazyHandshakerChannel), - lazyHandshakerChannel); + targetServiceAccounts, + handshakerChannelPool); + } + + @Override + public int getDefaultPort() { + return 443; } } @@ -90,9 +110,10 @@ private static final class ClientAltsProtocolNegotiator implements ProtocolNegot private final LazyChannel lazyHandshakerChannel; ClientAltsProtocolNegotiator( - TsiHandshakerFactory handshakerFactory, LazyChannel lazyHandshakerChannel) { - this.handshakerFactory = checkNotNull(handshakerFactory, "handshakerFactory"); - this.lazyHandshakerChannel = checkNotNull(lazyHandshakerChannel, "lazyHandshakerChannel"); + ImmutableList targetServiceAccounts, ObjectPool handshakerChannelPool) { + this.lazyHandshakerChannel = new LazyChannel(handshakerChannelPool); + this.handshakerFactory = + new ClientTsiHandshakerFactory(targetServiceAccounts, lazyHandshakerChannel); } @Override @@ -102,12 +123,16 @@ public AsciiString scheme() { @Override public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) { - TsiHandshaker handshaker = handshakerFactory.newHandshaker(grpcHandler.getAuthority()); + ChannelLogger negotiationLogger = grpcHandler.getNegotiationLogger(); + TsiHandshaker handshaker = + handshakerFactory.newHandshaker(grpcHandler.getAuthority(), negotiationLogger); NettyTsiHandshaker nettyHandshaker = new NettyTsiHandshaker(handshaker); ChannelHandler gnh = InternalProtocolNegotiators.grpcNegotiationHandler(grpcHandler); - ChannelHandler thh = - new TsiHandshakeHandler(gnh, nettyHandshaker, new AltsHandshakeValidator()); - ChannelHandler wuah = InternalProtocolNegotiators.waitUntilActiveHandler(thh); + ChannelHandler thh = new TsiHandshakeHandler( + gnh, nettyHandshaker, new AltsHandshakeValidator(), handshakeSemaphore, + negotiationLogger); + ChannelHandler wuah = InternalProtocolNegotiators.waitUntilActiveHandler(thh, + negotiationLogger); return wuah; } @@ -126,11 +151,13 @@ public static ProtocolNegotiator serverAltsProtocolNegotiator( final class ServerTsiHandshakerFactory implements TsiHandshakerFactory { @Override - public TsiHandshaker newHandshaker(@Nullable String authority) { + public TsiHandshaker newHandshaker( + @Nullable String authority, ChannelLogger negotiationLogger) { assert authority == null; return AltsTsiHandshaker.newServer( HandshakerServiceGrpc.newStub(lazyHandshakerChannel.get()), - new AltsHandshakerOptions(RpcProtocolVersionsUtil.getRpcProtocolVersions())); + new AltsHandshakerOptions(RpcProtocolVersionsUtil.getRpcProtocolVersions()), + negotiationLogger); } } @@ -157,12 +184,16 @@ public AsciiString scheme() { @Override public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) { - TsiHandshaker handshaker = handshakerFactory.newHandshaker(/* authority= */ null); + ChannelLogger negotiationLogger = grpcHandler.getNegotiationLogger(); + TsiHandshaker handshaker = + handshakerFactory.newHandshaker(/* authority= */ null, negotiationLogger); NettyTsiHandshaker nettyHandshaker = new NettyTsiHandshaker(handshaker); ChannelHandler gnh = InternalProtocolNegotiators.grpcNegotiationHandler(grpcHandler); - ChannelHandler thh = - new TsiHandshakeHandler(gnh, nettyHandshaker, new AltsHandshakeValidator()); - ChannelHandler wuah = InternalProtocolNegotiators.waitUntilActiveHandler(thh); + ChannelHandler thh = new TsiHandshakeHandler( + gnh, nettyHandshaker, new AltsHandshakeValidator(), handshakeSemaphore, + negotiationLogger); + ChannelHandler wuah = InternalProtocolNegotiators.waitUntilActiveHandler(thh, + negotiationLogger); return wuah; } @@ -177,9 +208,12 @@ public void close() { * A Protocol Negotiator factory which can switch between ALTS and TLS based on EAG Attrs. */ public static final class GoogleDefaultProtocolNegotiatorFactory - implements ProtocolNegotiatorFactory { + implements InternalProtocolNegotiator.ClientFactory { + @VisibleForTesting + @Nullable + static Attributes.Key clusterNameAttrKey = loadClusterNameAttrKey(); private final ImmutableList targetServiceAccounts; - private final LazyChannel lazyHandshakerChannel; + private final ObjectPool handshakerChannelPool; private final SslContext sslContext; /** @@ -191,16 +225,42 @@ public GoogleDefaultProtocolNegotiatorFactory( ObjectPool handshakerChannelPool, SslContext sslContext) { this.targetServiceAccounts = ImmutableList.copyOf(targetServiceAccounts); - this.lazyHandshakerChannel = new LazyChannel(handshakerChannelPool); + this.handshakerChannelPool = checkNotNull(handshakerChannelPool, "handshakerChannelPool"); this.sslContext = checkNotNull(sslContext, "sslContext"); } @Override - public ProtocolNegotiator buildProtocolNegotiator() { + public ProtocolNegotiator newNegotiator() { return new GoogleDefaultProtocolNegotiator( - new ClientTsiHandshakerFactory(targetServiceAccounts, lazyHandshakerChannel), - lazyHandshakerChannel, - sslContext); + targetServiceAccounts, + handshakerChannelPool, + sslContext, + clusterNameAttrKey); + } + + @Override + public int getDefaultPort() { + return 443; + } + + @SuppressWarnings("unchecked") + @Nullable + private static Attributes.Key loadClusterNameAttrKey() { + Attributes.Key key = null; + try { + Class klass = Class.forName("io.grpc.xds.InternalXdsAttributes"); + key = (Attributes.Key) klass.getField("ATTR_CLUSTER_NAME").get(null); + } catch (ClassNotFoundException e) { + logger.log(Level.FINE, + "Unable to load xDS endpoint cluster name key, this may be expected", e); + } catch (NoSuchFieldException e) { + logger.log(Level.FINE, + "Unable to load xDS endpoint cluster name key, this may be expected", e); + } catch (IllegalAccessException e) { + logger.log(Level.FINE, + "Unable to load xDS endpoint cluster name key, this may be expected", e); + } + return key; } } @@ -208,14 +268,19 @@ private static final class GoogleDefaultProtocolNegotiator implements ProtocolNe private final TsiHandshakerFactory handshakerFactory; private final LazyChannel lazyHandshakerChannel; private final SslContext sslContext; + @Nullable + private final Attributes.Key clusterNameAttrKey; GoogleDefaultProtocolNegotiator( - TsiHandshakerFactory handshakerFactory, - LazyChannel lazyHandshakerChannel, - SslContext sslContext) { - this.handshakerFactory = checkNotNull(handshakerFactory, "handshakerFactory"); - this.lazyHandshakerChannel = checkNotNull(lazyHandshakerChannel, "lazyHandshakerChannel"); + ImmutableList targetServiceAccounts, + ObjectPool handshakerChannelPool, + SslContext sslContext, + @Nullable Attributes.Key clusterNameAttrKey) { + this.lazyHandshakerChannel = new LazyChannel(handshakerChannelPool); + this.handshakerFactory = + new ClientTsiHandshakerFactory(targetServiceAccounts, lazyHandshakerChannel); this.sslContext = checkNotNull(sslContext, "checkNotNull"); + this.clusterNameAttrKey = clusterNameAttrKey; } @Override @@ -226,22 +291,49 @@ public AsciiString scheme() { @Override public ChannelHandler newHandler(GrpcHttp2ConnectionHandler grpcHandler) { ChannelHandler gnh = InternalProtocolNegotiators.grpcNegotiationHandler(grpcHandler); + ChannelLogger negotiationLogger = grpcHandler.getNegotiationLogger(); ChannelHandler securityHandler; - if (grpcHandler.getEagAttributes().get(GrpclbConstants.ATTR_LB_ADDR_AUTHORITY) != null - || grpcHandler.getEagAttributes().get( - GrpclbConstants.ATTR_LB_PROVIDED_BACKEND) != null) { - TsiHandshaker handshaker = handshakerFactory.newHandshaker(grpcHandler.getAuthority()); + boolean isXdsDirectPath = false; + if (clusterNameAttrKey != null) { + isXdsDirectPath = isDirectPathCluster( + grpcHandler.getEagAttributes().get(clusterNameAttrKey)); + } + if (isXdsDirectPath) { + TsiHandshaker handshaker = + handshakerFactory.newHandshaker(grpcHandler.getAuthority(), negotiationLogger); NettyTsiHandshaker nettyHandshaker = new NettyTsiHandshaker(handshaker); - securityHandler = - new TsiHandshakeHandler(gnh, nettyHandshaker, new AltsHandshakeValidator()); + securityHandler = new TsiHandshakeHandler( + gnh, nettyHandshaker, new AltsHandshakeValidator(), handshakeSemaphore, + negotiationLogger); } else { securityHandler = InternalProtocolNegotiators.clientTlsHandler( - gnh, sslContext, grpcHandler.getAuthority()); + gnh, sslContext, grpcHandler.getAuthority(), negotiationLogger); } - ChannelHandler wuah = InternalProtocolNegotiators.waitUntilActiveHandler(securityHandler); + ChannelHandler wuah = InternalProtocolNegotiators.waitUntilActiveHandler(securityHandler, + negotiationLogger); return wuah; } + private boolean isDirectPathCluster(String clusterName) { + if (clusterName == null) { + return false; + } + if (clusterName.startsWith(DIRECT_PATH_SERVICE_CFE_CLUSTER_PREFIX)) { + return false; + } + if (!clusterName.startsWith("xdstp:")) { + return true; + } + try { + URI uri = new URI(clusterName); + // If authority AND path match our CFE checks, use TLS; otherwise use ALTS. + return !CFE_CLUSTER_AUTHORITY_NAME.equals(uri.getHost()) + || !uri.getPath().startsWith(CFE_CLUSTER_RESOURCE_NAME_PREFIX); + } catch (URISyntaxException e) { + return true; // Shouldn't happen, but assume ALTS. + } + } + @Override public void close() { logger.finest("ALTS Server ProtocolNegotiator Closed"); @@ -261,7 +353,8 @@ private static final class ClientTsiHandshakerFactory implements TsiHandshakerFa } @Override - public TsiHandshaker newHandshaker(@Nullable String authority) { + public TsiHandshaker newHandshaker( + @Nullable String authority, ChannelLogger negotiationLogger) { AltsClientOptions handshakerOptions = new AltsClientOptions.Builder() .setRpcProtocolVersions(RpcProtocolVersionsUtil.getRpcProtocolVersions()) @@ -269,7 +362,9 @@ public TsiHandshaker newHandshaker(@Nullable String authority) { .setTargetName(authority) .build(); return AltsTsiHandshaker.newClient( - HandshakerServiceGrpc.newStub(lazyHandshakerChannel.get()), handshakerOptions); + HandshakerServiceGrpc.newStub(lazyHandshakerChannel.get()), + handshakerOptions, + negotiationLogger); } } @@ -307,26 +402,51 @@ private static final class AltsHandshakeValidator extends TsiHandshakeHandler.Ha @Override public SecurityDetails validatePeerObject(Object peerObject) throws GeneralSecurityException { - AltsAuthContext altsAuthContext = (AltsAuthContext) peerObject; + AltsInternalContext altsContext = (AltsInternalContext) peerObject; // Checks peer Rpc Protocol Versions in the ALTS auth context. Fails the connection if // Rpc Protocol Versions mismatch. RpcVersionsCheckResult checkResult = RpcProtocolVersionsUtil.checkRpcProtocolVersions( RpcProtocolVersionsUtil.getRpcProtocolVersions(), - altsAuthContext.getPeerRpcVersions()); + altsContext.getPeerRpcVersions()); if (!checkResult.getResult()) { String errorMessage = "Local Rpc Protocol Versions " + RpcProtocolVersionsUtil.getRpcProtocolVersions() + " are not compatible with peer Rpc Protocol Versions " - + altsAuthContext.getPeerRpcVersions(); + + altsContext.getPeerRpcVersions(); throw Status.UNAVAILABLE.withDescription(errorMessage).asRuntimeException(); } return new SecurityDetails( SecurityLevel.PRIVACY_AND_INTEGRITY, - new Security(new OtherSecurity("alts", Any.pack(altsAuthContext.context)))); + new Security(new OtherSecurity("alts", Any.pack(altsContext.context)))); + } + } + + @VisibleForTesting + static int getAltsMaxConcurrentHandshakes(String altsMaxConcurrentHandshakes) { + if (altsMaxConcurrentHandshakes == null) { + return DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES; + } + try { + int effectiveMaxConcurrentHandshakes = Integer.parseInt(altsMaxConcurrentHandshakes); + if (effectiveMaxConcurrentHandshakes < 0) { + logger.warning( + "GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES environment variable set to invalid value."); + return DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES; + } + return effectiveMaxConcurrentHandshakes; + } catch (NumberFormatException e) { + logger.warning( + "GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES environment variable set to invalid value."); + return DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES; } } + private static int getAltsMaxConcurrentHandshakes() { + return getAltsMaxConcurrentHandshakes( + System.getenv(ALTS_MAX_CONCURRENT_HANDSHAKES_ENV_VARIABLE)); + } + private AltsProtocolNegotiator() {} } diff --git a/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java b/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java index 844e1038746..2d6c322c1b1 100644 --- a/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java +++ b/alts/src/main/java/io/grpc/alts/internal/AltsTsiHandshaker.java @@ -20,20 +20,21 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; +import io.grpc.ChannelLogger; +import io.grpc.ChannelLogger.ChannelLogLevel; import io.grpc.alts.internal.HandshakerServiceGrpc.HandshakerServiceStub; import io.netty.buffer.ByteBufAllocator; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.util.ArrayList; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; /** * Negotiates a grpc channel key to be used by the TsiFrameProtector, using ALTs handshaker service. */ public final class AltsTsiHandshaker implements TsiHandshaker { - private static final Logger logger = Logger.getLogger(AltsTsiHandshaker.class.getName()); + private final ChannelLogger logger; public static final String TSI_SERVICE_ACCOUNT_PEER_PROPERTY = "service_account"; @@ -44,15 +45,20 @@ public final class AltsTsiHandshaker implements TsiHandshaker { /** Starts a new TSI handshaker with client options. */ private AltsTsiHandshaker( - boolean isClient, HandshakerServiceStub stub, AltsHandshakerOptions options) { + boolean isClient, + HandshakerServiceStub stub, + AltsHandshakerOptions options, + ChannelLogger logger) { this.isClient = isClient; - handshaker = new AltsHandshakerClient(stub, options); + this.logger = logger; + handshaker = new AltsHandshakerClient(stub, options, logger); } @VisibleForTesting - AltsTsiHandshaker(boolean isClient, AltsHandshakerClient handshaker) { + AltsTsiHandshaker(boolean isClient, AltsHandshakerClient handshaker, ChannelLogger logger) { this.isClient = isClient; this.handshaker = handshaker; + this.logger = logger; } /** @@ -74,11 +80,12 @@ public boolean processBytesFromPeer(ByteBuffer bytes) throws GeneralSecurityExce return true; } int remaining = bytes.remaining(); - // Call handshaker service to proceess the bytes. + // Call handshaker service to process the bytes. if (outputFrame == null) { checkState(!isClient, "Client handshaker should not process any frame at the beginning."); outputFrame = handshaker.startServerHandshake(bytes); } else { + logger.log(ChannelLogLevel.DEBUG, "Receive ALTS handshake from downstream"); outputFrame = handshaker.next(bytes); } // If handshake has finished or we already have bytes to write, just return true. @@ -119,17 +126,19 @@ public TsiPeer extractPeer() throws GeneralSecurityException { @Override public Object extractPeerObject() throws GeneralSecurityException { Preconditions.checkState(!isInProgress(), "Handshake is not complete."); - return new AltsAuthContext(handshaker.getResult()); + return new AltsInternalContext(handshaker.getResult()); } /** Creates a new TsiHandshaker for use by the client. */ - public static TsiHandshaker newClient(HandshakerServiceStub stub, AltsHandshakerOptions options) { - return new AltsTsiHandshaker(true, stub, options); + public static TsiHandshaker newClient( + HandshakerServiceStub stub, AltsHandshakerOptions options, ChannelLogger logger) { + return new AltsTsiHandshaker(true, stub, options, logger); } /** Creates a new TsiHandshaker for use by the server. */ - public static TsiHandshaker newServer(HandshakerServiceStub stub, AltsHandshakerOptions options) { - return new AltsTsiHandshaker(false, stub, options); + public static TsiHandshaker newServer( + HandshakerServiceStub stub, AltsHandshakerOptions options, ChannelLogger logger) { + return new AltsTsiHandshaker(false, stub, options, logger); } /** @@ -141,24 +150,26 @@ public static TsiHandshaker newServer(HandshakerServiceStub stub, AltsHandshaker public void getBytesToSendToPeer(ByteBuffer bytes) throws GeneralSecurityException { if (outputFrame == null) { // A null outputFrame indicates we haven't started the handshake. if (isClient) { + logger.log(ChannelLogLevel.DEBUG, "Initial ALTS handshake to downstream"); outputFrame = handshaker.startClientHandshake(); } else { // The server needs bytes to process before it can start the handshake. return; } } + logger.log(ChannelLogLevel.DEBUG, "Send ALTS request to downstream"); // Write as many bytes as we are able. ByteBuffer outputFrameAlias = outputFrame; if (outputFrame.remaining() > bytes.remaining()) { outputFrameAlias = outputFrame.duplicate(); - outputFrameAlias.limit(outputFrameAlias.position() + bytes.remaining()); + ((Buffer) outputFrameAlias).limit(outputFrameAlias.position() + bytes.remaining()); } bytes.put(outputFrameAlias); - outputFrame.position(outputFrameAlias.position()); + ((Buffer) outputFrame).position(outputFrameAlias.position()); } /** - * Returns true if and only if the handshake is still in progress + * Returns true if and only if the handshake is still in progress. * * @return true, if the handshake is still in progress, false otherwise. */ @@ -189,7 +200,7 @@ public TsiFrameProtector createFrameProtector(int maxFrameSize, ByteBufAllocator maxFrameSize = Math.min(peerMaxFrameSize, AltsTsiFrameProtector.getMaxFrameSize()); maxFrameSize = Math.max(AltsTsiFrameProtector.getMinFrameSize(), maxFrameSize); } - logger.log(Level.FINE, "Maximum frame size value is {0}.", maxFrameSize); + logger.log(ChannelLogLevel.INFO, "Maximum frame size value is {0}.", maxFrameSize); return new AltsTsiFrameProtector(maxFrameSize, new AltsChannelCrypter(key, isClient), alloc); } diff --git a/alts/src/main/java/io/grpc/alts/internal/AsyncSemaphore.java b/alts/src/main/java/io/grpc/alts/internal/AsyncSemaphore.java new file mode 100644 index 00000000000..a8251c7fbd3 --- /dev/null +++ b/alts/src/main/java/io/grpc/alts/internal/AsyncSemaphore.java @@ -0,0 +1,61 @@ +/* + * Copyright 2021 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts.internal; + +import com.google.errorprone.annotations.concurrent.GuardedBy; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelPromise; +import java.util.LinkedList; +import java.util.Queue; + +/** Provides a semaphore primitive, without blocking waiting on permits. */ +final class AsyncSemaphore { + private final Object lock = new Object(); + @SuppressWarnings("JdkObsolete") // LinkedList avoids high watermark memory issues + private final Queue queue = new LinkedList<>(); + @GuardedBy("lock") + private int permits; + + public AsyncSemaphore(int permits) { + this.permits = permits; + } + + public ChannelFuture acquire(ChannelHandlerContext ctx) { + synchronized (lock) { + if (permits > 0) { + permits--; + return ctx.newSucceededFuture(); + } + ChannelPromise promise = ctx.newPromise(); + queue.add(promise); + return promise; + } + } + + public void release() { + ChannelPromise next; + synchronized (lock) { + next = queue.poll(); + if (next == null) { + permits++; + return; + } + } + next.setSuccess(); + } +} diff --git a/alts/src/main/java/io/grpc/alts/internal/ChannelCrypterNetty.java b/alts/src/main/java/io/grpc/alts/internal/ChannelCrypterNetty.java index 4164560e7a0..e2e7d4046fb 100644 --- a/alts/src/main/java/io/grpc/alts/internal/ChannelCrypterNetty.java +++ b/alts/src/main/java/io/grpc/alts/internal/ChannelCrypterNetty.java @@ -21,8 +21,8 @@ import java.util.List; /** - * A @{code ChannelCrypterNetty} performs stateful encryption and decryption of independent input - * and output streams. Both decrypt and encrypt gather their input from a list of Netty @{link + * A {@code ChannelCrypterNetty} performs stateful encryption and decryption of independent input + * and output streams. Both decrypt and encrypt gather their input from a list of Netty {@link * ByteBuf} instances. * *

Note that we provide implementations of this interface that provide integrity only and diff --git a/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java b/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java index 5087123ab06..b91cfdad08c 100644 --- a/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java +++ b/alts/src/main/java/io/grpc/alts/internal/NettyTsiHandshaker.java @@ -99,7 +99,7 @@ boolean processBytesFromPeer(ByteBuf data) throws GeneralSecurityException { } /** - * Returns true if and only if the handshake is still in progress + * Returns true if and only if the handshake is still in progress. * * @return true, if the handshake is still in progress, false otherwise. */ diff --git a/alts/src/main/java/io/grpc/alts/internal/ProtectedPromise.java b/alts/src/main/java/io/grpc/alts/internal/ProtectedPromise.java index e204acdd5f9..871a51f1bea 100644 --- a/alts/src/main/java/io/grpc/alts/internal/ProtectedPromise.java +++ b/alts/src/main/java/io/grpc/alts/internal/ProtectedPromise.java @@ -78,7 +78,7 @@ public ChannelPromise doneAllocatingPromises() { if (!doneAllocating) { doneAllocating = true; if (successfulCount == expectedCount) { - trySuccessInternal(null); + trySuccessInternal(); return super.setSuccess(null); } } @@ -117,18 +117,18 @@ private boolean awaitingPromises() { } @Override - public ChannelPromise setSuccess(Void result) { - trySuccess(result); + public ChannelPromise setSuccess(Void unused) { + trySuccess(null); return this; } @Override - public boolean trySuccess(Void result) { + public boolean trySuccess(Void unused) { if (awaitingPromises()) { ++successfulCount; if (successfulCount == expectedCount && doneAllocating) { - trySuccessInternal(result); - return super.trySuccess(result); + trySuccessInternal(); + return super.trySuccess(null); } // TODO: We break the interface a bit here. // Multiple success events can be processed without issue because this is an aggregation. @@ -137,9 +137,9 @@ public boolean trySuccess(Void result) { return false; } - private void trySuccessInternal(Void result) { + private void trySuccessInternal() { for (int i = 0; i < unprotectedPromises.size(); ++i) { - unprotectedPromises.get(i).trySuccess(result); + unprotectedPromises.get(i).trySuccess(null); } } diff --git a/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java b/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java index a4123a7a53e..7964b122f8c 100644 --- a/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java +++ b/alts/src/main/java/io/grpc/alts/internal/TsiHandshakeHandler.java @@ -22,15 +22,16 @@ import static io.grpc.alts.internal.AltsProtocolNegotiator.TSI_PEER_KEY; import io.grpc.Attributes; +import io.grpc.ChannelLogger; import io.grpc.ChannelLogger.ChannelLogLevel; import io.grpc.InternalChannelz.Security; import io.grpc.SecurityLevel; import io.grpc.alts.internal.TsiHandshakeHandler.HandshakeValidator.SecurityDetails; import io.grpc.internal.GrpcAttributes; import io.grpc.netty.InternalProtocolNegotiationEvent; -import io.grpc.netty.InternalProtocolNegotiators; import io.grpc.netty.ProtocolNegotiationEvent; import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; @@ -82,17 +83,33 @@ public abstract SecurityDetails validatePeerObject(Object peerObject) private final NettyTsiHandshaker handshaker; private final HandshakeValidator handshakeValidator; private final ChannelHandler next; + private final AsyncSemaphore semaphore; private ProtocolNegotiationEvent pne; + private boolean semaphoreAcquired; + private final ChannelLogger negotiationLogger; /** * Constructs a TsiHandshakeHandler. */ public TsiHandshakeHandler( - ChannelHandler next, NettyTsiHandshaker handshaker, HandshakeValidator handshakeValidator) { + ChannelHandler next, NettyTsiHandshaker handshaker, HandshakeValidator handshakeValidator, + ChannelLogger negotiationLogger) { + this(next, handshaker, handshakeValidator, null, negotiationLogger); + } + + /** + * Constructs a TsHandshakeHandler. If a semaphore is provided, a permit from the semaphore is + * required to start the handshake and is returned when the handshake ends. + */ + public TsiHandshakeHandler( + ChannelHandler next, NettyTsiHandshaker handshaker, HandshakeValidator handshakeValidator, + AsyncSemaphore semaphore, ChannelLogger negotiationLogger) { this.handshaker = checkNotNull(handshaker, "handshaker"); this.handshakeValidator = checkNotNull(handshakeValidator, "handshakeValidator"); this.next = checkNotNull(next, "next"); + this.semaphore = semaphore; + this.negotiationLogger = negotiationLogger; } @Override @@ -137,13 +154,36 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List out) t } @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + public void userEventTriggered(final ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof ProtocolNegotiationEvent) { checkState(pne == null, "negotiation already started"); pne = (ProtocolNegotiationEvent) evt; - InternalProtocolNegotiators.negotiationLogger(ctx) - .log(ChannelLogLevel.INFO, "TsiHandshake started"); - sendHandshake(ctx); + negotiationLogger.log(ChannelLogLevel.INFO, "TsiHandshake started"); + ChannelFuture acquire = semaphoreAcquire(ctx); + if (acquire.isSuccess()) { + semaphoreAcquired = true; + sendHandshake(ctx); + } else { + acquire.addListener(new ChannelFutureListener() { + @Override public void operationComplete(ChannelFuture future) { + if (!future.isSuccess()) { + ctx.fireExceptionCaught(future.cause()); + return; + } + if (ctx.isRemoved()) { + semaphoreRelease(); + return; + } + semaphoreAcquired = true; + try { + sendHandshake(ctx); + } catch (Exception ex) { + ctx.fireExceptionCaught(ex); + } + ctx.flush(); + } + }); + } } else { super.userEventTriggered(ctx, evt); } @@ -152,8 +192,7 @@ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exc private void fireProtocolNegotiationEvent( ChannelHandlerContext ctx, TsiPeer peer, Object authContext, SecurityDetails details) { checkState(pne != null, "negotiation not yet complete"); - InternalProtocolNegotiators.negotiationLogger(ctx) - .log(ChannelLogLevel.INFO, "TsiHandshake finished"); + negotiationLogger.log(ChannelLogLevel.INFO, "TsiHandshake finished"); ProtocolNegotiationEvent localPne = pne; Attributes.Builder attrs = InternalProtocolNegotiationEvent.getAttributes(localPne).toBuilder() .set(TSI_PEER_KEY, peer) @@ -188,6 +227,24 @@ private void sendHandshake(ChannelHandlerContext ctx) throws GeneralSecurityExce @Override protected void handlerRemoved0(ChannelHandlerContext ctx) throws Exception { + if (semaphoreAcquired) { + semaphoreRelease(); + semaphoreAcquired = false; + } handshaker.close(); } -} \ No newline at end of file + + private ChannelFuture semaphoreAcquire(ChannelHandlerContext ctx) { + if (semaphore == null) { + return ctx.newSucceededFuture(); + } else { + return semaphore.acquire(ctx); + } + } + + private void semaphoreRelease() { + if (semaphore != null) { + semaphore.release(); + } + } +} diff --git a/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java b/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java index 35b945770d2..6580a4433c7 100644 --- a/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java +++ b/alts/src/main/java/io/grpc/alts/internal/TsiHandshaker.java @@ -68,7 +68,7 @@ public interface TsiHandshaker { boolean processBytesFromPeer(ByteBuffer bytes) throws GeneralSecurityException; /** - * Returns true if and only if the handshake is still in progress + * Returns true if and only if the handshake is still in progress. * * @return true, if the handshake is still in progress, false otherwise. */ @@ -86,7 +86,7 @@ public interface TsiHandshaker { * * @return the extracted peer. */ - public Object extractPeerObject() throws GeneralSecurityException; + Object extractPeerObject() throws GeneralSecurityException; /** * Creates a frame protector from a completed handshake. No other methods may be called after the diff --git a/alts/src/main/java/io/grpc/alts/internal/TsiHandshakerFactory.java b/alts/src/main/java/io/grpc/alts/internal/TsiHandshakerFactory.java index 996bd003654..7d17a3954c8 100644 --- a/alts/src/main/java/io/grpc/alts/internal/TsiHandshakerFactory.java +++ b/alts/src/main/java/io/grpc/alts/internal/TsiHandshakerFactory.java @@ -16,11 +16,12 @@ package io.grpc.alts.internal; +import io.grpc.ChannelLogger; import javax.annotation.Nullable; /** Factory that manufactures instances of {@link TsiHandshaker}. */ public interface TsiHandshakerFactory { /** Creates a new handshaker. */ - TsiHandshaker newHandshaker(@Nullable String authority); + TsiHandshaker newHandshaker(@Nullable String authority, ChannelLogger logger); } diff --git a/alts/src/main/java/io/grpc/alts/internal/TsiPeer.java b/alts/src/main/java/io/grpc/alts/internal/TsiPeer.java index 01e3c821ad8..c02188c50ac 100644 --- a/alts/src/main/java/io/grpc/alts/internal/TsiPeer.java +++ b/alts/src/main/java/io/grpc/alts/internal/TsiPeer.java @@ -54,7 +54,7 @@ public abstract static class Property { private final String name; private final T value; - public Property(@Nonnull String name, @Nonnull T value) { + protected Property(@Nonnull String name, @Nonnull T value) { this.name = name; this.value = value; } diff --git a/alts/src/test/java/io/grpc/alts/AltsContextUtilTest.java b/alts/src/test/java/io/grpc/alts/AltsContextUtilTest.java new file mode 100644 index 00000000000..675fa29fc99 --- /dev/null +++ b/alts/src/test/java/io/grpc/alts/AltsContextUtilTest.java @@ -0,0 +1,134 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package io.grpc.alts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.grpc.Attributes; +import io.grpc.ClientCall; +import io.grpc.ServerCall; +import io.grpc.alts.AltsContext.SecurityLevel; +import io.grpc.alts.internal.AltsInternalContext; +import io.grpc.alts.internal.AltsProtocolNegotiator; +import io.grpc.alts.internal.HandshakerResult; +import io.grpc.alts.internal.Identity; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link AltsContextUtil}. */ +@RunWith(JUnit4.class) +public class AltsContextUtilTest { + @Test + public void check_noAttributeValue() { + assertFalse(AltsContextUtil.check(Attributes.newBuilder().build())); + } + + @Test + public void check_unexpectedAttributeValueType() { + assertFalse(AltsContextUtil.check(Attributes.newBuilder() + .set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new Object()) + .build())); + } + + @Test + public void check_altsInternalContext() { + assertTrue(AltsContextUtil.check(Attributes.newBuilder() + .set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance()) + .build())); + } + + @Test + public void checkServer_altsInternalContext() { + ServerCall call = mock(ServerCall.class); + when(call.getAttributes()).thenReturn(Attributes.newBuilder() + .set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance()) + .build()); + + assertTrue(AltsContextUtil.check(call)); + } + + @Test + public void checkClient_altsInternalContext() { + ClientCall call = mock(ClientCall.class); + when(call.getAttributes()).thenReturn(Attributes.newBuilder() + .set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance()) + .build()); + + assertTrue(AltsContextUtil.check(call)); + } + + @Test + public void createFrom_altsInternalContext() { + HandshakerResult handshakerResult = + HandshakerResult.newBuilder() + .setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer")) + .setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer")) + .build(); + + AltsContext context = AltsContextUtil.createFrom(Attributes.newBuilder() + .set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult)) + .build()); + assertEquals("remote@peer", context.getPeerServiceAccount()); + assertEquals("local@peer", context.getLocalServiceAccount()); + assertEquals(SecurityLevel.INTEGRITY_AND_PRIVACY, context.getSecurityLevel()); + } + + @Test(expected = IllegalArgumentException.class) + public void createFrom_noAttributeValue() { + AltsContextUtil.createFrom(Attributes.newBuilder().build()); + } + + @Test + public void createFromServer_altsInternalContext() { + HandshakerResult handshakerResult = + HandshakerResult.newBuilder() + .setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer")) + .setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer")) + .build(); + + ServerCall call = mock(ServerCall.class); + when(call.getAttributes()).thenReturn(Attributes.newBuilder() + .set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult)) + .build()); + + AltsContext context = AltsContextUtil.createFrom(call); + assertEquals("remote@peer", context.getPeerServiceAccount()); + } + + @Test + public void createFromClient_altsInternalContext() { + HandshakerResult handshakerResult = + HandshakerResult.newBuilder() + .setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer")) + .setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer")) + .build(); + + ClientCall call = mock(ClientCall.class); + when(call.getAttributes()).thenReturn(Attributes.newBuilder() + .set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult)) + .build()); + + AltsContext context = AltsContextUtil.createFrom(call); + assertEquals("remote@peer", context.getPeerServiceAccount()); + } +} diff --git a/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java b/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java index dfbe8b5ff9f..8b4691df331 100644 --- a/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java +++ b/alts/src/test/java/io/grpc/alts/AuthorizationUtilTest.java @@ -24,7 +24,7 @@ import io.grpc.MethodDescriptor; import io.grpc.ServerCall; import io.grpc.Status; -import io.grpc.alts.internal.AltsAuthContext; +import io.grpc.alts.internal.AltsInternalContext; import io.grpc.alts.internal.AltsProtocolNegotiator; import io.grpc.alts.internal.HandshakerResult; import io.grpc.alts.internal.Identity; @@ -65,8 +65,8 @@ private static class FakeServerCall extends ServerCall { HandshakerResult.newBuilder() .setPeerIdentity(Identity.newBuilder().setServiceAccount(peerServiceAccount)) .build(); - AltsAuthContext altsAuthContext = new AltsAuthContext(handshakerResult); - attrsBuilder.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, altsAuthContext); + AltsInternalContext altsContext = new AltsInternalContext(handshakerResult); + attrsBuilder.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, altsContext); } attrs = attrsBuilder.build(); } diff --git a/alts/src/test/java/io/grpc/alts/CheckGcpEnvironmentTest.java b/alts/src/test/java/io/grpc/alts/CheckGcpEnvironmentTest.java deleted file mode 100644 index bef16f7776c..00000000000 --- a/alts/src/test/java/io/grpc/alts/CheckGcpEnvironmentTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2018 The gRPC Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.grpc.alts; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.BufferedReader; -import java.io.StringReader; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public final class CheckGcpEnvironmentTest { - - @Test - public void checkGcpLinuxPlatformData() throws Exception { - BufferedReader reader; - reader = new BufferedReader(new StringReader("HP Z440 Workstation")); - assertFalse(CheckGcpEnvironment.checkProductNameOnLinux(reader)); - reader = new BufferedReader(new StringReader("Google")); - assertTrue(CheckGcpEnvironment.checkProductNameOnLinux(reader)); - reader = new BufferedReader(new StringReader("Google Compute Engine")); - assertTrue(CheckGcpEnvironment.checkProductNameOnLinux(reader)); - reader = new BufferedReader(new StringReader("Google Compute Engine ")); - assertTrue(CheckGcpEnvironment.checkProductNameOnLinux(reader)); - } - - @Test - public void checkGcpWindowsPlatformData() throws Exception { - BufferedReader reader; - reader = new BufferedReader(new StringReader("Product : Google")); - assertFalse(CheckGcpEnvironment.checkBiosDataOnWindows(reader)); - reader = new BufferedReader(new StringReader("Manufacturer : LENOVO")); - assertFalse(CheckGcpEnvironment.checkBiosDataOnWindows(reader)); - reader = new BufferedReader(new StringReader("Manufacturer : Google Compute Engine")); - assertFalse(CheckGcpEnvironment.checkBiosDataOnWindows(reader)); - reader = new BufferedReader(new StringReader("Manufacturer : Google")); - assertTrue(CheckGcpEnvironment.checkBiosDataOnWindows(reader)); - reader = new BufferedReader(new StringReader("Manufacturer:Google")); - assertTrue(CheckGcpEnvironment.checkBiosDataOnWindows(reader)); - reader = new BufferedReader(new StringReader("Manufacturer : Google ")); - assertTrue(CheckGcpEnvironment.checkBiosDataOnWindows(reader)); - reader = new BufferedReader(new StringReader("BIOSVersion : 1.0\nManufacturer : Google\n")); - assertTrue(CheckGcpEnvironment.checkBiosDataOnWindows(reader)); - } -} diff --git a/alts/src/test/java/io/grpc/alts/ComputeEngineChannelBuilderTest.java b/alts/src/test/java/io/grpc/alts/ComputeEngineChannelBuilderTest.java index f7752a28735..03fd113a65e 100644 --- a/alts/src/test/java/io/grpc/alts/ComputeEngineChannelBuilderTest.java +++ b/alts/src/test/java/io/grpc/alts/ComputeEngineChannelBuilderTest.java @@ -16,9 +16,6 @@ package io.grpc.alts; -import static com.google.common.truth.Truth.assertThat; - -import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -30,9 +27,5 @@ public final class ComputeEngineChannelBuilderTest { public void buildsNettyChannel() throws Exception { ComputeEngineChannelBuilder builder = ComputeEngineChannelBuilder.forTarget("localhost:8080"); builder.build(); - - ProtocolNegotiator protocolNegotiator = builder.getProtocolNegotiatorForTest(); - assertThat(protocolNegotiator.getClass().getSimpleName()) - .isEqualTo("GoogleDefaultProtocolNegotiator"); } } diff --git a/alts/src/test/java/io/grpc/alts/DualCallCredentialsTest.java b/alts/src/test/java/io/grpc/alts/DualCallCredentialsTest.java new file mode 100644 index 00000000000..29646191be1 --- /dev/null +++ b/alts/src/test/java/io/grpc/alts/DualCallCredentialsTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2024 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import io.grpc.Attributes; +import io.grpc.CallCredentials; +import io.grpc.CallCredentials.RequestInfo; +import io.grpc.MethodDescriptor; +import io.grpc.SecurityLevel; +import io.grpc.alts.internal.AltsInternalContext; +import io.grpc.alts.internal.AltsProtocolNegotiator; +import io.grpc.testing.TestMethodDescriptors; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +/** Unit tests for {@link DualCallCredentials}. */ +@RunWith(JUnit4.class) +public class DualCallCredentialsTest { + + @Rule public final MockitoRule mocks = MockitoJUnit.rule(); + + @Mock CallCredentials tlsCallCredentials; + + @Mock CallCredentials altsCallCredentials; + + private static final String AUTHORITY = "testauthority"; + private static final SecurityLevel SECURITY_LEVEL = SecurityLevel.PRIVACY_AND_INTEGRITY; + + @Test + public void invokeTlsCallCredentials() { + DualCallCredentials callCredentials = + new DualCallCredentials(tlsCallCredentials, altsCallCredentials); + RequestInfo requestInfo = new RequestInfoImpl(false); + callCredentials.applyRequestMetadata(requestInfo, null, null); + + verify(altsCallCredentials, never()).applyRequestMetadata(any(), any(), any()); + verify(tlsCallCredentials, times(1)).applyRequestMetadata(requestInfo, null, null); + } + + @Test + public void invokeAltsCallCredentials() { + DualCallCredentials callCredentials = + new DualCallCredentials(tlsCallCredentials, altsCallCredentials); + RequestInfo requestInfo = new RequestInfoImpl(true); + callCredentials.applyRequestMetadata(requestInfo, null, null); + + verify(altsCallCredentials, times(1)).applyRequestMetadata(requestInfo, null, null); + verify(tlsCallCredentials, never()).applyRequestMetadata(any(), any(), any()); + } + + private static final class RequestInfoImpl extends CallCredentials.RequestInfo { + private Attributes attrs; + + RequestInfoImpl(boolean hasAltsContext) { + attrs = + hasAltsContext + ? Attributes.newBuilder() + .set( + AltsProtocolNegotiator.AUTH_CONTEXT_KEY, + AltsInternalContext.getDefaultInstance()) + .build() + : Attributes.EMPTY; + } + + @Override + public MethodDescriptor getMethodDescriptor() { + return TestMethodDescriptors.voidMethod(); + } + + @Override + public SecurityLevel getSecurityLevel() { + return SECURITY_LEVEL; + } + + @Override + public String getAuthority() { + return AUTHORITY; + } + + @Override + public Attributes getTransportAttrs() { + return attrs; + } + } +} diff --git a/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java b/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java index 4336aff7458..c73ef4444e9 100644 --- a/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java +++ b/alts/src/test/java/io/grpc/alts/GoogleDefaultChannelBuilderTest.java @@ -16,9 +16,6 @@ package io.grpc.alts; -import static com.google.common.truth.Truth.assertThat; - -import io.grpc.netty.InternalProtocolNegotiator.ProtocolNegotiator; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; @@ -30,9 +27,5 @@ public final class GoogleDefaultChannelBuilderTest { public void buildsNettyChannel() throws Exception { GoogleDefaultChannelBuilder builder = GoogleDefaultChannelBuilder.forTarget("localhost:8080"); builder.build(); - - ProtocolNegotiator protocolNegotiator = builder.getProtocolNegotiatorForTest(); - assertThat(protocolNegotiator.getClass().getSimpleName()) - .isEqualTo("GoogleDefaultProtocolNegotiator"); } } diff --git a/alts/src/test/java/io/grpc/alts/HandshakerServiceChannelTest.java b/alts/src/test/java/io/grpc/alts/HandshakerServiceChannelTest.java index dc297492fe3..221001157f1 100644 --- a/alts/src/test/java/io/grpc/alts/HandshakerServiceChannelTest.java +++ b/alts/src/test/java/io/grpc/alts/HandshakerServiceChannelTest.java @@ -46,7 +46,7 @@ public void unaryRpc(SimpleRequest request, StreamObserver so) { so.onCompleted(); } }) - .build()); + .build()); private Resource resource; @Before @@ -67,6 +67,24 @@ public void sharedChannel_authority() { } } + @Test + public void getHandshakerTarget_nullEnvVar() { + assertThat(HandshakerServiceChannel.getHandshakerTarget(null)) + .isEqualTo("metadata.google.internal.:8080"); + } + + @Test + public void getHandshakerTarget_envVarWithPort() { + assertThat(HandshakerServiceChannel.getHandshakerTarget("169.254.169.254:80")) + .isEqualTo("169.254.169.254:8080"); + } + + @Test + public void getHandshakerTarget_envVarWithHostOnly() { + assertThat(HandshakerServiceChannel.getHandshakerTarget("169.254.169.254")) + .isEqualTo("169.254.169.254:8080"); + } + @Test public void resource_works() { Channel channel = resource.create(); diff --git a/alts/src/test/java/io/grpc/alts/InternalCheckGcpEnvironmentTest.java b/alts/src/test/java/io/grpc/alts/InternalCheckGcpEnvironmentTest.java new file mode 100644 index 00000000000..1234cfc49c3 --- /dev/null +++ b/alts/src/test/java/io/grpc/alts/InternalCheckGcpEnvironmentTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.StringReader; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public final class InternalCheckGcpEnvironmentTest { + + @Test + public void checkGcpLinuxPlatformData() throws Exception { + BufferedReader reader; + reader = new BufferedReader(new StringReader("HP Z440 Workstation")); + assertFalse(InternalCheckGcpEnvironment.checkProductNameOnLinux(reader)); + reader = new BufferedReader(new StringReader("Google")); + assertTrue(InternalCheckGcpEnvironment.checkProductNameOnLinux(reader)); + reader = new BufferedReader(new StringReader("Google Compute Engine")); + assertTrue(InternalCheckGcpEnvironment.checkProductNameOnLinux(reader)); + reader = new BufferedReader(new StringReader("Google Compute Engine ")); + assertTrue(InternalCheckGcpEnvironment.checkProductNameOnLinux(reader)); + } + + @Test + public void checkGcpWindowsPlatformData() throws Exception { + BufferedReader reader; + reader = new BufferedReader(new StringReader("Product : Google")); + assertFalse(InternalCheckGcpEnvironment.checkBiosDataOnWindows(reader)); + reader = new BufferedReader(new StringReader("Manufacturer : LENOVO")); + assertFalse(InternalCheckGcpEnvironment.checkBiosDataOnWindows(reader)); + reader = new BufferedReader(new StringReader("Manufacturer : Google Compute Engine")); + assertFalse(InternalCheckGcpEnvironment.checkBiosDataOnWindows(reader)); + reader = new BufferedReader(new StringReader("Manufacturer : Google")); + assertTrue(InternalCheckGcpEnvironment.checkBiosDataOnWindows(reader)); + reader = new BufferedReader(new StringReader("Manufacturer:Google")); + assertTrue(InternalCheckGcpEnvironment.checkBiosDataOnWindows(reader)); + reader = new BufferedReader(new StringReader("Manufacturer : Google ")); + assertTrue(InternalCheckGcpEnvironment.checkBiosDataOnWindows(reader)); + reader = new BufferedReader(new StringReader("BIOSVersion : 1.0\nManufacturer : Google\n")); + assertTrue(InternalCheckGcpEnvironment.checkBiosDataOnWindows(reader)); + } +} diff --git a/alts/src/test/java/io/grpc/alts/internal/AesGcmHkdfAeadCrypterTest.java b/alts/src/test/java/io/grpc/alts/internal/AesGcmHkdfAeadCrypterTest.java index d655a6e8358..06f2ff5365f 100644 --- a/alts/src/test/java/io/grpc/alts/internal/AesGcmHkdfAeadCrypterTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/AesGcmHkdfAeadCrypterTest.java @@ -117,7 +117,7 @@ public void testVectorEncrypt() throws GeneralSecurityException { ByteBuffer.wrap(testVector.plaintext), ByteBuffer.wrap(testVector.aad), testVector.nonce); - String msg = "Failure for test vector " + i; + String msg = "Failure for test vector " + i + " " + testVector.comment; assertWithMessage(msg) .that(ciphertextBuffer.remaining()) .isEqualTo(bufferSize - testVector.ciphertext.length); @@ -142,7 +142,7 @@ public void testVectorDecrypt() throws GeneralSecurityException { ByteBuffer.wrap(testVector.ciphertext), ByteBuffer.wrap(testVector.aad), testVector.nonce); - String msg = "Failure for test vector " + i; + String msg = "Failure for test vector " + i + " " + testVector.comment; assertWithMessage(msg) .that(plaintextBuffer.remaining()) .isEqualTo(bufferSize - testVector.plaintext.length); diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsAuthContextTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsAuthContextTest.java deleted file mode 100644 index c73a145a4ca..00000000000 --- a/alts/src/test/java/io/grpc/alts/internal/AltsAuthContextTest.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2018 The gRPC Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.grpc.alts.internal; - -import static org.junit.Assert.assertEquals; - -import java.util.HashMap; -import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** Unit tests for {@link AltsAuthContext}. */ -@RunWith(JUnit4.class) -public final class AltsAuthContextTest { - private static final int TEST_MAX_RPC_VERSION_MAJOR = 3; - private static final int TEST_MAX_RPC_VERSION_MINOR = 5; - private static final int TEST_MIN_RPC_VERSION_MAJOR = 2; - private static final int TEST_MIN_RPC_VERSION_MINOR = 1; - private static final SecurityLevel TEST_SECURITY_LEVEL = SecurityLevel.INTEGRITY_AND_PRIVACY; - private static final String TEST_APPLICATION_PROTOCOL = "grpc"; - private static final String TEST_LOCAL_SERVICE_ACCOUNT = "local@gserviceaccount.com"; - private static final String TEST_PEER_SERVICE_ACCOUNT = "peer@gserviceaccount.com"; - private static final String TEST_RECORD_PROTOCOL = "ALTSRP_GCM_AES128"; - private static final String TEST_PEER_ATTRIBUTES_KEY = "peer"; - private static final String TEST_PEER_ATTRIBUTES_VALUE = "attributes"; - - private Map testPeerAttributes; - private HandshakerResult handshakerResult; - private RpcProtocolVersions rpcVersions; - - @Before - public void setUp() { - testPeerAttributes = new HashMap(); - testPeerAttributes.put(TEST_PEER_ATTRIBUTES_KEY, TEST_PEER_ATTRIBUTES_VALUE); - rpcVersions = - RpcProtocolVersions.newBuilder() - .setMaxRpcVersion( - RpcProtocolVersions.Version.newBuilder() - .setMajor(TEST_MAX_RPC_VERSION_MAJOR) - .setMinor(TEST_MAX_RPC_VERSION_MINOR) - .build()) - .setMinRpcVersion( - RpcProtocolVersions.Version.newBuilder() - .setMajor(TEST_MIN_RPC_VERSION_MAJOR) - .setMinor(TEST_MIN_RPC_VERSION_MINOR) - .build()) - .build(); - Identity.Builder peerIdentity = Identity.newBuilder() - .setServiceAccount(TEST_PEER_SERVICE_ACCOUNT); - peerIdentity.putAllAttributes(testPeerAttributes); - handshakerResult = - HandshakerResult.newBuilder() - .setApplicationProtocol(TEST_APPLICATION_PROTOCOL) - .setRecordProtocol(TEST_RECORD_PROTOCOL) - .setPeerIdentity(peerIdentity) - .setLocalIdentity(Identity.newBuilder().setServiceAccount(TEST_LOCAL_SERVICE_ACCOUNT)) - .setPeerRpcVersions(rpcVersions) - .build(); - } - - @Test - public void testAltsAuthContext() { - AltsAuthContext authContext = new AltsAuthContext(handshakerResult); - assertEquals(TEST_APPLICATION_PROTOCOL, authContext.getApplicationProtocol()); - assertEquals(TEST_RECORD_PROTOCOL, authContext.getRecordProtocol()); - assertEquals(TEST_SECURITY_LEVEL, authContext.getSecurityLevel()); - assertEquals(TEST_PEER_SERVICE_ACCOUNT, authContext.getPeerServiceAccount()); - assertEquals(TEST_LOCAL_SERVICE_ACCOUNT, authContext.getLocalServiceAccount()); - assertEquals(rpcVersions, authContext.getPeerRpcVersions()); - assertEquals(testPeerAttributes, authContext.getPeerAttributes()); - assertEquals(TEST_PEER_ATTRIBUTES_VALUE, authContext.getPeerAttributes() - .get(TEST_PEER_ATTRIBUTES_KEY)); - } -} diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsFramingTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsFramingTest.java index 5ad250e0621..a4703e052ee 100644 --- a/alts/src/test/java/io/grpc/alts/internal/AltsFramingTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/AltsFramingTest.java @@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.fail; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.GeneralSecurityException; @@ -38,7 +39,7 @@ public void parserFrameLengthNegativeFails() throws GeneralSecurityException { buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(-1); // write invalid length buffer.put((byte) 0); // write some byte - buffer.flip(); + ((Buffer) buffer).flip(); try { parser.readBytes(buffer); @@ -56,7 +57,7 @@ public void parserFrameLengthSmallerMessageTypeFails() throws GeneralSecurityExc buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(AltsFraming.getFrameMessageTypeHeaderSize() - 1); // write invalid length buffer.put((byte) 0); // write some byte - buffer.flip(); + ((Buffer) buffer).flip(); try { parser.readBytes(buffer); @@ -74,7 +75,7 @@ public void parserFrameLengthTooLargeFails() throws GeneralSecurityException { buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(AltsFraming.getMaxDataLength() + 1); // write invalid length buffer.put((byte) 0); // write some byte - buffer.flip(); + ((Buffer) buffer).flip(); try { parser.readBytes(buffer); @@ -97,7 +98,7 @@ public void parserFrameLengthMaxOk() throws GeneralSecurityException { buffer.putInt(6); // default message type buffer.put(new byte[dataLength - AltsFraming.getFrameMessageTypeHeaderSize()]); // write data buffer.put((byte) 0); - buffer.flip(); + ((Buffer) buffer).flip(); parser.readBytes(buffer); @@ -116,7 +117,7 @@ public void parserFrameLengthZeroOk() throws GeneralSecurityException { buffer.putInt(dataLength); // write invalid length buffer.putInt(6); // default message type buffer.put((byte) 0); - buffer.flip(); + ((Buffer) buffer).flip(); parser.readBytes(buffer); diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerClientTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerClientTest.java index d1bd5ffea08..5a41fc0fc4f 100644 --- a/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerClientTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerClientTest.java @@ -29,6 +29,8 @@ import com.google.common.collect.ImmutableList; import com.google.protobuf.ByteString; +import io.grpc.internal.TestUtils.NoopChannelLogger; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import org.junit.Before; @@ -59,7 +61,8 @@ public void setUp() { .setTargetName(TEST_TARGET_NAME) .setTargetServiceAccounts(ImmutableList.of(TEST_TARGET_SERVICE_ACCOUNT)) .build(); - handshaker = new AltsHandshakerClient(mockStub, clientOptions); + NoopChannelLogger channelLogger = new NoopChannelLogger(); + handshaker = new AltsHandshakerClient(mockStub, clientOptions, channelLogger); } @Test @@ -178,7 +181,7 @@ public void startServerHandshakeWithPrefixBuffer() throws Exception { .thenReturn(MockAltsHandshakerResp.getOkResponse(BYTES_CONSUMED)); ByteBuffer inBytes = ByteBuffer.allocate(IN_BYTES_SIZE); - inBytes.position(PREFIX_POSITION); + ((Buffer) inBytes).position(PREFIX_POSITION); ByteBuffer outFrame = handshaker.startServerHandshake(inBytes); assertEquals(ByteString.copyFrom(outFrame), MockAltsHandshakerResp.getOutFrame()); @@ -265,7 +268,8 @@ public void setRpcVersions() throws Exception { .setTargetServiceAccounts(ImmutableList.of(TEST_TARGET_SERVICE_ACCOUNT)) .setRpcProtocolVersions(rpcVersions) .build(); - handshaker = new AltsHandshakerClient(mockStub, clientOptions); + NoopChannelLogger channelLogger = new NoopChannelLogger(); + handshaker = new AltsHandshakerClient(mockStub, clientOptions, channelLogger); handshaker.startClientHandshake(); diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerStubTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerStubTest.java index 2267a765a90..7a6018b5064 100644 --- a/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerStubTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/AltsHandshakerStubTest.java @@ -32,7 +32,7 @@ @RunWith(JUnit4.class) public class AltsHandshakerStubTest { /** Mock status of handshaker service. */ - private static enum Status { + private enum Status { OK, ERROR, COMPLETE @@ -68,6 +68,7 @@ private void sendAndExpectError() throws InterruptedException { fail("Exception expected"); } catch (IOException ex) { assertThat(ex).hasMessageThat().contains("Received a terminating error"); + assertThat(ex.getCause()).hasMessageThat().contains("Root cause message"); } } @@ -152,7 +153,7 @@ public void onNext(final HandshakerReq req) { reader.onNext(resp.setOutFrames(req.getNext().getInBytes()).build()); break; case ERROR: - reader.onError(new RuntimeException()); + reader.onError(new RuntimeException("Root cause message")); break; case COMPLETE: reader.onCompleted(); diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsInternalContextTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsInternalContextTest.java new file mode 100644 index 00000000000..87898a3300b --- /dev/null +++ b/alts/src/test/java/io/grpc/alts/internal/AltsInternalContextTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2018 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.alts.internal; + +import static org.junit.Assert.assertEquals; + +import java.util.HashMap; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link AltsInternalContext}. */ +@RunWith(JUnit4.class) +public final class AltsInternalContextTest { + private static final int TEST_MAX_RPC_VERSION_MAJOR = 3; + private static final int TEST_MAX_RPC_VERSION_MINOR = 5; + private static final int TEST_MIN_RPC_VERSION_MAJOR = 2; + private static final int TEST_MIN_RPC_VERSION_MINOR = 1; + private static final SecurityLevel TEST_SECURITY_LEVEL = SecurityLevel.INTEGRITY_AND_PRIVACY; + private static final String TEST_APPLICATION_PROTOCOL = "grpc"; + private static final String TEST_LOCAL_SERVICE_ACCOUNT = "local@gserviceaccount.com"; + private static final String TEST_PEER_SERVICE_ACCOUNT = "peer@gserviceaccount.com"; + private static final String TEST_RECORD_PROTOCOL = "ALTSRP_GCM_AES128"; + private static final String TEST_PEER_ATTRIBUTES_KEY = "peer"; + private static final String TEST_PEER_ATTRIBUTES_VALUE = "attributes"; + + private Map testPeerAttributes; + private HandshakerResult handshakerResult; + private RpcProtocolVersions rpcVersions; + + @Before + public void setUp() { + testPeerAttributes = new HashMap(); + testPeerAttributes.put(TEST_PEER_ATTRIBUTES_KEY, TEST_PEER_ATTRIBUTES_VALUE); + rpcVersions = + RpcProtocolVersions.newBuilder() + .setMaxRpcVersion( + RpcProtocolVersions.Version.newBuilder() + .setMajor(TEST_MAX_RPC_VERSION_MAJOR) + .setMinor(TEST_MAX_RPC_VERSION_MINOR) + .build()) + .setMinRpcVersion( + RpcProtocolVersions.Version.newBuilder() + .setMajor(TEST_MIN_RPC_VERSION_MAJOR) + .setMinor(TEST_MIN_RPC_VERSION_MINOR) + .build()) + .build(); + Identity.Builder peerIdentity = Identity.newBuilder() + .setServiceAccount(TEST_PEER_SERVICE_ACCOUNT); + peerIdentity.putAllAttributes(testPeerAttributes); + handshakerResult = + HandshakerResult.newBuilder() + .setApplicationProtocol(TEST_APPLICATION_PROTOCOL) + .setRecordProtocol(TEST_RECORD_PROTOCOL) + .setPeerIdentity(peerIdentity) + .setLocalIdentity(Identity.newBuilder().setServiceAccount(TEST_LOCAL_SERVICE_ACCOUNT)) + .setPeerRpcVersions(rpcVersions) + .build(); + } + + @Test + public void testAltsInternalContext() { + AltsInternalContext context = new AltsInternalContext(handshakerResult); + assertEquals(TEST_APPLICATION_PROTOCOL, context.getApplicationProtocol()); + assertEquals(TEST_RECORD_PROTOCOL, context.getRecordProtocol()); + assertEquals(TEST_SECURITY_LEVEL, context.getSecurityLevel()); + assertEquals(TEST_PEER_SERVICE_ACCOUNT, context.getPeerServiceAccount()); + assertEquals(TEST_LOCAL_SERVICE_ACCOUNT, context.getLocalServiceAccount()); + assertEquals(rpcVersions, context.getPeerRpcVersions()); + assertEquals(testPeerAttributes, context.getPeerAttributes()); + assertEquals(TEST_PEER_ATTRIBUTES_VALUE, context.getPeerAttributes() + .get(TEST_PEER_ATTRIBUTES_KEY)); + } +} diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java index 395090dbd83..d47607ed90f 100644 --- a/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/AltsProtocolNegotiatorTest.java @@ -26,6 +26,7 @@ import io.grpc.Attributes; import io.grpc.Channel; +import io.grpc.ChannelLogger; import io.grpc.Grpc; import io.grpc.InternalChannelz; import io.grpc.ManagedChannel; @@ -37,6 +38,7 @@ import io.grpc.internal.FixedObjectPool; import io.grpc.internal.GrpcAttributes; import io.grpc.internal.ObjectPool; +import io.grpc.internal.TestUtils.NoopChannelLogger; import io.grpc.netty.GrpcHttp2ConnectionHandler; import io.grpc.netty.InternalProtocolNegotiationEvent; import io.grpc.netty.NettyChannelBuilder; @@ -96,8 +98,8 @@ public class AltsProtocolNegotiatorTest { private Throwable caughtException; private TsiPeer mockedTsiPeer = new TsiPeer(Collections.>emptyList()); - private AltsAuthContext mockedAltsContext = - new AltsAuthContext( + private AltsInternalContext mockedAltsContext = + new AltsInternalContext( HandshakerResult.newBuilder() .setPeerRpcVersions(RpcProtocolVersionsUtil.getRpcProtocolVersions()) .build()); @@ -130,8 +132,8 @@ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws E TsiHandshakerFactory handshakerFactory = new DelegatingTsiHandshakerFactory(FakeTsiHandshaker.clientHandshakerFactory()) { @Override - public TsiHandshaker newHandshaker(String authority) { - return new DelegatingTsiHandshaker(super.newHandshaker(authority)) { + public TsiHandshaker newHandshaker(String authority, ChannelLogger logger) { + return new DelegatingTsiHandshaker(super.newHandshaker(authority, logger)) { @Override public TsiPeer extractPeer() throws GeneralSecurityException { return mockedTsiPeer; @@ -200,8 +202,11 @@ public void operationComplete(ChannelFuture future) throws Exception { channel.flush(); // Capture the protected data written to the wire. - assertEquals(1, channel.outboundMessages().size()); - ByteBuf protectedData = channel.readOutbound(); + assertThat(channel.outboundMessages()).isNotEmpty(); + ByteBuf protectedData = channel.alloc().buffer(); + while (!channel.outboundMessages().isEmpty()) { + protectedData.writeBytes((ByteBuf) channel.readOutbound()); + } assertEquals(message.length(), writeCount.get()); // Read the protected message at the server and verify it matches the original message. @@ -325,16 +330,18 @@ public void doNotFlushEmptyBuffer() throws Exception { String message = "hello"; ByteBuf in = Unpooled.copiedBuffer(message, UTF_8); - assertEquals(0, protector.flushes.get()); + int flushes = protector.flushes.get(); Future done = channel.write(in); channel.flush(); + flushes++; done.get(5, TimeUnit.SECONDS); - assertEquals(1, protector.flushes.get()); + assertEquals(flushes, protector.flushes.get()); + // Flush does not propagate done = channel.write(Unpooled.EMPTY_BUFFER); channel.flush(); done.get(5, TimeUnit.SECONDS); - assertEquals(1, protector.flushes.get()); + assertEquals(flushes, protector.flushes.get()); } @Test @@ -352,6 +359,29 @@ public void peerPropagated() throws Exception { .isEqualTo(SecurityLevel.PRIVACY_AND_INTEGRITY); } + @Test + public void getAltsMaxConcurrentHandshakes_success() throws Exception { + assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes("10")).isEqualTo(10); + } + + @Test + public void getAltsMaxConcurrentHandshakes_envVariableNotSet() throws Exception { + assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes(null)) + .isEqualTo(AltsProtocolNegotiator.DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES); + } + + @Test + public void getAltsMaxConcurrentHandshakes_envVariableNotANumber() throws Exception { + assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes("not-a-number")) + .isEqualTo(AltsProtocolNegotiator.DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES); + } + + @Test + public void getAltsMaxConcurrentHandshakes_envVariableNegative() throws Exception { + assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes("-10")) + .isEqualTo(AltsProtocolNegotiator.DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES); + } + private void doHandshake() throws Exception { // Capture the client frame and add to the server. assertEquals(1, channel.outboundMessages().size()); @@ -404,7 +434,7 @@ private CapturingGrpcHttp2ConnectionHandler( Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder, Http2Settings initialSettings) { - super(null, decoder, encoder, initialSettings); + super(null, decoder, encoder, initialSettings, new NoopChannelLogger()); } @Override @@ -426,8 +456,8 @@ private static class DelegatingTsiHandshakerFactory implements TsiHandshakerFact } @Override - public TsiHandshaker newHandshaker(String authority) { - return delegate.newHandshaker(authority); + public TsiHandshaker newHandshaker(String authority, ChannelLogger logger) { + return delegate.newHandshaker(authority, logger); } } diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsTsiHandshakerTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsTsiHandshakerTest.java index f474586b6ad..ae1696401be 100644 --- a/alts/src/test/java/io/grpc/alts/internal/AltsTsiHandshakerTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/AltsTsiHandshakerTest.java @@ -26,6 +26,8 @@ import static org.mockito.Mockito.when; import com.google.protobuf.ByteString; +import io.grpc.internal.TestUtils.NoopChannelLogger; +import java.nio.Buffer; import java.nio.ByteBuffer; import org.junit.Before; import org.junit.Test; @@ -70,8 +72,9 @@ public class AltsTsiHandshakerTest { public void setUp() throws Exception { mockClient = mock(AltsHandshakerClient.class); mockServer = mock(AltsHandshakerClient.class); - handshakerClient = new AltsTsiHandshaker(true, mockClient); - handshakerServer = new AltsTsiHandshaker(false, mockServer); + NoopChannelLogger channelLogger = new NoopChannelLogger(); + handshakerClient = new AltsTsiHandshaker(true, mockClient, channelLogger); + handshakerServer = new AltsTsiHandshaker(false, mockServer, channelLogger); } private HandshakerResult getHandshakerResult(boolean isClient) { @@ -112,7 +115,7 @@ public void processBytesFromPeerStartServer() throws Exception { verify(mockServer, never()).startClientHandshake(); verify(mockServer, never()).next(ArgumentMatchers.any()); // Mock transport buffer all consumed by processBytesFromPeer and there is an output frame. - transportBuffer.position(transportBuffer.limit()); + ((Buffer) transportBuffer).position(transportBuffer.limit()); when(mockServer.startServerHandshake(transportBuffer)).thenReturn(outputFrame); when(mockServer.isFinished()).thenReturn(false); @@ -127,7 +130,7 @@ public void processBytesFromPeerStartServerEmptyOutput() throws Exception { verify(mockServer, never()).next(ArgumentMatchers.any()); // Mock transport buffer all consumed by processBytesFromPeer and output frame is empty. // Expect processBytesFromPeer return False, because more data are needed from the peer. - transportBuffer.position(transportBuffer.limit()); + ((Buffer) transportBuffer).position(transportBuffer.limit()); when(mockServer.startServerHandshake(transportBuffer)).thenReturn(emptyOutputFrame); when(mockServer.isFinished()).thenReturn(false); @@ -174,7 +177,7 @@ public void processBytesFromPeerClientNext() throws Exception { when(mockClient.isFinished()).thenReturn(false); handshakerClient.getBytesToSendToPeer(transportBuffer); - transportBuffer.position(transportBuffer.limit()); + ((Buffer) transportBuffer).position(transportBuffer.limit()); assertFalse(handshakerClient.processBytesFromPeer(transportBuffer)); } @@ -231,7 +234,7 @@ public void extractClientPeerSuccess() throws Exception { TEST_SERVER_SERVICE_ACCOUNT, clientPeer.getProperty(AltsTsiHandshaker.TSI_SERVICE_ACCOUNT_PEER_PROPERTY).getValue()); - AltsAuthContext clientContext = (AltsAuthContext) handshakerClient.extractPeerObject(); + AltsInternalContext clientContext = (AltsInternalContext) handshakerClient.extractPeerObject(); assertEquals(TEST_APPLICATION_PROTOCOL, clientContext.getApplicationProtocol()); assertEquals(TEST_RECORD_PROTOCOL, clientContext.getRecordProtocol()); assertEquals(TEST_SERVER_SERVICE_ACCOUNT, clientContext.getPeerServiceAccount()); @@ -257,7 +260,7 @@ public void extractServerPeerSuccess() throws Exception { TEST_CLIENT_SERVICE_ACCOUNT, serverPeer.getProperty(AltsTsiHandshaker.TSI_SERVICE_ACCOUNT_PEER_PROPERTY).getValue()); - AltsAuthContext serverContext = (AltsAuthContext) handshakerServer.extractPeerObject(); + AltsInternalContext serverContext = (AltsInternalContext) handshakerServer.extractPeerObject(); assertEquals(TEST_APPLICATION_PROTOCOL, serverContext.getApplicationProtocol()); assertEquals(TEST_RECORD_PROTOCOL, serverContext.getRecordProtocol()); assertEquals(TEST_CLIENT_SERVICE_ACCOUNT, serverContext.getPeerServiceAccount()); diff --git a/alts/src/test/java/io/grpc/alts/internal/AltsTsiTest.java b/alts/src/test/java/io/grpc/alts/internal/AltsTsiTest.java index a6832ad8de2..cb39abb9ddc 100644 --- a/alts/src/test/java/io/grpc/alts/internal/AltsTsiTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/AltsTsiTest.java @@ -21,6 +21,7 @@ import com.google.common.testing.GcFinalization; import io.grpc.alts.internal.ByteBufTestUtils.RegisterRef; import io.grpc.alts.internal.TsiTest.Handshakers; +import io.grpc.internal.TestUtils.NoopChannelLogger; import io.netty.buffer.ByteBuf; import io.netty.util.ReferenceCounted; import io.netty.util.ResourceLeakDetector; @@ -61,8 +62,9 @@ public void setUp() throws Exception { AltsHandshakerOptions handshakerOptions = new AltsHandshakerOptions(null); MockAltsHandshakerStub clientStub = new MockAltsHandshakerStub(); MockAltsHandshakerStub serverStub = new MockAltsHandshakerStub(); - client = new AltsHandshakerClient(clientStub, handshakerOptions); - server = new AltsHandshakerClient(serverStub, handshakerOptions); + NoopChannelLogger channelLogger = new NoopChannelLogger(); + client = new AltsHandshakerClient(clientStub, handshakerOptions, channelLogger); + server = new AltsHandshakerClient(serverStub, handshakerOptions, channelLogger); } @After @@ -76,8 +78,9 @@ public void tearDown() { } private Handshakers newHandshakers() { - TsiHandshaker clientHandshaker = new AltsTsiHandshaker(true, client); - TsiHandshaker serverHandshaker = new AltsTsiHandshaker(false, server); + NoopChannelLogger channelLogger = new NoopChannelLogger(); + TsiHandshaker clientHandshaker = new AltsTsiHandshaker(true, client, channelLogger); + TsiHandshaker serverHandshaker = new AltsTsiHandshaker(false, server, channelLogger); return new Handshakers(clientHandshaker, serverHandshaker); } diff --git a/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java b/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java index 1483e4b08e2..7a6119dc0be 100644 --- a/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java +++ b/alts/src/test/java/io/grpc/alts/internal/FakeTsiHandshaker.java @@ -19,7 +19,9 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.Preconditions; +import io.grpc.ChannelLogger; import io.grpc.alts.internal.TsiPeer.Property; +import io.grpc.internal.TestUtils.NoopChannelLogger; import io.netty.buffer.ByteBufAllocator; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; @@ -37,7 +39,7 @@ public class FakeTsiHandshaker implements TsiHandshaker { private static final TsiHandshakerFactory clientHandshakerFactory = new TsiHandshakerFactory() { @Override - public TsiHandshaker newHandshaker(String authority) { + public TsiHandshaker newHandshaker(String authority, ChannelLogger logger) { return new FakeTsiHandshaker(true); } }; @@ -45,7 +47,7 @@ public TsiHandshaker newHandshaker(String authority) { private static final TsiHandshakerFactory serverHandshakerFactory = new TsiHandshakerFactory() { @Override - public TsiHandshaker newHandshaker(String authority) { + public TsiHandshaker newHandshaker(String authority, ChannelLogger logger) { return new FakeTsiHandshaker(false); } }; @@ -66,6 +68,7 @@ enum State { SERVER_FINISHED; // Returns the next State. In order to advance to sendState=N, receiveState must be N-1. + @SuppressWarnings("EnumOrdinal") public State next() { if (ordinal() + 1 < values().length) { return values()[ordinal() + 1]; @@ -83,11 +86,13 @@ public static TsiHandshakerFactory serverHandshakerFactory() { } public static TsiHandshaker newFakeHandshakerClient() { - return clientHandshakerFactory.newHandshaker(null); + NoopChannelLogger channelLogger = new NoopChannelLogger(); + return clientHandshakerFactory.newHandshaker(null, channelLogger); } public static TsiHandshaker newFakeHandshakerServer() { - return serverHandshakerFactory.newHandshaker(null); + NoopChannelLogger channelLogger = new NoopChannelLogger(); + return serverHandshakerFactory.newHandshaker(null, channelLogger); } protected FakeTsiHandshaker(boolean isClient) { @@ -143,7 +148,7 @@ public void getBytesToSendToPeer(ByteBuffer bytes) throws GeneralSecurityExcepti return; } - // Prepare the next message, if neeeded. + // Prepare the next message, if needed. if (sendBuffer == null) { if (sendState.next() != receiveState) { // We're still waiting for bytes from the peer, so bail. @@ -210,7 +215,7 @@ public TsiPeer extractPeer() { @Override public Object extractPeerObject() { - return AltsAuthContext.getDefaultInstance(); + return AltsInternalContext.getDefaultInstance(); } @Override diff --git a/alts/src/test/java/io/grpc/alts/internal/FakeTsiTest.java b/alts/src/test/java/io/grpc/alts/internal/FakeTsiTest.java index cf7c3133e7b..f908160f958 100644 --- a/alts/src/test/java/io/grpc/alts/internal/FakeTsiTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/FakeTsiTest.java @@ -27,6 +27,7 @@ import io.netty.util.ReferenceCounted; import io.netty.util.ResourceLeakDetector; import io.netty.util.ResourceLeakDetector.Level; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.util.ArrayList; @@ -86,11 +87,11 @@ public void handshakeStateOrderTest() { byte[] transportBufferBytes = new byte[TsiTest.getDefaultTransportBufferSize()]; ByteBuffer transportBuffer = ByteBuffer.wrap(transportBufferBytes); - transportBuffer.limit(0); // Start off with an empty buffer + ((Buffer) transportBuffer).limit(0); // Start off with an empty buffer - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); clientHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertEquals( FakeTsiHandshaker.State.CLIENT_INIT.toString().trim(), new String(transportBufferBytes, 4, transportBuffer.remaining(), UTF_8).trim()); @@ -99,14 +100,14 @@ public void handshakeStateOrderTest() { assertFalse(transportBuffer.hasRemaining()); // client shouldn't offer any more bytes - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); clientHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertFalse(transportBuffer.hasRemaining()); - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); serverHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertEquals( FakeTsiHandshaker.State.SERVER_INIT.toString().trim(), new String(transportBufferBytes, 4, transportBuffer.remaining(), UTF_8).trim()); @@ -115,14 +116,14 @@ public void handshakeStateOrderTest() { assertFalse(transportBuffer.hasRemaining()); // server shouldn't offer any more bytes - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); serverHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertFalse(transportBuffer.hasRemaining()); - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); clientHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertEquals( FakeTsiHandshaker.State.CLIENT_FINISHED.toString().trim(), new String(transportBufferBytes, 4, transportBuffer.remaining(), UTF_8).trim()); @@ -131,14 +132,14 @@ public void handshakeStateOrderTest() { assertFalse(transportBuffer.hasRemaining()); // client shouldn't offer any more bytes - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); clientHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertFalse(transportBuffer.hasRemaining()); - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); serverHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertEquals( FakeTsiHandshaker.State.SERVER_FINISHED.toString().trim(), new String(transportBufferBytes, 4, transportBuffer.remaining(), UTF_8).trim()); @@ -147,9 +148,9 @@ public void handshakeStateOrderTest() { assertFalse(transportBuffer.hasRemaining()); // server shouldn't offer any more bytes - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); serverHandshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); assertFalse(transportBuffer.hasRemaining()); } catch (GeneralSecurityException e) { throw new AssertionError(e); diff --git a/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java b/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java index 5858fc3f52d..14c19e554ae 100644 --- a/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/GoogleDefaultProtocolNegotiatorTest.java @@ -17,14 +17,18 @@ package io.grpc.alts.internal; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import com.google.common.collect.ImmutableList; import io.grpc.Attributes; import io.grpc.Channel; +import io.grpc.ChannelLogger; +import io.grpc.ChannelLogger.ChannelLogLevel; import io.grpc.ManagedChannel; -import io.grpc.grpclb.GrpclbConstants; import io.grpc.inprocess.InProcessChannelBuilder; import io.grpc.internal.ObjectPool; import io.grpc.netty.GrpcHttp2ConnectionHandler; @@ -37,84 +41,183 @@ import io.netty.channel.embedded.EmbeddedChannel; import io.netty.handler.ssl.SslContext; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.Nullable; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.experimental.runners.Enclosed; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -@RunWith(JUnit4.class) +@RunWith(Enclosed.class) public final class GoogleDefaultProtocolNegotiatorTest { - private ProtocolNegotiator googleProtocolNegotiator; - private final ObjectPool handshakerChannelPool = new ObjectPool() { + @RunWith(JUnit4.class) + public abstract static class HandlerSelectionTest { + private ProtocolNegotiator googleProtocolNegotiator; + private Attributes.Key originalClusterNameAttrKey; + private final ObjectPool handshakerChannelPool = new ObjectPool() { - @Override - public Channel getObject() { - return InProcessChannelBuilder.forName("test").build(); + @Override + public Channel getObject() { + return InProcessChannelBuilder.forName("test").build(); + } + + @Override + public Channel returnObject(Object object) { + ((ManagedChannel) object).shutdownNow(); + return null; + } + }; + + @Before + public void setUp() throws Exception { + SslContext sslContext = GrpcSslContexts.forClient().build(); + originalClusterNameAttrKey = + AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory.clusterNameAttrKey; + AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory.clusterNameAttrKey = + getClusterNameAttrKey(); + googleProtocolNegotiator = new AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory( + ImmutableList.of(), + handshakerChannelPool, + sslContext) + .newNegotiator(); } - @Override - public Channel returnObject(Object object) { - ((ManagedChannel) object).shutdownNow(); - return null; + @After + public void tearDown() { + googleProtocolNegotiator.close(); + AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory.clusterNameAttrKey = + originalClusterNameAttrKey; } - }; - @Before - public void setUp() throws Exception { - SslContext sslContext = GrpcSslContexts.forClient().build(); + @Nullable + abstract Attributes.Key getClusterNameAttrKey(); - googleProtocolNegotiator = new AltsProtocolNegotiator.GoogleDefaultProtocolNegotiatorFactory( - ImmutableList.of(), - handshakerChannelPool, - sslContext) - .buildProtocolNegotiator(); - } + @Test + public void tlsHandler_emptyAttributes() { + subtest_tlsHandler(Attributes.EMPTY); + } + + void subtest_altsHandler(Attributes eagAttributes) { + GrpcHttp2ConnectionHandler mockHandler = mock(GrpcHttp2ConnectionHandler.class); + when(mockHandler.getEagAttributes()).thenReturn(eagAttributes); + ChannelLogger logger = mock(ChannelLogger.class); + doNothing().when(logger).log(any(ChannelLogLevel.class), anyString()); + when(mockHandler.getNegotiationLogger()).thenReturn(logger); + + final AtomicReference failure = new AtomicReference<>(); + ChannelHandler exceptionCaught = new ChannelInboundHandlerAdapter() { + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + failure.set(cause); + super.exceptionCaught(ctx, cause); + } + }; + ChannelHandler h = googleProtocolNegotiator.newHandler(mockHandler); + EmbeddedChannel chan = new EmbeddedChannel(exceptionCaught); + // Add the negotiator handler last, but to the front. Putting this in ctor above would make + // it throw early. + chan.pipeline().addFirst(h); + chan.pipeline().fireUserEventTriggered(InternalProtocolNegotiationEvent.getDefault()); + + // Check that the message complained about the ALTS code, rather than SSL. ALTS throws on + // being added, so it's hard to catch it at the right time to make this assertion. + assertThat(failure.get()).hasMessageThat().contains("TsiHandshakeHandler"); + } + + void subtest_tlsHandler(Attributes eagAttributes) { + GrpcHttp2ConnectionHandler mockHandler = mock(GrpcHttp2ConnectionHandler.class); + when(mockHandler.getEagAttributes()).thenReturn(eagAttributes); + when(mockHandler.getAuthority()).thenReturn("authority"); + ChannelLogger logger = mock(ChannelLogger.class); + doNothing().when(logger).log(any(ChannelLogLevel.class), anyString()); + when(mockHandler.getNegotiationLogger()).thenReturn(logger); - @After - public void tearDown() { - googleProtocolNegotiator.close(); + ChannelHandler h = googleProtocolNegotiator.newHandler(mockHandler); + EmbeddedChannel chan = new EmbeddedChannel(h); + chan.pipeline().fireUserEventTriggered(InternalProtocolNegotiationEvent.getDefault()); + + assertThat(chan.pipeline().first().getClass().getSimpleName()).isEqualTo("SslHandler"); + } } - @Test - public void altsHandler() { - Attributes eagAttributes = - Attributes.newBuilder().set(GrpclbConstants.ATTR_LB_PROVIDED_BACKEND, true).build(); - GrpcHttp2ConnectionHandler mockHandler = mock(GrpcHttp2ConnectionHandler.class); - when(mockHandler.getEagAttributes()).thenReturn(eagAttributes); + @RunWith(JUnit4.class) + public static class WithoutXdsInClasspath extends HandlerSelectionTest { - final AtomicReference failure = new AtomicReference<>(); - ChannelHandler exceptionCaught = new ChannelInboundHandlerAdapter() { - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - failure.set(cause); - super.exceptionCaught(ctx, cause); - } - }; - ChannelHandler h = googleProtocolNegotiator.newHandler(mockHandler); - EmbeddedChannel chan = new EmbeddedChannel(exceptionCaught); - // Add the negotiator handler last, but to the front. Putting this in ctor above would make it - // throw early. - chan.pipeline().addFirst(h); - chan.pipeline().fireUserEventTriggered(InternalProtocolNegotiationEvent.getDefault()); - - // Check that the message complained about the ALTS code, rather than SSL. ALTS throws on - // being added, so it's hard to catch it at the right time to make this assertion. - assertThat(failure.get()).hasMessageThat().contains("TsiHandshakeHandler"); + @Nullable + @Override + Attributes.Key getClusterNameAttrKey() { + return null; + } } - @Test - public void tlsHandler() { - Attributes eagAttributes = Attributes.EMPTY; - GrpcHttp2ConnectionHandler mockHandler = mock(GrpcHttp2ConnectionHandler.class); - when(mockHandler.getEagAttributes()).thenReturn(eagAttributes); - when(mockHandler.getAuthority()).thenReturn("authority"); + @RunWith(JUnit4.class) + public static class WithXdsInClasspath extends HandlerSelectionTest { + // Same as io.grpc.xds.InternalXdsAttributes.ATTR_CLUSTER_NAME + private static final Attributes.Key XDS_CLUSTER_NAME_ATTR_KEY = + Attributes.Key.create("io.grpc.xds.InternalXdsAttributes.clusterName"); + + @Nullable + @Override + Attributes.Key getClusterNameAttrKey() { + return XDS_CLUSTER_NAME_ATTR_KEY; + } - ChannelHandler h = googleProtocolNegotiator.newHandler(mockHandler); - EmbeddedChannel chan = new EmbeddedChannel(h); - chan.pipeline().fireUserEventTriggered(InternalProtocolNegotiationEvent.getDefault()); + @Test + public void altsHandler_xdsCluster() { + Attributes attrs = + Attributes.newBuilder().set(XDS_CLUSTER_NAME_ATTR_KEY, "api.googleapis.com").build(); + subtest_altsHandler(attrs); + } + + @Test + public void tlsHandler_googleCfe() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, "google_cfe_api.googleapis.com").build(); + subtest_tlsHandler(attrs); + } - assertThat(chan.pipeline().first().getClass().getSimpleName()).isEqualTo("SslHandler"); + @Test + public void altsHandler_googleCfe_federation() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, "xdstp1://").build(); + subtest_altsHandler(attrs); + } + + @Test + public void tlsHanlder_googleCfe() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, + "xdstp://traffic-director-c2p.xds.googleapis.com/" + + "envoy.config.cluster.v3.Cluster/google_cfe_example/apis") + .build(); + subtest_tlsHandler(attrs); + } + + @Test + public void altsHanlder_nonGoogleCfe_authorityNotMatch() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, + "//example.com/envoy.config.cluster.v3.Cluster/google_cfe_") + .build(); + subtest_altsHandler(attrs); + } + + @Test + public void altsHanlder_nonGoogleCfe_pathNotMatch() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, + "//traffic-director-c2p.xds.googleapis.com/envoy.config.cluster.v3.Cluster/google_gfe") + .build(); + subtest_altsHandler(attrs); + } + + @Test + public void altsHandler_googleCfe_invalidUri() { + Attributes attrs = Attributes.newBuilder().set( + XDS_CLUSTER_NAME_ATTR_KEY, "//").build(); + subtest_altsHandler(attrs); + } } } diff --git a/alts/src/test/java/io/grpc/alts/internal/MockAltsHandshakerResp.java b/alts/src/test/java/io/grpc/alts/internal/MockAltsHandshakerResp.java index 7843d681208..a21082be41f 100644 --- a/alts/src/test/java/io/grpc/alts/internal/MockAltsHandshakerResp.java +++ b/alts/src/test/java/io/grpc/alts/internal/MockAltsHandshakerResp.java @@ -20,6 +20,7 @@ import com.google.protobuf.ByteString; import io.grpc.Status; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.security.SecureRandom; @@ -62,7 +63,7 @@ static ByteString getOutFrame() { buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(frameSize); buffer.put(TEST_OUT_FRAME.getBytes(UTF_8)); - buffer.flip(); + ((Buffer) buffer).flip(); return ByteString.copyFrom(buffer); } diff --git a/alts/src/test/java/io/grpc/alts/internal/TsiTest.java b/alts/src/test/java/io/grpc/alts/internal/TsiTest.java index 5182ecde028..0241182f2db 100644 --- a/alts/src/test/java/io/grpc/alts/internal/TsiTest.java +++ b/alts/src/test/java/io/grpc/alts/internal/TsiTest.java @@ -26,6 +26,7 @@ import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.buffer.UnpooledByteBufAllocator; +import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.GeneralSecurityException; import java.util.ArrayList; @@ -33,13 +34,13 @@ import java.util.List; import javax.crypto.AEADBadTagException; -/** Utility class that provides tests for implementations of @{link TsiHandshaker}. */ +/** Utility class that provides tests for implementations of {@link TsiHandshaker}. */ public final class TsiTest { - private static final String DECRYPTION_FAILURE_RE = "Tag mismatch!|BAD_DECRYPT"; + private static final String DECRYPTION_FAILURE_RE = "Tag mismatch|BAD_DECRYPT"; private TsiTest() {} - /** A @{code TsiHandshaker} pair for running tests. */ + /** A {@code TsiHandshaker} pair for running tests. */ public static class Handshakers { private final TsiHandshaker client; private final TsiHandshaker server; @@ -83,7 +84,7 @@ static void performHandshake(int transportBufferSize, Handshakers handshakers) byte[] transportBufferBytes = new byte[transportBufferSize]; ByteBuffer transportBuffer = ByteBuffer.wrap(transportBufferBytes); - transportBuffer.limit(0); // Start off with an empty buffer + ((Buffer) transportBuffer).limit(0); // Start off with an empty buffer while (clientHandshaker.isInProgress() || serverHandshaker.isInProgress()) { for (TsiHandshaker handshaker : new TsiHandshaker[] {clientHandshaker, serverHandshaker}) { @@ -94,9 +95,9 @@ static void performHandshake(int transportBufferSize, Handshakers handshakers) } // Put new bytes on the wire, if needed. if (handshaker.isInProgress()) { - transportBuffer.clear(); + ((Buffer) transportBuffer).clear(); handshaker.getBytesToSendToPeer(transportBuffer); - transportBuffer.flip(); + ((Buffer) transportBuffer).flip(); } } } diff --git a/android-interop-testing/build.gradle b/android-interop-testing/build.gradle index ec144bda19a..b61d50a6763 100644 --- a/android-interop-testing/build.gradle +++ b/android-interop-testing/build.gradle @@ -7,10 +7,10 @@ description = 'gRPC: Android Integration Testing' repositories { google() - jcenter() } android { + namespace = 'io.grpc.android.integrationtest' sourceSets { main { java { @@ -25,17 +25,19 @@ android { } } } - compileSdkVersion 26 + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + compileSdkVersion 34 defaultConfig { applicationId "io.grpc.android.integrationtest" - // API level 14+ is required for TLS since Google Play Services v10.2 - minSdkVersion 14 - targetSdkVersion 26 + minSdkVersion 23 + targetSdkVersion 33 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - multiDexEnabled true } buildTypes { debug { minifyEnabled false } @@ -44,33 +46,42 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } - lintOptions { disable 'InvalidPackage', 'HardcodedText' } + lintOptions { + disable 'InvalidPackage', 'HardcodedText', 'UsingOnClickInXml', + 'MissingClass' // https://github.com/grpc/grpc-java/issues/8799 + } + packagingOptions { + exclude 'META-INF/INDEX.LIST' + exclude 'META-INF/io.netty.versions.properties' + } } dependencies { - implementation 'com.android.support:appcompat-v7:26.1.0' - implementation 'com.android.support:multidex:1.0.3' - implementation 'com.android.support:support-annotations:27.1.1' - implementation 'com.google.android.gms:play-services-base:15.0.1' + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation libraries.androidx.annotation + implementation 'com.google.android.gms:play-services-base:18.0.1' - implementation project(':grpc-auth'), + implementation project(':grpc-android'), + project(':grpc-api'), + project(':grpc-core'), project(':grpc-census'), project(':grpc-okhttp'), project(':grpc-protobuf-lite'), project(':grpc-stub'), project(':grpc-testing'), libraries.junit, - libraries.truth + libraries.truth, + libraries.androidx.test.rules, + libraries.androidx.test.core, + libraries.opencensus.contrib.grpc.metrics - implementation (libraries.google_auth_oauth2_http) { - exclude group: 'org.apache.httpcomponents' + implementation (project(':grpc-services')) { + exclude group: 'com.google.protobuf' + exclude group: 'com.google.guava' } - censusGrpcMetricDependency 'implementation' - compileOnly libraries.javax_annotation - - androidTestImplementation 'androidx.test:rules:1.1.0-alpha1' - androidTestImplementation 'androidx.test:runner:1.1.0-alpha1' + androidTestImplementation libraries.androidx.test.ext.junit, + libraries.androidx.test.runner } // Checkstyle doesn't run automatically with android @@ -90,12 +101,46 @@ project.tasks['check'].dependsOn checkStyleMain, checkStyleTest import net.ltgt.gradle.errorprone.CheckSeverity -tasks.withType(JavaCompile) { +tasks.withType(JavaCompile).configureEach { options.compilerArgs += [ - "-Xlint:-cast" + "-Xlint:-cast", ] - // Reuses source code from grpc-interop-testing, which targets Java 7 (no method references) - options.errorprone.check("UnnecessaryAnonymousClass", CheckSeverity.OFF) + appendToProperty(it.options.errorprone.excludedPaths, ".*/R.java", "|") + appendToProperty( + it.options.errorprone.excludedPaths, + ".*/src/generated/.*", + "|") +} + +// Workaround error seen with Gradle 8.14.3 and AGP 7.4.1 when building: +// ./gradlew clean :grpc-android-interop-testing:build -PskipAndroid=false \ +// -Pandroid.useAndroidX=true --no-build-cache +// +// Error message: +// +// Execution failed for task ':grpc-android-interop-testing:mergeExtDexDebug'. +// > Could not resolve all files for configuration ':grpc-android-interop-testing:debugRuntimeClasspath'. +// > Failed to transform opencensus-contrib-grpc-metrics-0.31.1.jar (io.opencensus:opencensus-contrib-grpc-metrics:0.31.1) to match attributes {artifactType=android-dex, asm-transformed-variant=NONE, dexing-enable-desugaring=true, dexing-enable-jacoco-instrumentation=false, dexing-is-debuggable=true, dexing-min-sdk=23, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}. +// > Could not resolve all files for configuration ':grpc-android-interop-testing:debugRuntimeClasspath'. +// > Failed to transform grpc-api-1.81.0-SNAPSHOT.jar (project :grpc-api) to match attributes {artifactType=android-classes-jar, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.jvm.version=8, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}. +// > Execution failed for IdentityTransform: grpc-java/api/build/libs/grpc-api-1.81.0-SNAPSHOT.jar. +// > File/directory does not exist: grpc-java/api/build/libs/grpc-api-1.81.0-SNAPSHOT.jar +tasks.configureEach { task -> + if (task.name.equals("mergeExtDexDebug")) { + dependsOn(':grpc-api:jar') + } +} + +afterEvaluate { + // Hack to workaround "Task ':grpc-android-interop-testing:extractIncludeDebugProto' uses this + // output of task ':grpc-context:jar' without declaring an explicit or implicit dependency." The + // issue started when grpc-context became empty. + tasks.named('extractIncludeDebugProto').configure { + dependsOn project(':grpc-context').tasks.named('jar') + } + tasks.named('extractIncludeReleaseProto').configure { + dependsOn project(':grpc-context').tasks.named('jar') + } } configureProtoCompilation() diff --git a/android-interop-testing/proguard-rules.pro b/android-interop-testing/proguard-rules.pro index 8af80352076..a9e696958b9 100644 --- a/android-interop-testing/proguard-rules.pro +++ b/android-interop-testing/proguard-rules.pro @@ -21,3 +21,7 @@ # Ignores: can't find referenced method from grpc-testing's compileOnly dependency on Truth -dontwarn io.grpc.testing.DeadlineSubject + +-keepclassmembers class io.grpc.testing.integration.Messages$* { + *; +} \ No newline at end of file diff --git a/android-interop-testing/src/androidTest/AndroidManifest.xml b/android-interop-testing/src/androidTest/AndroidManifest.xml index 916a1c04332..3cc0a29a85f 100644 --- a/android-interop-testing/src/androidTest/AndroidManifest.xml +++ b/android-interop-testing/src/androidTest/AndroidManifest.xml @@ -1,13 +1,11 @@ - + - - + diff --git a/android-interop-testing/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java b/android-interop-testing/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java index e6a2c85fda5..a5870063a87 100644 --- a/android-interop-testing/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java +++ b/android-interop-testing/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java @@ -16,21 +16,22 @@ package io.grpc.android.integrationtest; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import android.util.Log; -import androidx.test.InstrumentationRegistry; -import androidx.test.rule.ActivityTestRule; -import androidx.test.runner.AndroidJUnit4; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; import com.google.android.gms.common.GooglePlayServicesNotAvailableException; import com.google.android.gms.common.GooglePlayServicesRepairableException; import com.google.android.gms.security.ProviderInstaller; -import com.google.common.util.concurrent.SettableFuture; -import io.grpc.android.integrationtest.InteropTask.Listener; import java.io.InputStream; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,12 +46,7 @@ public class InteropInstrumentationTest { private String serverHostOverride; private boolean useTestCa; private String testCase; - - // Ensures Looper is initialized for tests running on API level 15. Otherwise instantiating an - // AsyncTask throws an exception. - @Rule - public ActivityTestRule activityRule = - new ActivityTestRule(TesterActivity.class); + private ExecutorService executor = Executors.newSingleThreadExecutor(); @Before public void setUp() throws Exception { @@ -67,7 +63,7 @@ public void setUp() throws Exception { if (useTls) { try { - ProviderInstaller.installIfNeeded(InstrumentationRegistry.getTargetContext()); + ProviderInstaller.installIfNeeded(ApplicationProvider.getApplicationContext()); } catch (GooglePlayServicesRepairableException e) { // The provider is helpful, but it is possible to succeed without it. // Hope that the system-provided libraries are new enough. @@ -108,26 +104,22 @@ public void interopTests() throws Exception { } private void runTest(String testCase) throws Exception { - final SettableFuture resultFuture = SettableFuture.create(); - InteropTask.Listener listener = - new Listener() { - @Override - public void onComplete(String result) { - resultFuture.set(result); - } - }; InputStream testCa; if (useTestCa) { - testCa = InstrumentationRegistry.getTargetContext().getResources().openRawResource(R.raw.ca); + testCa = ApplicationProvider.getApplicationContext().getResources().openRawResource(R.raw.ca); } else { testCa = null; } - new InteropTask( - listener, - TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, useTls, testCa), - testCase) - .execute(); - String result = resultFuture.get(TIMEOUT_SECONDS, TimeUnit.SECONDS); - assertEquals(testCase + " failed", InteropTask.SUCCESS_MESSAGE, result); + + String result = null; + try { + result = executor.submit(new TestCallable( + TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, useTls, testCa), + testCase)).get(TIMEOUT_SECONDS, TimeUnit.SECONDS); + } catch (ExecutionException | InterruptedException | TimeoutException e) { + Log.e(LOG_TAG, "Error while executing test case " + testCase, e); + result = e.getMessage(); + } + assertEquals(testCase + " failed", TestCallable.SUCCESS_MESSAGE, result); } } diff --git a/android-interop-testing/src/androidTest/java/io/grpc/android/integrationtest/UdsChannelInteropTest.java b/android-interop-testing/src/androidTest/java/io/grpc/android/integrationtest/UdsChannelInteropTest.java new file mode 100644 index 00000000000..5b98665ba29 --- /dev/null +++ b/android-interop-testing/src/androidTest/java/io/grpc/android/integrationtest/UdsChannelInteropTest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2021 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.android.integrationtest; + +import static org.junit.Assert.assertEquals; + +import android.net.LocalSocketAddress.Namespace; +import androidx.test.ext.junit.rules.ActivityScenarioRule; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import androidx.test.platform.app.InstrumentationRegistry; +import io.grpc.Grpc; +import io.grpc.InsecureServerCredentials; +import io.grpc.Server; +import io.grpc.android.UdsChannelBuilder; +import io.grpc.testing.integration.TestServiceImpl; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests for channels created with {@link UdsChannelBuilder}. The UDS Channel is only meant to talk + * to Unix Domain Socket endpoints on servers that are on-device, so a {@link LocalTestServer} is + * set up to expose a UDS endpoint. + */ +@RunWith(AndroidJUnit4.class) +public class UdsChannelInteropTest { + private static final int TIMEOUT_SECONDS = 150; + + private static final String UDS_PATH = "udspath"; + private String testCase; + + private Server server; + private UdsTcpEndpointConnector endpointConnector; + + private ScheduledExecutorService serverExecutor = Executors.newScheduledThreadPool(2); + private ExecutorService testExecutor = Executors.newSingleThreadExecutor(); + + // Ensures Looper is initialized for tests running on API level 15. Otherwise instantiating an + // AsyncTask throws an exception. + @Rule + public ActivityScenarioRule activityRule = + new ActivityScenarioRule<>(TesterActivity.class); + + @Before + public void setUp() throws IOException { + testCase = InstrumentationRegistry.getArguments().getString("test_case", "all"); + + // Start local server. + server = + Grpc.newServerBuilderForPort(0, InsecureServerCredentials.create()) + .maxInboundMessageSize(16 * 1024 * 1024) + .addService(new TestServiceImpl(serverExecutor)) + .build(); + server.start(); + + // Connect uds endpoint to server's endpoint. + endpointConnector = new UdsTcpEndpointConnector(UDS_PATH, "0.0.0.0", server.getPort()); + endpointConnector.start(); + } + + @After + public void teardown() { + server.shutdownNow(); + endpointConnector.shutDown(); + } + + @Test + public void interopTests() throws Exception { + if (testCase.equals("all")) { + runTest("empty_unary"); + runTest("large_unary"); + runTest("client_streaming"); + runTest("server_streaming"); + runTest("ping_pong"); + runTest("empty_stream"); + runTest("cancel_after_begin"); + runTest("cancel_after_first_response"); + runTest("full_duplex_call_should_succeed"); + runTest("half_duplex_call_should_succeed"); + runTest("server_streaming_should_be_flow_controlled"); + runTest("very_large_request"); + runTest("very_large_response"); + runTest("deadline_not_exceeded"); + runTest("deadline_exceeded"); + runTest("deadline_exceeded_server_streaming"); + runTest("unimplemented_method"); + runTest("timeout_on_sleeping_server"); + runTest("graceful_shutdown"); + } else { + runTest(testCase); + } + } + + private void runTest(String testCase) throws Exception { + String result = null; + try { + result = testExecutor.submit(new TestCallable( + UdsChannelBuilder.forPath(UDS_PATH, Namespace.ABSTRACT) + .maxInboundMessageSize(16 * 1024 * 1024) + .build(), + testCase)).get(TIMEOUT_SECONDS, TimeUnit.SECONDS); + assertEquals(testCase + " failed", TestCallable.SUCCESS_MESSAGE, result); + } catch (ExecutionException | InterruptedException e) { + result = e.getMessage(); + } + } +} diff --git a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java index 26ac2a72df2..33b914bb4b3 100644 --- a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java +++ b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java @@ -1,33 +1,18 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
  * A service used to obtain stats for verifying LB behavior.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class LoadBalancerStatsServiceGrpc { private LoadBalancerStatsServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor getGetClientStat return getGetClientStatsMethod; } + private static volatile io.grpc.MethodDescriptor getGetClientAccumulatedStatsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetClientAccumulatedStats", + requestType = io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest.class, + responseType = io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetClientAccumulatedStatsMethod() { + io.grpc.MethodDescriptor getGetClientAccumulatedStatsMethod; + if ((getGetClientAccumulatedStatsMethod = LoadBalancerStatsServiceGrpc.getGetClientAccumulatedStatsMethod) == null) { + synchronized (LoadBalancerStatsServiceGrpc.class) { + if ((getGetClientAccumulatedStatsMethod = LoadBalancerStatsServiceGrpc.getGetClientAccumulatedStatsMethod) == null) { + LoadBalancerStatsServiceGrpc.getGetClientAccumulatedStatsMethod = getGetClientAccumulatedStatsMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetClientAccumulatedStats")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse.getDefaultInstance())) + .build(); + } + } + } + return getGetClientAccumulatedStatsMethod; + } + /** * Creates a new async stub that supports all call types for the service */ @@ -74,6 +89,21 @@ public LoadBalancerStatsServiceStub newStub(io.grpc.Channel channel, io.grpc.Cal return LoadBalancerStatsServiceStub.newStub(factory, channel); } + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static LoadBalancerStatsServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public LoadBalancerStatsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions); + } + }; + return LoadBalancerStatsServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -109,37 +139,51 @@ public LoadBalancerStatsServiceFutureStub newStub(io.grpc.Channel channel, io.gr * A service used to obtain stats for verifying LB behavior. * */ - public static abstract class LoadBalancerStatsServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
      * Gets the backend distribution for RPCs sent by a test client.
      * 
*/ - public void getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request, + default void getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getGetClientStatsMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetClientStatsMethod(), responseObserver); } + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + default void getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetClientAccumulatedStatsMethod(), responseObserver); + } + } + + /** + * Base class for the server implementation of the service LoadBalancerStatsService. + *
+   * A service used to obtain stats for verifying LB behavior.
+   * 
+ */ + public static abstract class LoadBalancerStatsServiceImplBase + implements io.grpc.BindableService, AsyncService { + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getGetClientStatsMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.LoadBalancerStatsRequest, - io.grpc.testing.integration.Messages.LoadBalancerStatsResponse>( - this, METHODID_GET_CLIENT_STATS))) - .build(); + return LoadBalancerStatsServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service LoadBalancerStatsService. *
    * A service used to obtain stats for verifying LB behavior.
    * 
*/ - public static final class LoadBalancerStatsServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class LoadBalancerStatsServiceStub + extends io.grpc.stub.AbstractAsyncStub { private LoadBalancerStatsServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -158,17 +202,70 @@ protected LoadBalancerStatsServiceStub build( */ public void getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getGetClientStatsMethod(), getCallOptions()), request, responseObserver); } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public void getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetClientAccumulatedStatsMethod(), getCallOptions()), request, responseObserver); + } } /** + * A stub to allow clients to do synchronous rpc calls to service LoadBalancerStatsService. *
    * A service used to obtain stats for verifying LB behavior.
    * 
*/ - public static final class LoadBalancerStatsServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class LoadBalancerStatsServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private LoadBalancerStatsServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected LoadBalancerStatsServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * Gets the backend distribution for RPCs sent by a test client.
+     * 
+ */ + public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getGetClientStatsMethod(), getCallOptions(), request); + } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service LoadBalancerStatsService. + *
+   * A service used to obtain stats for verifying LB behavior.
+   * 
+ */ + public static final class LoadBalancerStatsServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private LoadBalancerStatsServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -186,17 +283,29 @@ protected LoadBalancerStatsServiceBlockingStub build( * */ public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getGetClientStatsMethod(), getCallOptions(), request); } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request); + } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service LoadBalancerStatsService. *
    * A service used to obtain stats for verifying LB behavior.
    * 
*/ - public static final class LoadBalancerStatsServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class LoadBalancerStatsServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private LoadBalancerStatsServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -215,22 +324,34 @@ protected LoadBalancerStatsServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture getClientStats( io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getGetClientStatsMethod(), getCallOptions()), request); } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture getClientAccumulatedStats( + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetClientAccumulatedStatsMethod(), getCallOptions()), request); + } } private static final int METHODID_GET_CLIENT_STATS = 0; + private static final int METHODID_GET_CLIENT_ACCUMULATED_STATS = 1; private static final class MethodHandlers implements io.grpc.stub.ServerCalls.UnaryMethod, io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final LoadBalancerStatsServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(LoadBalancerStatsServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -243,6 +364,10 @@ public void invoke(Req request, io.grpc.stub.StreamObserver responseObserv serviceImpl.getClientStats((io.grpc.testing.integration.Messages.LoadBalancerStatsRequest) request, (io.grpc.stub.StreamObserver) responseObserver); break; + case METHODID_GET_CLIENT_ACCUMULATED_STATS: + serviceImpl.getClientAccumulatedStats((io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; default: throw new AssertionError(); } @@ -259,6 +384,25 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getGetClientStatsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.LoadBalancerStatsRequest, + io.grpc.testing.integration.Messages.LoadBalancerStatsResponse>( + service, METHODID_GET_CLIENT_STATS))) + .addMethod( + getGetClientAccumulatedStatsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest, + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse>( + service, METHODID_GET_CLIENT_ACCUMULATED_STATS))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { @@ -269,6 +413,7 @@ public static io.grpc.ServiceDescriptor getServiceDescriptor() { if (result == null) { serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) .addMethod(getGetClientStatsMethod()) + .addMethod(getGetClientAccumulatedStatsMethod()) .build(); } } diff --git a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java index 470c3bcee09..c99abcff7cb 100644 --- a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java +++ b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java @@ -1,30 +1,15 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** */ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/metrics.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class MetricsServiceGrpc { private MetricsServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.MetricsService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.MetricsService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public MetricsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new MetricsServiceBlockingV2Stub(channel, callOptions); + } + }; + return MetricsServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -133,7 +133,7 @@ public MetricsServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOpt /** */ - public static abstract class MetricsServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
@@ -141,9 +141,9 @@ public static abstract class MetricsServiceImplBase implements io.grpc.BindableS
      * the service
      * 
*/ - public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request, + default void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getGetAllGaugesMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetAllGaugesMethod(), responseObserver); } /** @@ -151,34 +151,28 @@ public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage reques * Returns the value of one gauge * */ - public void getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request, + default void getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getGetGaugeMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetGaugeMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service MetricsService. + */ + public static abstract class MetricsServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getGetAllGaugesMethod(), - asyncServerStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Metrics.EmptyMessage, - io.grpc.testing.integration.Metrics.GaugeResponse>( - this, METHODID_GET_ALL_GAUGES))) - .addMethod( - getGetGaugeMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Metrics.GaugeRequest, - io.grpc.testing.integration.Metrics.GaugeResponse>( - this, METHODID_GET_GAUGE))) - .build(); + return MetricsServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service MetricsService. */ - public static final class MetricsServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class MetricsServiceStub + extends io.grpc.stub.AbstractAsyncStub { private MetricsServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -198,7 +192,7 @@ protected MetricsServiceStub build( */ public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request, io.grpc.stub.StreamObserver responseObserver) { - asyncServerStreamingCall( + io.grpc.stub.ClientCalls.asyncServerStreamingCall( getChannel().newCall(getGetAllGaugesMethod(), getCallOptions()), request, responseObserver); } @@ -209,14 +203,56 @@ public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage reques */ public void getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getGetGaugeMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service MetricsService. + */ + public static final class MetricsServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private MetricsServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected MetricsServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new MetricsServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * Returns the values of all the gauges that are currently being maintained by
+     * the service
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request) { + return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall( + getChannel(), getGetAllGaugesMethod(), getCallOptions(), request); + } + + /** + *
+     * Returns the value of one gauge
+     * 
+ */ + public io.grpc.testing.integration.Metrics.GaugeResponse getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getGetGaugeMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service MetricsService. */ - public static final class MetricsServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class MetricsServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private MetricsServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -236,7 +272,7 @@ protected MetricsServiceBlockingStub build( */ public java.util.Iterator getAllGauges( io.grpc.testing.integration.Metrics.EmptyMessage request) { - return blockingServerStreamingCall( + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( getChannel(), getGetAllGaugesMethod(), getCallOptions(), request); } @@ -246,14 +282,16 @@ public java.util.Iterator get * */ public io.grpc.testing.integration.Metrics.GaugeResponse getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getGetGaugeMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service MetricsService. */ - public static final class MetricsServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class MetricsServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private MetricsServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -272,7 +310,7 @@ protected MetricsServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture getGauge( io.grpc.testing.integration.Metrics.GaugeRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getGetGaugeMethod(), getCallOptions()), request); } } @@ -285,10 +323,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final MetricsServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(MetricsServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -321,6 +359,25 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getGetAllGaugesMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Metrics.EmptyMessage, + io.grpc.testing.integration.Metrics.GaugeResponse>( + service, METHODID_GET_ALL_GAUGES))) + .addMethod( + getGetGaugeMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Metrics.GaugeRequest, + io.grpc.testing.integration.Metrics.GaugeResponse>( + service, METHODID_GET_GAUGE))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java index 832368c26e0..fffcaad2df2 100644 --- a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java +++ b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java @@ -1,56 +1,41 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
  * A service used to control reconnect server.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class ReconnectServiceGrpc { private ReconnectServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.ReconnectService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.ReconnectService"; // Static method descriptors that strictly reflect the proto. - private static volatile io.grpc.MethodDescriptor getStartMethod; @io.grpc.stub.annotations.RpcMethod( fullMethodName = SERVICE_NAME + '/' + "Start", - requestType = io.grpc.testing.integration.EmptyProtos.Empty.class, + requestType = io.grpc.testing.integration.Messages.ReconnectParams.class, responseType = io.grpc.testing.integration.EmptyProtos.Empty.class, methodType = io.grpc.MethodDescriptor.MethodType.UNARY) - public static io.grpc.MethodDescriptor getStartMethod() { - io.grpc.MethodDescriptor getStartMethod; + io.grpc.MethodDescriptor getStartMethod; if ((getStartMethod = ReconnectServiceGrpc.getStartMethod) == null) { synchronized (ReconnectServiceGrpc.class) { if ((getStartMethod = ReconnectServiceGrpc.getStartMethod) == null) { ReconnectServiceGrpc.getStartMethod = getStartMethod = - io.grpc.MethodDescriptor.newBuilder() + io.grpc.MethodDescriptor.newBuilder() .setType(io.grpc.MethodDescriptor.MethodType.UNARY) .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Start")) .setSampledToLocalTracing(true) .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( - io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + io.grpc.testing.integration.Messages.ReconnectParams.getDefaultInstance())) .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) .build(); @@ -104,6 +89,21 @@ public ReconnectServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions return ReconnectServiceStub.newStub(factory, channel); } + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static ReconnectServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public ReconnectServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new ReconnectServiceBlockingV2Stub(channel, callOptions); + } + }; + return ReconnectServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -139,48 +139,45 @@ public ReconnectServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallO * A service used to control reconnect server. * */ - public static abstract class ReconnectServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** */ - public void start(io.grpc.testing.integration.EmptyProtos.Empty request, + default void start(io.grpc.testing.integration.Messages.ReconnectParams request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getStartMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStartMethod(), responseObserver); } /** */ - public void stop(io.grpc.testing.integration.EmptyProtos.Empty request, + default void stop(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getStopMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStopMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service ReconnectService. + *
+   * A service used to control reconnect server.
+   * 
+ */ + public static abstract class ReconnectServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getStartMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_START))) - .addMethod( - getStopMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.Messages.ReconnectInfo>( - this, METHODID_STOP))) - .build(); + return ReconnectServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service ReconnectService. *
    * A service used to control reconnect server.
    * 
*/ - public static final class ReconnectServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class ReconnectServiceStub + extends io.grpc.stub.AbstractAsyncStub { private ReconnectServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -194,9 +191,9 @@ protected ReconnectServiceStub build( /** */ - public void start(io.grpc.testing.integration.EmptyProtos.Empty request, + public void start(io.grpc.testing.integration.Messages.ReconnectParams request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getStartMethod(), getCallOptions()), request, responseObserver); } @@ -204,17 +201,53 @@ public void start(io.grpc.testing.integration.EmptyProtos.Empty request, */ public void stop(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getStopMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service ReconnectService. *
    * A service used to control reconnect server.
    * 
*/ - public static final class ReconnectServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class ReconnectServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private ReconnectServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected ReconnectServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new ReconnectServiceBlockingV2Stub(channel, callOptions); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getStartMethod(), getCallOptions(), request); + } + + /** + */ + public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getStopMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service ReconnectService. + *
+   * A service used to control reconnect server.
+   * 
+ */ + public static final class ReconnectServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private ReconnectServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -228,25 +261,27 @@ protected ReconnectServiceBlockingStub build( /** */ - public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getStartMethod(), getCallOptions(), request); } /** */ public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getStopMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service ReconnectService. *
    * A service used to control reconnect server.
    * 
*/ - public static final class ReconnectServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class ReconnectServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private ReconnectServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -261,8 +296,8 @@ protected ReconnectServiceFutureStub build( /** */ public com.google.common.util.concurrent.ListenableFuture start( - io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + io.grpc.testing.integration.Messages.ReconnectParams request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getStartMethod(), getCallOptions()), request); } @@ -270,7 +305,7 @@ public com.google.common.util.concurrent.ListenableFuture stop( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getStopMethod(), getCallOptions()), request); } } @@ -283,10 +318,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final ReconnectServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(ReconnectServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -296,7 +331,7 @@ private static final class MethodHandlers implements public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { switch (methodId) { case METHODID_START: - serviceImpl.start((io.grpc.testing.integration.EmptyProtos.Empty) request, + serviceImpl.start((io.grpc.testing.integration.Messages.ReconnectParams) request, (io.grpc.stub.StreamObserver) responseObserver); break; case METHODID_STOP: @@ -319,6 +354,25 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getStartMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.ReconnectParams, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_START))) + .addMethod( + getStopMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.Messages.ReconnectInfo>( + service, METHODID_STOP))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/TestServiceGrpc.java b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/TestServiceGrpc.java index 064eb7f757a..1d7805e3a3f 100644 --- a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/TestServiceGrpc.java +++ b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/TestServiceGrpc.java @@ -1,19 +1,6 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
@@ -21,14 +8,12 @@
  * performance with various types of payload.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class TestServiceGrpc { private TestServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.TestService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.TestService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public TestServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new TestServiceBlockingV2Stub(channel, callOptions); + } + }; + return TestServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -321,16 +321,16 @@ public TestServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOption * performance with various types of payload. * */ - public static abstract class TestServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
      * One empty request followed by one empty response.
      * 
*/ - public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, + default void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getEmptyCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEmptyCallMethod(), responseObserver); } /** @@ -338,9 +338,9 @@ public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, * One request followed by one response. * */ - public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, + default void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getUnaryCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnaryCallMethod(), responseObserver); } /** @@ -350,9 +350,9 @@ public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request * satisfy subsequent requests. * */ - public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, + default void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getCacheableUnaryCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCacheableUnaryCallMethod(), responseObserver); } /** @@ -361,9 +361,9 @@ public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleReques * The server returns the payload with client desired type and sizes. * */ - public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request, + default void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getStreamingOutputCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStreamingOutputCallMethod(), responseObserver); } /** @@ -372,9 +372,9 @@ public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOu * The server returns the aggregated size of client payload as the result. * */ - public io.grpc.stub.StreamObserver streamingInputCall( + default io.grpc.stub.StreamObserver streamingInputCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getStreamingInputCallMethod(), responseObserver); + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getStreamingInputCallMethod(), responseObserver); } /** @@ -384,9 +384,9 @@ public io.grpc.stub.StreamObserver */ - public io.grpc.stub.StreamObserver fullDuplexCall( + default io.grpc.stub.StreamObserver fullDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getFullDuplexCallMethod(), responseObserver); + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getFullDuplexCallMethod(), responseObserver); } /** @@ -397,9 +397,9 @@ public io.grpc.stub.StreamObserver */ - public io.grpc.stub.StreamObserver halfDuplexCall( + default io.grpc.stub.StreamObserver halfDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getHalfDuplexCallMethod(), responseObserver); + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getHalfDuplexCallMethod(), responseObserver); } /** @@ -408,80 +408,36 @@ public io.grpc.stub.StreamObserver */ - public void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, + default void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service TestService. + *
+   * A simple service to test the various types of RPCs and experiment with
+   * performance with various types of payload.
+   * 
+ */ + public static abstract class TestServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getEmptyCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_EMPTY_CALL))) - .addMethod( - getUnaryCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.SimpleRequest, - io.grpc.testing.integration.Messages.SimpleResponse>( - this, METHODID_UNARY_CALL))) - .addMethod( - getCacheableUnaryCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.SimpleRequest, - io.grpc.testing.integration.Messages.SimpleResponse>( - this, METHODID_CACHEABLE_UNARY_CALL))) - .addMethod( - getStreamingOutputCallMethod(), - asyncServerStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingOutputCallRequest, - io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( - this, METHODID_STREAMING_OUTPUT_CALL))) - .addMethod( - getStreamingInputCallMethod(), - asyncClientStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingInputCallRequest, - io.grpc.testing.integration.Messages.StreamingInputCallResponse>( - this, METHODID_STREAMING_INPUT_CALL))) - .addMethod( - getFullDuplexCallMethod(), - asyncBidiStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingOutputCallRequest, - io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( - this, METHODID_FULL_DUPLEX_CALL))) - .addMethod( - getHalfDuplexCallMethod(), - asyncBidiStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingOutputCallRequest, - io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( - this, METHODID_HALF_DUPLEX_CALL))) - .addMethod( - getUnimplementedCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_UNIMPLEMENTED_CALL))) - .build(); + return TestServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service TestService. *
    * A simple service to test the various types of RPCs and experiment with
    * performance with various types of payload.
    * 
*/ - public static final class TestServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class TestServiceStub + extends io.grpc.stub.AbstractAsyncStub { private TestServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -500,7 +456,7 @@ protected TestServiceStub build( */ public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getEmptyCallMethod(), getCallOptions()), request, responseObserver); } @@ -511,7 +467,7 @@ public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, */ public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getUnaryCallMethod(), getCallOptions()), request, responseObserver); } @@ -524,7 +480,7 @@ public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request */ public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getCacheableUnaryCallMethod(), getCallOptions()), request, responseObserver); } @@ -536,7 +492,7 @@ public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleReques */ public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncServerStreamingCall( + io.grpc.stub.ClientCalls.asyncServerStreamingCall( getChannel().newCall(getStreamingOutputCallMethod(), getCallOptions()), request, responseObserver); } @@ -548,7 +504,7 @@ public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOu */ public io.grpc.stub.StreamObserver streamingInputCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncClientStreamingCall( + return io.grpc.stub.ClientCalls.asyncClientStreamingCall( getChannel().newCall(getStreamingInputCallMethod(), getCallOptions()), responseObserver); } @@ -561,7 +517,7 @@ public io.grpc.stub.StreamObserver fullDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncBidiStreamingCall( + return io.grpc.stub.ClientCalls.asyncBidiStreamingCall( getChannel().newCall(getFullDuplexCallMethod(), getCallOptions()), responseObserver); } @@ -575,7 +531,7 @@ public io.grpc.stub.StreamObserver halfDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncBidiStreamingCall( + return io.grpc.stub.ClientCalls.asyncBidiStreamingCall( getChannel().newCall(getHalfDuplexCallMethod(), getCallOptions()), responseObserver); } @@ -587,18 +543,139 @@ public io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service TestService. + *
+   * A simple service to test the various types of RPCs and experiment with
+   * performance with various types of payload.
+   * 
+ */ + public static final class TestServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private TestServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected TestServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new TestServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * One empty request followed by one empty response.
+     * 
+ */ + public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getEmptyCallMethod(), getCallOptions(), request); + } + + /** + *
+     * One request followed by one response.
+     * 
+ */ + public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getUnaryCallMethod(), getCallOptions(), request); + } + + /** + *
+     * One request followed by one response. Response has cache control
+     * headers set such that a caching HTTP proxy (such as GFE) can
+     * satisfy subsequent requests.
+     * 
+ */ + public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getCacheableUnaryCallMethod(), getCallOptions(), request); + } + + /** + *
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) { + return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall( + getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request); + } + + /** + *
+     * A sequence of requests followed by one response (streamed upload).
+     * The server returns the aggregated size of client payload as the result.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + streamingInputCall() { + return io.grpc.stub.ClientCalls.blockingClientStreamingCall( + getChannel(), getStreamingInputCallMethod(), getCallOptions()); + } + + /** + *
+     * A sequence of requests with each request served by the server immediately.
+     * As one request could lead to multiple responses, this interface
+     * demonstrates the idea of full duplexing.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + fullDuplexCall() { + return io.grpc.stub.ClientCalls.blockingBidiStreamingCall( + getChannel(), getFullDuplexCallMethod(), getCallOptions()); + } + + /** + *
+     * A sequence of requests followed by a sequence of responses.
+     * The server buffers all the client requests and then serves them in order. A
+     * stream of responses are returned to the client when the server starts with
+     * first request.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + halfDuplexCall() { + return io.grpc.stub.ClientCalls.blockingBidiStreamingCall( + getChannel(), getHalfDuplexCallMethod(), getCallOptions()); + } + + /** + *
+     * The test server will not implement this method. It will be used
+     * to test the behavior when clients call unimplemented methods.
+     * 
+ */ + public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service TestService. *
    * A simple service to test the various types of RPCs and experiment with
    * performance with various types of payload.
    * 
*/ - public static final class TestServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class TestServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private TestServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -616,7 +693,7 @@ protected TestServiceBlockingStub build( * */ public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getEmptyCallMethod(), getCallOptions(), request); } @@ -626,7 +703,7 @@ public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.i * */ public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getUnaryCallMethod(), getCallOptions(), request); } @@ -638,7 +715,7 @@ public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.tes * */ public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getCacheableUnaryCallMethod(), getCallOptions(), request); } @@ -650,7 +727,7 @@ public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io */ public java.util.Iterator streamingOutputCall( io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) { - return blockingServerStreamingCall( + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request); } @@ -661,18 +738,20 @@ public java.util.Iterator */ public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service TestService. *
    * A simple service to test the various types of RPCs and experiment with
    * performance with various types of payload.
    * 
*/ - public static final class TestServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class TestServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private TestServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -691,7 +770,7 @@ protected TestServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture emptyCall( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getEmptyCallMethod(), getCallOptions()), request); } @@ -702,7 +781,7 @@ public com.google.common.util.concurrent.ListenableFuture unaryCall( io.grpc.testing.integration.Messages.SimpleRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getUnaryCallMethod(), getCallOptions()), request); } @@ -715,7 +794,7 @@ public com.google.common.util.concurrent.ListenableFuture cacheableUnaryCall( io.grpc.testing.integration.Messages.SimpleRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getCacheableUnaryCallMethod(), getCallOptions()), request); } @@ -727,7 +806,7 @@ public com.google.common.util.concurrent.ListenableFuture unimplementedCall( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request); } } @@ -746,10 +825,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final TestServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(TestServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -803,6 +882,67 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getEmptyCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_EMPTY_CALL))) + .addMethod( + getUnaryCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.SimpleRequest, + io.grpc.testing.integration.Messages.SimpleResponse>( + service, METHODID_UNARY_CALL))) + .addMethod( + getCacheableUnaryCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.SimpleRequest, + io.grpc.testing.integration.Messages.SimpleResponse>( + service, METHODID_CACHEABLE_UNARY_CALL))) + .addMethod( + getStreamingOutputCallMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingOutputCallRequest, + io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( + service, METHODID_STREAMING_OUTPUT_CALL))) + .addMethod( + getStreamingInputCallMethod(), + io.grpc.stub.ServerCalls.asyncClientStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingInputCallRequest, + io.grpc.testing.integration.Messages.StreamingInputCallResponse>( + service, METHODID_STREAMING_INPUT_CALL))) + .addMethod( + getFullDuplexCallMethod(), + io.grpc.stub.ServerCalls.asyncBidiStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingOutputCallRequest, + io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( + service, METHODID_FULL_DUPLEX_CALL))) + .addMethod( + getHalfDuplexCallMethod(), + io.grpc.stub.ServerCalls.asyncBidiStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingOutputCallRequest, + io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( + service, METHODID_HALF_DUPLEX_CALL))) + .addMethod( + getUnimplementedCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_UNIMPLEMENTED_CALL))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java index 7bc4e1c5cf6..bec9b5a723a 100644 --- a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java +++ b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java @@ -1,19 +1,6 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
@@ -21,14 +8,12 @@
  * that case.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class UnimplementedServiceGrpc { private UnimplementedServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.UnimplementedService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.UnimplementedService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public UnimplementedServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UnimplementedServiceBlockingV2Stub(channel, callOptions); + } + }; + return UnimplementedServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -111,38 +111,43 @@ public UnimplementedServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.C * that case. * */ - public static abstract class UnimplementedServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
      * A call that no server should implement
      * 
*/ - public void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, + default void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service UnimplementedService. + *
+   * A simple service NOT implemented at servers so clients can test for
+   * that case.
+   * 
+ */ + public static abstract class UnimplementedServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getUnimplementedCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_UNIMPLEMENTED_CALL))) - .build(); + return UnimplementedServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service UnimplementedService. *
    * A simple service NOT implemented at servers so clients can test for
    * that case.
    * 
*/ - public static final class UnimplementedServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class UnimplementedServiceStub + extends io.grpc.stub.AbstractAsyncStub { private UnimplementedServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -161,18 +166,51 @@ protected UnimplementedServiceStub build( */ public void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service UnimplementedService. + *
+   * A simple service NOT implemented at servers so clients can test for
+   * that case.
+   * 
+ */ + public static final class UnimplementedServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private UnimplementedServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected UnimplementedServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UnimplementedServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * A call that no server should implement
+     * 
+ */ + public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service UnimplementedService. *
    * A simple service NOT implemented at servers so clients can test for
    * that case.
    * 
*/ - public static final class UnimplementedServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class UnimplementedServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private UnimplementedServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -190,18 +228,20 @@ protected UnimplementedServiceBlockingStub build( * */ public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service UnimplementedService. *
    * A simple service NOT implemented at servers so clients can test for
    * that case.
    * 
*/ - public static final class UnimplementedServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class UnimplementedServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private UnimplementedServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -220,7 +260,7 @@ protected UnimplementedServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture unimplementedCall( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request); } } @@ -232,10 +272,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final UnimplementedServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(UnimplementedServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -264,6 +304,18 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getUnimplementedCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_UNIMPLEMENTED_CALL))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/XdsUpdateClientConfigureServiceGrpc.java b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/XdsUpdateClientConfigureServiceGrpc.java new file mode 100644 index 00000000000..3453b6c01be --- /dev/null +++ b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/XdsUpdateClientConfigureServiceGrpc.java @@ -0,0 +1,328 @@ +package io.grpc.testing.integration; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + *
+ * A service to dynamically update the configuration of an xDS test client.
+ * 
+ */ +@io.grpc.stub.annotations.GrpcGenerated +public final class XdsUpdateClientConfigureServiceGrpc { + + private XdsUpdateClientConfigureServiceGrpc() {} + + public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getConfigureMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "Configure", + requestType = io.grpc.testing.integration.Messages.ClientConfigureRequest.class, + responseType = io.grpc.testing.integration.Messages.ClientConfigureResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getConfigureMethod() { + io.grpc.MethodDescriptor getConfigureMethod; + if ((getConfigureMethod = XdsUpdateClientConfigureServiceGrpc.getConfigureMethod) == null) { + synchronized (XdsUpdateClientConfigureServiceGrpc.class) { + if ((getConfigureMethod = XdsUpdateClientConfigureServiceGrpc.getConfigureMethod) == null) { + XdsUpdateClientConfigureServiceGrpc.getConfigureMethod = getConfigureMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Configure")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.ClientConfigureRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.ClientConfigureResponse.getDefaultInstance())) + .build(); + } + } + } + return getConfigureMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static XdsUpdateClientConfigureServiceStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceStub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static XdsUpdateClientConfigureServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceBlockingV2Stub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static XdsUpdateClientConfigureServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingStub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static XdsUpdateClientConfigureServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceFutureStub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceFutureStub.newStub(factory, channel); + } + + /** + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public interface AsyncService { + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + default void configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getConfigureMethod(), responseObserver); + } + } + + /** + * Base class for the server implementation of the service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static abstract class XdsUpdateClientConfigureServiceImplBase + implements io.grpc.BindableService, AsyncService { + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return XdsUpdateClientConfigureServiceGrpc.bindService(this); + } + } + + /** + * A stub to allow clients to do asynchronous rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceStub + extends io.grpc.stub.AbstractAsyncStub { + private XdsUpdateClientConfigureServiceStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceStub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public void configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getConfigureMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + * A stub to allow clients to do synchronous rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateClientConfigureServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getConfigureMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateClientConfigureServiceBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingStub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getConfigureMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { + private XdsUpdateClientConfigureServiceFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceFutureStub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture configure( + io.grpc.testing.integration.Messages.ClientConfigureRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getConfigureMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_CONFIGURE = 0; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final AsyncService serviceImpl; + private final int methodId; + + MethodHandlers(AsyncService serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_CONFIGURE: + serviceImpl.configure((io.grpc.testing.integration.Messages.ClientConfigureRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getConfigureMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.ClientConfigureRequest, + io.grpc.testing.integration.Messages.ClientConfigureResponse>( + service, METHODID_CONFIGURE))) + .build(); + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (XdsUpdateClientConfigureServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .addMethod(getConfigureMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/XdsUpdateHealthServiceGrpc.java b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/XdsUpdateHealthServiceGrpc.java new file mode 100644 index 00000000000..fb5f2cdebc7 --- /dev/null +++ b/android-interop-testing/src/generated/debug/grpc/io/grpc/testing/integration/XdsUpdateHealthServiceGrpc.java @@ -0,0 +1,393 @@ +package io.grpc.testing.integration; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + *
+ * A service to remotely control health status of an xDS test server.
+ * 
+ */ +@io.grpc.stub.annotations.GrpcGenerated +public final class XdsUpdateHealthServiceGrpc { + + private XdsUpdateHealthServiceGrpc() {} + + public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getSetServingMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "SetServing", + requestType = io.grpc.testing.integration.EmptyProtos.Empty.class, + responseType = io.grpc.testing.integration.EmptyProtos.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSetServingMethod() { + io.grpc.MethodDescriptor getSetServingMethod; + if ((getSetServingMethod = XdsUpdateHealthServiceGrpc.getSetServingMethod) == null) { + synchronized (XdsUpdateHealthServiceGrpc.class) { + if ((getSetServingMethod = XdsUpdateHealthServiceGrpc.getSetServingMethod) == null) { + XdsUpdateHealthServiceGrpc.getSetServingMethod = getSetServingMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetServing")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .build(); + } + } + } + return getSetServingMethod; + } + + private static volatile io.grpc.MethodDescriptor getSetNotServingMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "SetNotServing", + requestType = io.grpc.testing.integration.EmptyProtos.Empty.class, + responseType = io.grpc.testing.integration.EmptyProtos.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSetNotServingMethod() { + io.grpc.MethodDescriptor getSetNotServingMethod; + if ((getSetNotServingMethod = XdsUpdateHealthServiceGrpc.getSetNotServingMethod) == null) { + synchronized (XdsUpdateHealthServiceGrpc.class) { + if ((getSetNotServingMethod = XdsUpdateHealthServiceGrpc.getSetNotServingMethod) == null) { + XdsUpdateHealthServiceGrpc.getSetNotServingMethod = getSetNotServingMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetNotServing")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .build(); + } + } + } + return getSetNotServingMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static XdsUpdateHealthServiceStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceStub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static XdsUpdateHealthServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceBlockingV2Stub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static XdsUpdateHealthServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingStub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static XdsUpdateHealthServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceFutureStub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceFutureStub.newStub(factory, channel); + } + + /** + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public interface AsyncService { + + /** + */ + default void setServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetServingMethod(), responseObserver); + } + + /** + */ + default void setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetNotServingMethod(), responseObserver); + } + } + + /** + * Base class for the server implementation of the service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static abstract class XdsUpdateHealthServiceImplBase + implements io.grpc.BindableService, AsyncService { + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return XdsUpdateHealthServiceGrpc.bindService(this); + } + } + + /** + * A stub to allow clients to do asynchronous rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceStub + extends io.grpc.stub.AbstractAsyncStub { + private XdsUpdateHealthServiceStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceStub(channel, callOptions); + } + + /** + */ + public void setServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getSetServingMethod(), getCallOptions()), request, responseObserver); + } + + /** + */ + public void setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getSetNotServingMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + * A stub to allow clients to do synchronous rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateHealthServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getSetServingMethod(), getCallOptions(), request); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getSetNotServingMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateHealthServiceBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingStub(channel, callOptions); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getSetServingMethod(), getCallOptions(), request); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getSetNotServingMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { + private XdsUpdateHealthServiceFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceFutureStub(channel, callOptions); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture setServing( + io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getSetServingMethod(), getCallOptions()), request); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture setNotServing( + io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getSetNotServingMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_SET_SERVING = 0; + private static final int METHODID_SET_NOT_SERVING = 1; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final AsyncService serviceImpl; + private final int methodId; + + MethodHandlers(AsyncService serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_SET_SERVING: + serviceImpl.setServing((io.grpc.testing.integration.EmptyProtos.Empty) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_SET_NOT_SERVING: + serviceImpl.setNotServing((io.grpc.testing.integration.EmptyProtos.Empty) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getSetServingMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_SET_SERVING))) + .addMethod( + getSetNotServingMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_SET_NOT_SERVING))) + .build(); + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (XdsUpdateHealthServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .addMethod(getSetServingMethod()) + .addMethod(getSetNotServingMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java index 26ac2a72df2..33b914bb4b3 100644 --- a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java +++ b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/LoadBalancerStatsServiceGrpc.java @@ -1,33 +1,18 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
  * A service used to obtain stats for verifying LB behavior.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class LoadBalancerStatsServiceGrpc { private LoadBalancerStatsServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor getGetClientStat return getGetClientStatsMethod; } + private static volatile io.grpc.MethodDescriptor getGetClientAccumulatedStatsMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "GetClientAccumulatedStats", + requestType = io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest.class, + responseType = io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getGetClientAccumulatedStatsMethod() { + io.grpc.MethodDescriptor getGetClientAccumulatedStatsMethod; + if ((getGetClientAccumulatedStatsMethod = LoadBalancerStatsServiceGrpc.getGetClientAccumulatedStatsMethod) == null) { + synchronized (LoadBalancerStatsServiceGrpc.class) { + if ((getGetClientAccumulatedStatsMethod = LoadBalancerStatsServiceGrpc.getGetClientAccumulatedStatsMethod) == null) { + LoadBalancerStatsServiceGrpc.getGetClientAccumulatedStatsMethod = getGetClientAccumulatedStatsMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetClientAccumulatedStats")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse.getDefaultInstance())) + .build(); + } + } + } + return getGetClientAccumulatedStatsMethod; + } + /** * Creates a new async stub that supports all call types for the service */ @@ -74,6 +89,21 @@ public LoadBalancerStatsServiceStub newStub(io.grpc.Channel channel, io.grpc.Cal return LoadBalancerStatsServiceStub.newStub(factory, channel); } + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static LoadBalancerStatsServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public LoadBalancerStatsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions); + } + }; + return LoadBalancerStatsServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -109,37 +139,51 @@ public LoadBalancerStatsServiceFutureStub newStub(io.grpc.Channel channel, io.gr * A service used to obtain stats for verifying LB behavior. * */ - public static abstract class LoadBalancerStatsServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
      * Gets the backend distribution for RPCs sent by a test client.
      * 
*/ - public void getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request, + default void getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getGetClientStatsMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetClientStatsMethod(), responseObserver); } + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + default void getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetClientAccumulatedStatsMethod(), responseObserver); + } + } + + /** + * Base class for the server implementation of the service LoadBalancerStatsService. + *
+   * A service used to obtain stats for verifying LB behavior.
+   * 
+ */ + public static abstract class LoadBalancerStatsServiceImplBase + implements io.grpc.BindableService, AsyncService { + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getGetClientStatsMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.LoadBalancerStatsRequest, - io.grpc.testing.integration.Messages.LoadBalancerStatsResponse>( - this, METHODID_GET_CLIENT_STATS))) - .build(); + return LoadBalancerStatsServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service LoadBalancerStatsService. *
    * A service used to obtain stats for verifying LB behavior.
    * 
*/ - public static final class LoadBalancerStatsServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class LoadBalancerStatsServiceStub + extends io.grpc.stub.AbstractAsyncStub { private LoadBalancerStatsServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -158,17 +202,70 @@ protected LoadBalancerStatsServiceStub build( */ public void getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getGetClientStatsMethod(), getCallOptions()), request, responseObserver); } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public void getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getGetClientAccumulatedStatsMethod(), getCallOptions()), request, responseObserver); + } } /** + * A stub to allow clients to do synchronous rpc calls to service LoadBalancerStatsService. *
    * A service used to obtain stats for verifying LB behavior.
    * 
*/ - public static final class LoadBalancerStatsServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class LoadBalancerStatsServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private LoadBalancerStatsServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected LoadBalancerStatsServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * Gets the backend distribution for RPCs sent by a test client.
+     * 
+ */ + public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getGetClientStatsMethod(), getCallOptions(), request); + } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service LoadBalancerStatsService. + *
+   * A service used to obtain stats for verifying LB behavior.
+   * 
+ */ + public static final class LoadBalancerStatsServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private LoadBalancerStatsServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -186,17 +283,29 @@ protected LoadBalancerStatsServiceBlockingStub build( * */ public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getGetClientStatsMethod(), getCallOptions(), request); } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request); + } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service LoadBalancerStatsService. *
    * A service used to obtain stats for verifying LB behavior.
    * 
*/ - public static final class LoadBalancerStatsServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class LoadBalancerStatsServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private LoadBalancerStatsServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -215,22 +324,34 @@ protected LoadBalancerStatsServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture getClientStats( io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getGetClientStatsMethod(), getCallOptions()), request); } + + /** + *
+     * Gets the accumulated stats for RPCs sent by a test client.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture getClientAccumulatedStats( + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getGetClientAccumulatedStatsMethod(), getCallOptions()), request); + } } private static final int METHODID_GET_CLIENT_STATS = 0; + private static final int METHODID_GET_CLIENT_ACCUMULATED_STATS = 1; private static final class MethodHandlers implements io.grpc.stub.ServerCalls.UnaryMethod, io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final LoadBalancerStatsServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(LoadBalancerStatsServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -243,6 +364,10 @@ public void invoke(Req request, io.grpc.stub.StreamObserver responseObserv serviceImpl.getClientStats((io.grpc.testing.integration.Messages.LoadBalancerStatsRequest) request, (io.grpc.stub.StreamObserver) responseObserver); break; + case METHODID_GET_CLIENT_ACCUMULATED_STATS: + serviceImpl.getClientAccumulatedStats((io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; default: throw new AssertionError(); } @@ -259,6 +384,25 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getGetClientStatsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.LoadBalancerStatsRequest, + io.grpc.testing.integration.Messages.LoadBalancerStatsResponse>( + service, METHODID_GET_CLIENT_STATS))) + .addMethod( + getGetClientAccumulatedStatsMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest, + io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse>( + service, METHODID_GET_CLIENT_ACCUMULATED_STATS))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { @@ -269,6 +413,7 @@ public static io.grpc.ServiceDescriptor getServiceDescriptor() { if (result == null) { serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) .addMethod(getGetClientStatsMethod()) + .addMethod(getGetClientAccumulatedStatsMethod()) .build(); } } diff --git a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java index 470c3bcee09..c99abcff7cb 100644 --- a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java +++ b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/MetricsServiceGrpc.java @@ -1,30 +1,15 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** */ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/metrics.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class MetricsServiceGrpc { private MetricsServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.MetricsService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.MetricsService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public MetricsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new MetricsServiceBlockingV2Stub(channel, callOptions); + } + }; + return MetricsServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -133,7 +133,7 @@ public MetricsServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOpt /** */ - public static abstract class MetricsServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
@@ -141,9 +141,9 @@ public static abstract class MetricsServiceImplBase implements io.grpc.BindableS
      * the service
      * 
*/ - public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request, + default void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getGetAllGaugesMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetAllGaugesMethod(), responseObserver); } /** @@ -151,34 +151,28 @@ public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage reques * Returns the value of one gauge * */ - public void getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request, + default void getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getGetGaugeMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetGaugeMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service MetricsService. + */ + public static abstract class MetricsServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getGetAllGaugesMethod(), - asyncServerStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Metrics.EmptyMessage, - io.grpc.testing.integration.Metrics.GaugeResponse>( - this, METHODID_GET_ALL_GAUGES))) - .addMethod( - getGetGaugeMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Metrics.GaugeRequest, - io.grpc.testing.integration.Metrics.GaugeResponse>( - this, METHODID_GET_GAUGE))) - .build(); + return MetricsServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service MetricsService. */ - public static final class MetricsServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class MetricsServiceStub + extends io.grpc.stub.AbstractAsyncStub { private MetricsServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -198,7 +192,7 @@ protected MetricsServiceStub build( */ public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request, io.grpc.stub.StreamObserver responseObserver) { - asyncServerStreamingCall( + io.grpc.stub.ClientCalls.asyncServerStreamingCall( getChannel().newCall(getGetAllGaugesMethod(), getCallOptions()), request, responseObserver); } @@ -209,14 +203,56 @@ public void getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage reques */ public void getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getGetGaugeMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service MetricsService. + */ + public static final class MetricsServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private MetricsServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected MetricsServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new MetricsServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * Returns the values of all the gauges that are currently being maintained by
+     * the service
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request) { + return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall( + getChannel(), getGetAllGaugesMethod(), getCallOptions(), request); + } + + /** + *
+     * Returns the value of one gauge
+     * 
+ */ + public io.grpc.testing.integration.Metrics.GaugeResponse getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getGetGaugeMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service MetricsService. */ - public static final class MetricsServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class MetricsServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private MetricsServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -236,7 +272,7 @@ protected MetricsServiceBlockingStub build( */ public java.util.Iterator getAllGauges( io.grpc.testing.integration.Metrics.EmptyMessage request) { - return blockingServerStreamingCall( + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( getChannel(), getGetAllGaugesMethod(), getCallOptions(), request); } @@ -246,14 +282,16 @@ public java.util.Iterator get * */ public io.grpc.testing.integration.Metrics.GaugeResponse getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getGetGaugeMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service MetricsService. */ - public static final class MetricsServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class MetricsServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private MetricsServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -272,7 +310,7 @@ protected MetricsServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture getGauge( io.grpc.testing.integration.Metrics.GaugeRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getGetGaugeMethod(), getCallOptions()), request); } } @@ -285,10 +323,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final MetricsServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(MetricsServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -321,6 +359,25 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getGetAllGaugesMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Metrics.EmptyMessage, + io.grpc.testing.integration.Metrics.GaugeResponse>( + service, METHODID_GET_ALL_GAUGES))) + .addMethod( + getGetGaugeMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Metrics.GaugeRequest, + io.grpc.testing.integration.Metrics.GaugeResponse>( + service, METHODID_GET_GAUGE))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java index 832368c26e0..fffcaad2df2 100644 --- a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java +++ b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/ReconnectServiceGrpc.java @@ -1,56 +1,41 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
  * A service used to control reconnect server.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class ReconnectServiceGrpc { private ReconnectServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.ReconnectService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.ReconnectService"; // Static method descriptors that strictly reflect the proto. - private static volatile io.grpc.MethodDescriptor getStartMethod; @io.grpc.stub.annotations.RpcMethod( fullMethodName = SERVICE_NAME + '/' + "Start", - requestType = io.grpc.testing.integration.EmptyProtos.Empty.class, + requestType = io.grpc.testing.integration.Messages.ReconnectParams.class, responseType = io.grpc.testing.integration.EmptyProtos.Empty.class, methodType = io.grpc.MethodDescriptor.MethodType.UNARY) - public static io.grpc.MethodDescriptor getStartMethod() { - io.grpc.MethodDescriptor getStartMethod; + io.grpc.MethodDescriptor getStartMethod; if ((getStartMethod = ReconnectServiceGrpc.getStartMethod) == null) { synchronized (ReconnectServiceGrpc.class) { if ((getStartMethod = ReconnectServiceGrpc.getStartMethod) == null) { ReconnectServiceGrpc.getStartMethod = getStartMethod = - io.grpc.MethodDescriptor.newBuilder() + io.grpc.MethodDescriptor.newBuilder() .setType(io.grpc.MethodDescriptor.MethodType.UNARY) .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Start")) .setSampledToLocalTracing(true) .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( - io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + io.grpc.testing.integration.Messages.ReconnectParams.getDefaultInstance())) .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) .build(); @@ -104,6 +89,21 @@ public ReconnectServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions return ReconnectServiceStub.newStub(factory, channel); } + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static ReconnectServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public ReconnectServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new ReconnectServiceBlockingV2Stub(channel, callOptions); + } + }; + return ReconnectServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -139,48 +139,45 @@ public ReconnectServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallO * A service used to control reconnect server. * */ - public static abstract class ReconnectServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** */ - public void start(io.grpc.testing.integration.EmptyProtos.Empty request, + default void start(io.grpc.testing.integration.Messages.ReconnectParams request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getStartMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStartMethod(), responseObserver); } /** */ - public void stop(io.grpc.testing.integration.EmptyProtos.Empty request, + default void stop(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getStopMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStopMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service ReconnectService. + *
+   * A service used to control reconnect server.
+   * 
+ */ + public static abstract class ReconnectServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getStartMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_START))) - .addMethod( - getStopMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.Messages.ReconnectInfo>( - this, METHODID_STOP))) - .build(); + return ReconnectServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service ReconnectService. *
    * A service used to control reconnect server.
    * 
*/ - public static final class ReconnectServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class ReconnectServiceStub + extends io.grpc.stub.AbstractAsyncStub { private ReconnectServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -194,9 +191,9 @@ protected ReconnectServiceStub build( /** */ - public void start(io.grpc.testing.integration.EmptyProtos.Empty request, + public void start(io.grpc.testing.integration.Messages.ReconnectParams request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getStartMethod(), getCallOptions()), request, responseObserver); } @@ -204,17 +201,53 @@ public void start(io.grpc.testing.integration.EmptyProtos.Empty request, */ public void stop(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getStopMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service ReconnectService. *
    * A service used to control reconnect server.
    * 
*/ - public static final class ReconnectServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class ReconnectServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private ReconnectServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected ReconnectServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new ReconnectServiceBlockingV2Stub(channel, callOptions); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getStartMethod(), getCallOptions(), request); + } + + /** + */ + public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getStopMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service ReconnectService. + *
+   * A service used to control reconnect server.
+   * 
+ */ + public static final class ReconnectServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private ReconnectServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -228,25 +261,27 @@ protected ReconnectServiceBlockingStub build( /** */ - public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getStartMethod(), getCallOptions(), request); } /** */ public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getStopMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service ReconnectService. *
    * A service used to control reconnect server.
    * 
*/ - public static final class ReconnectServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class ReconnectServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private ReconnectServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -261,8 +296,8 @@ protected ReconnectServiceFutureStub build( /** */ public com.google.common.util.concurrent.ListenableFuture start( - io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + io.grpc.testing.integration.Messages.ReconnectParams request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getStartMethod(), getCallOptions()), request); } @@ -270,7 +305,7 @@ public com.google.common.util.concurrent.ListenableFuture stop( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getStopMethod(), getCallOptions()), request); } } @@ -283,10 +318,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final ReconnectServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(ReconnectServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -296,7 +331,7 @@ private static final class MethodHandlers implements public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { switch (methodId) { case METHODID_START: - serviceImpl.start((io.grpc.testing.integration.EmptyProtos.Empty) request, + serviceImpl.start((io.grpc.testing.integration.Messages.ReconnectParams) request, (io.grpc.stub.StreamObserver) responseObserver); break; case METHODID_STOP: @@ -319,6 +354,25 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getStartMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.ReconnectParams, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_START))) + .addMethod( + getStopMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.Messages.ReconnectInfo>( + service, METHODID_STOP))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/TestServiceGrpc.java b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/TestServiceGrpc.java index 064eb7f757a..1d7805e3a3f 100644 --- a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/TestServiceGrpc.java +++ b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/TestServiceGrpc.java @@ -1,19 +1,6 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
@@ -21,14 +8,12 @@
  * performance with various types of payload.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class TestServiceGrpc { private TestServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.TestService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.TestService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public TestServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new TestServiceBlockingV2Stub(channel, callOptions); + } + }; + return TestServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -321,16 +321,16 @@ public TestServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOption * performance with various types of payload. * */ - public static abstract class TestServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
      * One empty request followed by one empty response.
      * 
*/ - public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, + default void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getEmptyCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getEmptyCallMethod(), responseObserver); } /** @@ -338,9 +338,9 @@ public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, * One request followed by one response. * */ - public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, + default void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getUnaryCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnaryCallMethod(), responseObserver); } /** @@ -350,9 +350,9 @@ public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request * satisfy subsequent requests. * */ - public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, + default void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getCacheableUnaryCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCacheableUnaryCallMethod(), responseObserver); } /** @@ -361,9 +361,9 @@ public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleReques * The server returns the payload with client desired type and sizes. * */ - public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request, + default void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getStreamingOutputCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getStreamingOutputCallMethod(), responseObserver); } /** @@ -372,9 +372,9 @@ public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOu * The server returns the aggregated size of client payload as the result. * */ - public io.grpc.stub.StreamObserver streamingInputCall( + default io.grpc.stub.StreamObserver streamingInputCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getStreamingInputCallMethod(), responseObserver); + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getStreamingInputCallMethod(), responseObserver); } /** @@ -384,9 +384,9 @@ public io.grpc.stub.StreamObserver */ - public io.grpc.stub.StreamObserver fullDuplexCall( + default io.grpc.stub.StreamObserver fullDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getFullDuplexCallMethod(), responseObserver); + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getFullDuplexCallMethod(), responseObserver); } /** @@ -397,9 +397,9 @@ public io.grpc.stub.StreamObserver */ - public io.grpc.stub.StreamObserver halfDuplexCall( + default io.grpc.stub.StreamObserver halfDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncUnimplementedStreamingCall(getHalfDuplexCallMethod(), responseObserver); + return io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall(getHalfDuplexCallMethod(), responseObserver); } /** @@ -408,80 +408,36 @@ public io.grpc.stub.StreamObserver */ - public void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, + default void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service TestService. + *
+   * A simple service to test the various types of RPCs and experiment with
+   * performance with various types of payload.
+   * 
+ */ + public static abstract class TestServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getEmptyCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_EMPTY_CALL))) - .addMethod( - getUnaryCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.SimpleRequest, - io.grpc.testing.integration.Messages.SimpleResponse>( - this, METHODID_UNARY_CALL))) - .addMethod( - getCacheableUnaryCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.SimpleRequest, - io.grpc.testing.integration.Messages.SimpleResponse>( - this, METHODID_CACHEABLE_UNARY_CALL))) - .addMethod( - getStreamingOutputCallMethod(), - asyncServerStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingOutputCallRequest, - io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( - this, METHODID_STREAMING_OUTPUT_CALL))) - .addMethod( - getStreamingInputCallMethod(), - asyncClientStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingInputCallRequest, - io.grpc.testing.integration.Messages.StreamingInputCallResponse>( - this, METHODID_STREAMING_INPUT_CALL))) - .addMethod( - getFullDuplexCallMethod(), - asyncBidiStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingOutputCallRequest, - io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( - this, METHODID_FULL_DUPLEX_CALL))) - .addMethod( - getHalfDuplexCallMethod(), - asyncBidiStreamingCall( - new MethodHandlers< - io.grpc.testing.integration.Messages.StreamingOutputCallRequest, - io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( - this, METHODID_HALF_DUPLEX_CALL))) - .addMethod( - getUnimplementedCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_UNIMPLEMENTED_CALL))) - .build(); + return TestServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service TestService. *
    * A simple service to test the various types of RPCs and experiment with
    * performance with various types of payload.
    * 
*/ - public static final class TestServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class TestServiceStub + extends io.grpc.stub.AbstractAsyncStub { private TestServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -500,7 +456,7 @@ protected TestServiceStub build( */ public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getEmptyCallMethod(), getCallOptions()), request, responseObserver); } @@ -511,7 +467,7 @@ public void emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request, */ public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getUnaryCallMethod(), getCallOptions()), request, responseObserver); } @@ -524,7 +480,7 @@ public void unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request */ public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getCacheableUnaryCallMethod(), getCallOptions()), request, responseObserver); } @@ -536,7 +492,7 @@ public void cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleReques */ public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request, io.grpc.stub.StreamObserver responseObserver) { - asyncServerStreamingCall( + io.grpc.stub.ClientCalls.asyncServerStreamingCall( getChannel().newCall(getStreamingOutputCallMethod(), getCallOptions()), request, responseObserver); } @@ -548,7 +504,7 @@ public void streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOu */ public io.grpc.stub.StreamObserver streamingInputCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncClientStreamingCall( + return io.grpc.stub.ClientCalls.asyncClientStreamingCall( getChannel().newCall(getStreamingInputCallMethod(), getCallOptions()), responseObserver); } @@ -561,7 +517,7 @@ public io.grpc.stub.StreamObserver fullDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncBidiStreamingCall( + return io.grpc.stub.ClientCalls.asyncBidiStreamingCall( getChannel().newCall(getFullDuplexCallMethod(), getCallOptions()), responseObserver); } @@ -575,7 +531,7 @@ public io.grpc.stub.StreamObserver halfDuplexCall( io.grpc.stub.StreamObserver responseObserver) { - return asyncBidiStreamingCall( + return io.grpc.stub.ClientCalls.asyncBidiStreamingCall( getChannel().newCall(getHalfDuplexCallMethod(), getCallOptions()), responseObserver); } @@ -587,18 +543,139 @@ public io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service TestService. + *
+   * A simple service to test the various types of RPCs and experiment with
+   * performance with various types of payload.
+   * 
+ */ + public static final class TestServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private TestServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected TestServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new TestServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * One empty request followed by one empty response.
+     * 
+ */ + public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getEmptyCallMethod(), getCallOptions(), request); + } + + /** + *
+     * One request followed by one response.
+     * 
+ */ + public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getUnaryCallMethod(), getCallOptions(), request); + } + + /** + *
+     * One request followed by one response. Response has cache control
+     * headers set such that a caching HTTP proxy (such as GFE) can
+     * satisfy subsequent requests.
+     * 
+ */ + public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getCacheableUnaryCallMethod(), getCallOptions(), request); + } + + /** + *
+     * One request followed by a sequence of responses (streamed download).
+     * The server returns the payload with client desired type and sizes.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) { + return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall( + getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request); + } + + /** + *
+     * A sequence of requests followed by one response (streamed upload).
+     * The server returns the aggregated size of client payload as the result.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + streamingInputCall() { + return io.grpc.stub.ClientCalls.blockingClientStreamingCall( + getChannel(), getStreamingInputCallMethod(), getCallOptions()); + } + + /** + *
+     * A sequence of requests with each request served by the server immediately.
+     * As one request could lead to multiple responses, this interface
+     * demonstrates the idea of full duplexing.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + fullDuplexCall() { + return io.grpc.stub.ClientCalls.blockingBidiStreamingCall( + getChannel(), getFullDuplexCallMethod(), getCallOptions()); + } + + /** + *
+     * A sequence of requests followed by a sequence of responses.
+     * The server buffers all the client requests and then serves them in order. A
+     * stream of responses are returned to the client when the server starts with
+     * first request.
+     * 
+ */ + @io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918") + public io.grpc.stub.BlockingClientCall + halfDuplexCall() { + return io.grpc.stub.ClientCalls.blockingBidiStreamingCall( + getChannel(), getHalfDuplexCallMethod(), getCallOptions()); + } + + /** + *
+     * The test server will not implement this method. It will be used
+     * to test the behavior when clients call unimplemented methods.
+     * 
+ */ + public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service TestService. *
    * A simple service to test the various types of RPCs and experiment with
    * performance with various types of payload.
    * 
*/ - public static final class TestServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class TestServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private TestServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -616,7 +693,7 @@ protected TestServiceBlockingStub build( * */ public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getEmptyCallMethod(), getCallOptions(), request); } @@ -626,7 +703,7 @@ public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.i * */ public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getUnaryCallMethod(), getCallOptions(), request); } @@ -638,7 +715,7 @@ public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.tes * */ public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getCacheableUnaryCallMethod(), getCallOptions(), request); } @@ -650,7 +727,7 @@ public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io */ public java.util.Iterator streamingOutputCall( io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) { - return blockingServerStreamingCall( + return io.grpc.stub.ClientCalls.blockingServerStreamingCall( getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request); } @@ -661,18 +738,20 @@ public java.util.Iterator */ public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service TestService. *
    * A simple service to test the various types of RPCs and experiment with
    * performance with various types of payload.
    * 
*/ - public static final class TestServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class TestServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private TestServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -691,7 +770,7 @@ protected TestServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture emptyCall( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getEmptyCallMethod(), getCallOptions()), request); } @@ -702,7 +781,7 @@ public com.google.common.util.concurrent.ListenableFuture unaryCall( io.grpc.testing.integration.Messages.SimpleRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getUnaryCallMethod(), getCallOptions()), request); } @@ -715,7 +794,7 @@ public com.google.common.util.concurrent.ListenableFuture cacheableUnaryCall( io.grpc.testing.integration.Messages.SimpleRequest request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getCacheableUnaryCallMethod(), getCallOptions()), request); } @@ -727,7 +806,7 @@ public com.google.common.util.concurrent.ListenableFuture unimplementedCall( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request); } } @@ -746,10 +825,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final TestServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(TestServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -803,6 +882,67 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getEmptyCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_EMPTY_CALL))) + .addMethod( + getUnaryCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.SimpleRequest, + io.grpc.testing.integration.Messages.SimpleResponse>( + service, METHODID_UNARY_CALL))) + .addMethod( + getCacheableUnaryCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.SimpleRequest, + io.grpc.testing.integration.Messages.SimpleResponse>( + service, METHODID_CACHEABLE_UNARY_CALL))) + .addMethod( + getStreamingOutputCallMethod(), + io.grpc.stub.ServerCalls.asyncServerStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingOutputCallRequest, + io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( + service, METHODID_STREAMING_OUTPUT_CALL))) + .addMethod( + getStreamingInputCallMethod(), + io.grpc.stub.ServerCalls.asyncClientStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingInputCallRequest, + io.grpc.testing.integration.Messages.StreamingInputCallResponse>( + service, METHODID_STREAMING_INPUT_CALL))) + .addMethod( + getFullDuplexCallMethod(), + io.grpc.stub.ServerCalls.asyncBidiStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingOutputCallRequest, + io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( + service, METHODID_FULL_DUPLEX_CALL))) + .addMethod( + getHalfDuplexCallMethod(), + io.grpc.stub.ServerCalls.asyncBidiStreamingCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.StreamingOutputCallRequest, + io.grpc.testing.integration.Messages.StreamingOutputCallResponse>( + service, METHODID_HALF_DUPLEX_CALL))) + .addMethod( + getUnimplementedCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_UNIMPLEMENTED_CALL))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java index 7bc4e1c5cf6..bec9b5a723a 100644 --- a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java +++ b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/UnimplementedServiceGrpc.java @@ -1,19 +1,6 @@ package io.grpc.testing.integration; import static io.grpc.MethodDescriptor.generateFullMethodName; -import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; -import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; -import static io.grpc.stub.ClientCalls.asyncUnaryCall; -import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; -import static io.grpc.stub.ClientCalls.blockingUnaryCall; -import static io.grpc.stub.ClientCalls.futureUnaryCall; -import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall; -import static io.grpc.stub.ServerCalls.asyncClientStreamingCall; -import static io.grpc.stub.ServerCalls.asyncServerStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnaryCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall; -import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall; /** *
@@ -21,14 +8,12 @@
  * that case.
  * 
*/ -@javax.annotation.Generated( - value = "by gRPC proto compiler", - comments = "Source: grpc/testing/test.proto") +@io.grpc.stub.annotations.GrpcGenerated public final class UnimplementedServiceGrpc { private UnimplementedServiceGrpc() {} - public static final String SERVICE_NAME = "grpc.testing.UnimplementedService"; + public static final java.lang.String SERVICE_NAME = "grpc.testing.UnimplementedService"; // Static method descriptors that strictly reflect the proto. private static volatile io.grpc.MethodDescriptor factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public UnimplementedServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UnimplementedServiceBlockingV2Stub(channel, callOptions); + } + }; + return UnimplementedServiceBlockingV2Stub.newStub(factory, channel); + } + /** * Creates a new blocking-style stub that supports unary and streaming output calls on the service */ @@ -111,38 +111,43 @@ public UnimplementedServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.C * that case. * */ - public static abstract class UnimplementedServiceImplBase implements io.grpc.BindableService { + public interface AsyncService { /** *
      * A call that no server should implement
      * 
*/ - public void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, + default void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUnimplementedCallMethod(), responseObserver); } + } + + /** + * Base class for the server implementation of the service UnimplementedService. + *
+   * A simple service NOT implemented at servers so clients can test for
+   * that case.
+   * 
+ */ + public static abstract class UnimplementedServiceImplBase + implements io.grpc.BindableService, AsyncService { @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { - return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) - .addMethod( - getUnimplementedCallMethod(), - asyncUnaryCall( - new MethodHandlers< - io.grpc.testing.integration.EmptyProtos.Empty, - io.grpc.testing.integration.EmptyProtos.Empty>( - this, METHODID_UNIMPLEMENTED_CALL))) - .build(); + return UnimplementedServiceGrpc.bindService(this); } } /** + * A stub to allow clients to do asynchronous rpc calls to service UnimplementedService. *
    * A simple service NOT implemented at servers so clients can test for
    * that case.
    * 
*/ - public static final class UnimplementedServiceStub extends io.grpc.stub.AbstractAsyncStub { + public static final class UnimplementedServiceStub + extends io.grpc.stub.AbstractAsyncStub { private UnimplementedServiceStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -161,18 +166,51 @@ protected UnimplementedServiceStub build( */ public void unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request, io.grpc.stub.StreamObserver responseObserver) { - asyncUnaryCall( + io.grpc.stub.ClientCalls.asyncUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request, responseObserver); } } /** + * A stub to allow clients to do synchronous rpc calls to service UnimplementedService. + *
+   * A simple service NOT implemented at servers so clients can test for
+   * that case.
+   * 
+ */ + public static final class UnimplementedServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private UnimplementedServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected UnimplementedServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new UnimplementedServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * A call that no server should implement
+     * 
+ */ + public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service UnimplementedService. *
    * A simple service NOT implemented at servers so clients can test for
    * that case.
    * 
*/ - public static final class UnimplementedServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub { + public static final class UnimplementedServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { private UnimplementedServiceBlockingStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -190,18 +228,20 @@ protected UnimplementedServiceBlockingStub build( * */ public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) { - return blockingUnaryCall( + return io.grpc.stub.ClientCalls.blockingUnaryCall( getChannel(), getUnimplementedCallMethod(), getCallOptions(), request); } } /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service UnimplementedService. *
    * A simple service NOT implemented at servers so clients can test for
    * that case.
    * 
*/ - public static final class UnimplementedServiceFutureStub extends io.grpc.stub.AbstractFutureStub { + public static final class UnimplementedServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { private UnimplementedServiceFutureStub( io.grpc.Channel channel, io.grpc.CallOptions callOptions) { super(channel, callOptions); @@ -220,7 +260,7 @@ protected UnimplementedServiceFutureStub build( */ public com.google.common.util.concurrent.ListenableFuture unimplementedCall( io.grpc.testing.integration.EmptyProtos.Empty request) { - return futureUnaryCall( + return io.grpc.stub.ClientCalls.futureUnaryCall( getChannel().newCall(getUnimplementedCallMethod(), getCallOptions()), request); } } @@ -232,10 +272,10 @@ private static final class MethodHandlers implements io.grpc.stub.ServerCalls.ServerStreamingMethod, io.grpc.stub.ServerCalls.ClientStreamingMethod, io.grpc.stub.ServerCalls.BidiStreamingMethod { - private final UnimplementedServiceImplBase serviceImpl; + private final AsyncService serviceImpl; private final int methodId; - MethodHandlers(UnimplementedServiceImplBase serviceImpl, int methodId) { + MethodHandlers(AsyncService serviceImpl, int methodId) { this.serviceImpl = serviceImpl; this.methodId = methodId; } @@ -264,6 +304,18 @@ public io.grpc.stub.StreamObserver invoke( } } + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getUnimplementedCallMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_UNIMPLEMENTED_CALL))) + .build(); + } + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; public static io.grpc.ServiceDescriptor getServiceDescriptor() { diff --git a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/XdsUpdateClientConfigureServiceGrpc.java b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/XdsUpdateClientConfigureServiceGrpc.java new file mode 100644 index 00000000000..3453b6c01be --- /dev/null +++ b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/XdsUpdateClientConfigureServiceGrpc.java @@ -0,0 +1,328 @@ +package io.grpc.testing.integration; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + *
+ * A service to dynamically update the configuration of an xDS test client.
+ * 
+ */ +@io.grpc.stub.annotations.GrpcGenerated +public final class XdsUpdateClientConfigureServiceGrpc { + + private XdsUpdateClientConfigureServiceGrpc() {} + + public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getConfigureMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "Configure", + requestType = io.grpc.testing.integration.Messages.ClientConfigureRequest.class, + responseType = io.grpc.testing.integration.Messages.ClientConfigureResponse.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getConfigureMethod() { + io.grpc.MethodDescriptor getConfigureMethod; + if ((getConfigureMethod = XdsUpdateClientConfigureServiceGrpc.getConfigureMethod) == null) { + synchronized (XdsUpdateClientConfigureServiceGrpc.class) { + if ((getConfigureMethod = XdsUpdateClientConfigureServiceGrpc.getConfigureMethod) == null) { + XdsUpdateClientConfigureServiceGrpc.getConfigureMethod = getConfigureMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "Configure")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.ClientConfigureRequest.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.Messages.ClientConfigureResponse.getDefaultInstance())) + .build(); + } + } + } + return getConfigureMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static XdsUpdateClientConfigureServiceStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceStub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static XdsUpdateClientConfigureServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceBlockingV2Stub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static XdsUpdateClientConfigureServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingStub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static XdsUpdateClientConfigureServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateClientConfigureServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceFutureStub(channel, callOptions); + } + }; + return XdsUpdateClientConfigureServiceFutureStub.newStub(factory, channel); + } + + /** + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public interface AsyncService { + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + default void configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getConfigureMethod(), responseObserver); + } + } + + /** + * Base class for the server implementation of the service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static abstract class XdsUpdateClientConfigureServiceImplBase + implements io.grpc.BindableService, AsyncService { + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return XdsUpdateClientConfigureServiceGrpc.bindService(this); + } + } + + /** + * A stub to allow clients to do asynchronous rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceStub + extends io.grpc.stub.AbstractAsyncStub { + private XdsUpdateClientConfigureServiceStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceStub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public void configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getConfigureMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + * A stub to allow clients to do synchronous rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateClientConfigureServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getConfigureMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateClientConfigureServiceBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceBlockingStub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getConfigureMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service XdsUpdateClientConfigureService. + *
+   * A service to dynamically update the configuration of an xDS test client.
+   * 
+ */ + public static final class XdsUpdateClientConfigureServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { + private XdsUpdateClientConfigureServiceFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateClientConfigureServiceFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateClientConfigureServiceFutureStub(channel, callOptions); + } + + /** + *
+     * Update the tes client's configuration.
+     * 
+ */ + public com.google.common.util.concurrent.ListenableFuture configure( + io.grpc.testing.integration.Messages.ClientConfigureRequest request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getConfigureMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_CONFIGURE = 0; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final AsyncService serviceImpl; + private final int methodId; + + MethodHandlers(AsyncService serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_CONFIGURE: + serviceImpl.configure((io.grpc.testing.integration.Messages.ClientConfigureRequest) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getConfigureMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.Messages.ClientConfigureRequest, + io.grpc.testing.integration.Messages.ClientConfigureResponse>( + service, METHODID_CONFIGURE))) + .build(); + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (XdsUpdateClientConfigureServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .addMethod(getConfigureMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/XdsUpdateHealthServiceGrpc.java b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/XdsUpdateHealthServiceGrpc.java new file mode 100644 index 00000000000..fb5f2cdebc7 --- /dev/null +++ b/android-interop-testing/src/generated/release/grpc/io/grpc/testing/integration/XdsUpdateHealthServiceGrpc.java @@ -0,0 +1,393 @@ +package io.grpc.testing.integration; + +import static io.grpc.MethodDescriptor.generateFullMethodName; + +/** + *
+ * A service to remotely control health status of an xDS test server.
+ * 
+ */ +@io.grpc.stub.annotations.GrpcGenerated +public final class XdsUpdateHealthServiceGrpc { + + private XdsUpdateHealthServiceGrpc() {} + + public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService"; + + // Static method descriptors that strictly reflect the proto. + private static volatile io.grpc.MethodDescriptor getSetServingMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "SetServing", + requestType = io.grpc.testing.integration.EmptyProtos.Empty.class, + responseType = io.grpc.testing.integration.EmptyProtos.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSetServingMethod() { + io.grpc.MethodDescriptor getSetServingMethod; + if ((getSetServingMethod = XdsUpdateHealthServiceGrpc.getSetServingMethod) == null) { + synchronized (XdsUpdateHealthServiceGrpc.class) { + if ((getSetServingMethod = XdsUpdateHealthServiceGrpc.getSetServingMethod) == null) { + XdsUpdateHealthServiceGrpc.getSetServingMethod = getSetServingMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetServing")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .build(); + } + } + } + return getSetServingMethod; + } + + private static volatile io.grpc.MethodDescriptor getSetNotServingMethod; + + @io.grpc.stub.annotations.RpcMethod( + fullMethodName = SERVICE_NAME + '/' + "SetNotServing", + requestType = io.grpc.testing.integration.EmptyProtos.Empty.class, + responseType = io.grpc.testing.integration.EmptyProtos.Empty.class, + methodType = io.grpc.MethodDescriptor.MethodType.UNARY) + public static io.grpc.MethodDescriptor getSetNotServingMethod() { + io.grpc.MethodDescriptor getSetNotServingMethod; + if ((getSetNotServingMethod = XdsUpdateHealthServiceGrpc.getSetNotServingMethod) == null) { + synchronized (XdsUpdateHealthServiceGrpc.class) { + if ((getSetNotServingMethod = XdsUpdateHealthServiceGrpc.getSetNotServingMethod) == null) { + XdsUpdateHealthServiceGrpc.getSetNotServingMethod = getSetNotServingMethod = + io.grpc.MethodDescriptor.newBuilder() + .setType(io.grpc.MethodDescriptor.MethodType.UNARY) + .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetNotServing")) + .setSampledToLocalTracing(true) + .setRequestMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .setResponseMarshaller(io.grpc.protobuf.lite.ProtoLiteUtils.marshaller( + io.grpc.testing.integration.EmptyProtos.Empty.getDefaultInstance())) + .build(); + } + } + } + return getSetNotServingMethod; + } + + /** + * Creates a new async stub that supports all call types for the service + */ + public static XdsUpdateHealthServiceStub newStub(io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceStub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceStub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports all types of calls on the service + */ + public static XdsUpdateHealthServiceBlockingV2Stub newBlockingV2Stub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceBlockingV2Stub.newStub(factory, channel); + } + + /** + * Creates a new blocking-style stub that supports unary and streaming output calls on the service + */ + public static XdsUpdateHealthServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingStub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceBlockingStub.newStub(factory, channel); + } + + /** + * Creates a new ListenableFuture-style stub that supports unary calls on the service + */ + public static XdsUpdateHealthServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + io.grpc.stub.AbstractStub.StubFactory factory = + new io.grpc.stub.AbstractStub.StubFactory() { + @java.lang.Override + public XdsUpdateHealthServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceFutureStub(channel, callOptions); + } + }; + return XdsUpdateHealthServiceFutureStub.newStub(factory, channel); + } + + /** + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public interface AsyncService { + + /** + */ + default void setServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetServingMethod(), responseObserver); + } + + /** + */ + default void setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetNotServingMethod(), responseObserver); + } + } + + /** + * Base class for the server implementation of the service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static abstract class XdsUpdateHealthServiceImplBase + implements io.grpc.BindableService, AsyncService { + + @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() { + return XdsUpdateHealthServiceGrpc.bindService(this); + } + } + + /** + * A stub to allow clients to do asynchronous rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceStub + extends io.grpc.stub.AbstractAsyncStub { + private XdsUpdateHealthServiceStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceStub(channel, callOptions); + } + + /** + */ + public void setServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getSetServingMethod(), getCallOptions()), request, responseObserver); + } + + /** + */ + public void setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + io.grpc.stub.ClientCalls.asyncUnaryCall( + getChannel().newCall(getSetNotServingMethod(), getCallOptions()), request, responseObserver); + } + } + + /** + * A stub to allow clients to do synchronous rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceBlockingV2Stub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateHealthServiceBlockingV2Stub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceBlockingV2Stub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getSetServingMethod(), getCallOptions(), request); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException { + return io.grpc.stub.ClientCalls.blockingV2UnaryCall( + getChannel(), getSetNotServingMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceBlockingStub + extends io.grpc.stub.AbstractBlockingStub { + private XdsUpdateHealthServiceBlockingStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceBlockingStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceBlockingStub(channel, callOptions); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getSetServingMethod(), getCallOptions(), request); + } + + /** + */ + public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.blockingUnaryCall( + getChannel(), getSetNotServingMethod(), getCallOptions(), request); + } + } + + /** + * A stub to allow clients to do ListenableFuture-style rpc calls to service XdsUpdateHealthService. + *
+   * A service to remotely control health status of an xDS test server.
+   * 
+ */ + public static final class XdsUpdateHealthServiceFutureStub + extends io.grpc.stub.AbstractFutureStub { + private XdsUpdateHealthServiceFutureStub( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + super(channel, callOptions); + } + + @java.lang.Override + protected XdsUpdateHealthServiceFutureStub build( + io.grpc.Channel channel, io.grpc.CallOptions callOptions) { + return new XdsUpdateHealthServiceFutureStub(channel, callOptions); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture setServing( + io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getSetServingMethod(), getCallOptions()), request); + } + + /** + */ + public com.google.common.util.concurrent.ListenableFuture setNotServing( + io.grpc.testing.integration.EmptyProtos.Empty request) { + return io.grpc.stub.ClientCalls.futureUnaryCall( + getChannel().newCall(getSetNotServingMethod(), getCallOptions()), request); + } + } + + private static final int METHODID_SET_SERVING = 0; + private static final int METHODID_SET_NOT_SERVING = 1; + + private static final class MethodHandlers implements + io.grpc.stub.ServerCalls.UnaryMethod, + io.grpc.stub.ServerCalls.ServerStreamingMethod, + io.grpc.stub.ServerCalls.ClientStreamingMethod, + io.grpc.stub.ServerCalls.BidiStreamingMethod { + private final AsyncService serviceImpl; + private final int methodId; + + MethodHandlers(AsyncService serviceImpl, int methodId) { + this.serviceImpl = serviceImpl; + this.methodId = methodId; + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public void invoke(Req request, io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + case METHODID_SET_SERVING: + serviceImpl.setServing((io.grpc.testing.integration.EmptyProtos.Empty) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + case METHODID_SET_NOT_SERVING: + serviceImpl.setNotServing((io.grpc.testing.integration.EmptyProtos.Empty) request, + (io.grpc.stub.StreamObserver) responseObserver); + break; + default: + throw new AssertionError(); + } + } + + @java.lang.Override + @java.lang.SuppressWarnings("unchecked") + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + switch (methodId) { + default: + throw new AssertionError(); + } + } + } + + public static final io.grpc.ServerServiceDefinition bindService(AsyncService service) { + return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor()) + .addMethod( + getSetServingMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_SET_SERVING))) + .addMethod( + getSetNotServingMethod(), + io.grpc.stub.ServerCalls.asyncUnaryCall( + new MethodHandlers< + io.grpc.testing.integration.EmptyProtos.Empty, + io.grpc.testing.integration.EmptyProtos.Empty>( + service, METHODID_SET_NOT_SERVING))) + .build(); + } + + private static volatile io.grpc.ServiceDescriptor serviceDescriptor; + + public static io.grpc.ServiceDescriptor getServiceDescriptor() { + io.grpc.ServiceDescriptor result = serviceDescriptor; + if (result == null) { + synchronized (XdsUpdateHealthServiceGrpc.class) { + result = serviceDescriptor; + if (result == null) { + serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME) + .addMethod(getSetServingMethod()) + .addMethod(getSetNotServingMethod()) + .build(); + } + } + } + return result; + } +} diff --git a/android-interop-testing/src/main/AndroidManifest.xml b/android-interop-testing/src/main/AndroidManifest.xml index c3f35131ad4..08c139e5880 100644 --- a/android-interop-testing/src/main/AndroidManifest.xml +++ b/android-interop-testing/src/main/AndroidManifest.xml @@ -1,24 +1,32 @@ + xmlns:tools="http://schemas.android.com/tools"> + + + + + android:theme="@style/Base.V7.Theme.AppCompat.Light"> + android:exported="true"> + + + diff --git a/android-interop-testing/src/main/java/io/grpc/android/integrationtest/InteropTask.java b/android-interop-testing/src/main/java/io/grpc/android/integrationtest/InteropTask.java deleted file mode 100644 index 8beaea3ec9c..00000000000 --- a/android-interop-testing/src/main/java/io/grpc/android/integrationtest/InteropTask.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2018 The gRPC Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.grpc.android.integrationtest; - -import android.os.AsyncTask; -import android.util.Log; -import io.grpc.ManagedChannel; -import io.grpc.ManagedChannelBuilder; -import io.grpc.testing.integration.AbstractInteropTest; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.ref.WeakReference; -import org.junit.AssumptionViolatedException; - -/** AsyncTask for interop test cases. */ -final class InteropTask extends AsyncTask { - private static final String LOG_TAG = "GrpcInteropTask"; - - interface Listener { - void onComplete(String result); - } - - static final String SUCCESS_MESSAGE = "Success!"; - - private final WeakReference listenerReference; - private final String testCase; - private final Tester tester; - - InteropTask( - Listener listener, - ManagedChannel channel, - String testCase) { - this.listenerReference = new WeakReference(listener); - this.testCase = testCase; - this.tester = new Tester(channel); - } - - @Override - protected void onPreExecute() { - tester.setUp(); - } - - @SuppressWarnings("Finally") - @Override - protected String doInBackground(Void... ignored) { - try { - runTest(testCase); - return SUCCESS_MESSAGE; - } catch (Throwable t) { - // Print the stack trace to logcat. - t.printStackTrace(); - // Then print to the error message. - StringWriter sw = new StringWriter(); - t.printStackTrace(new PrintWriter(sw)); - return "Failed... : " + t.getMessage() + "\n" + sw; - } finally { - try { - tester.tearDown(); - } catch (RuntimeException ex) { - throw ex; - } catch (Exception ex) { - throw new RuntimeException(ex); - } - } - } - - private void runTest(String testCase) throws Exception { - Log.i(LOG_TAG, "Running test case: " + testCase); - if ("empty_unary".equals(testCase)) { - tester.emptyUnary(); - } else if ("large_unary".equals(testCase)) { - try { - tester.largeUnary(); - } catch (AssumptionViolatedException e) { - // This test case requires more memory than most Android devices have available - Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e); - } - } else if ("client_streaming".equals(testCase)) { - tester.clientStreaming(); - } else if ("server_streaming".equals(testCase)) { - tester.serverStreaming(); - } else if ("ping_pong".equals(testCase)) { - tester.pingPong(); - } else if ("empty_stream".equals(testCase)) { - tester.emptyStream(); - } else if ("cancel_after_begin".equals(testCase)) { - tester.cancelAfterBegin(); - } else if ("cancel_after_first_response".equals(testCase)) { - tester.cancelAfterFirstResponse(); - } else if ("full_duplex_call_should_succeed".equals(testCase)) { - tester.fullDuplexCallShouldSucceed(); - } else if ("half_duplex_call_should_succeed".equals(testCase)) { - tester.halfDuplexCallShouldSucceed(); - } else if ("server_streaming_should_be_flow_controlled".equals(testCase)) { - tester.serverStreamingShouldBeFlowControlled(); - } else if ("very_large_request".equals(testCase)) { - try { - tester.veryLargeRequest(); - } catch (AssumptionViolatedException e) { - // This test case requires more memory than most Android devices have available - Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e); - } - } else if ("very_large_response".equals(testCase)) { - try { - tester.veryLargeResponse(); - } catch (AssumptionViolatedException e) { - // This test case requires more memory than most Android devices have available - Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e); - } - } else if ("deadline_not_exceeded".equals(testCase)) { - tester.deadlineNotExceeded(); - } else if ("deadline_exceeded".equals(testCase)) { - tester.deadlineExceeded(); - } else if ("deadline_exceeded_server_streaming".equals(testCase)) { - tester.deadlineExceededServerStreaming(); - } else if ("unimplemented_method".equals(testCase)) { - tester.unimplementedMethod(); - } else if ("timeout_on_sleeping_server".equals(testCase)) { - tester.timeoutOnSleepingServer(); - } else if ("graceful_shutdown".equals(testCase)) { - tester.gracefulShutdown(); - } else { - throw new IllegalArgumentException("Unimplemented/Unknown test case: " + testCase); - } - } - - @Override - protected void onPostExecute(String result) { - Listener listener = listenerReference.get(); - if (listener != null) { - listener.onComplete(result); - } - } - - private static class Tester extends AbstractInteropTest { - - private Tester(ManagedChannel channel) { - this.channel = channel; - } - - @Override - protected ManagedChannel createChannel() { - return channel; - } - - @Override - protected ManagedChannelBuilder createChannelBuilder() { - throw new UnsupportedOperationException(); - } - - @Override - protected boolean metricsExpected() { - return false; - } - } -} diff --git a/android-interop-testing/src/main/java/io/grpc/android/integrationtest/TestCallable.java b/android-interop-testing/src/main/java/io/grpc/android/integrationtest/TestCallable.java new file mode 100644 index 00000000000..56ea75bb657 --- /dev/null +++ b/android-interop-testing/src/main/java/io/grpc/android/integrationtest/TestCallable.java @@ -0,0 +1,149 @@ +/* + * Copyright 2023 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc.android.integrationtest; + +import android.util.Log; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import io.grpc.testing.integration.AbstractInteropTest; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.concurrent.Callable; +import org.junit.AssumptionViolatedException; + +/** + * Used to run a single test case against a channel in a separate thread. + */ +public class TestCallable implements Callable { + private final ManagedChannel channel; + private final String testCase; + + private static final String LOG_TAG = "GrpcInteropTask"; + static final String SUCCESS_MESSAGE = "Success!"; + + public TestCallable(ManagedChannel channel, String testCase) { + this.channel = channel; + this.testCase = testCase; + } + + @Override + public String call() { + Tester tester = new Tester(channel); + tester.setUp(); + try { + runTest(tester, testCase); + return SUCCESS_MESSAGE; + } catch (Throwable t) { + // Print the stack trace to logcat. + t.printStackTrace(); + // Then print to the error message. + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + return "Failed... : " + t.getMessage() + "\n" + sw; + } finally { + try { + tester.tearDown(); + } catch (RuntimeException ex) { + throw ex; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + } + + private void runTest(Tester tester, String testCase) throws Exception { + Log.i(LOG_TAG, "Running test case: " + testCase); + if ("empty_unary".equals(testCase)) { + tester.emptyUnary(); + } else if ("large_unary".equals(testCase)) { + try { + tester.largeUnary(); + } catch (AssumptionViolatedException e) { + // This test case requires more memory than most Android devices have available + Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e); + } + } else if ("client_streaming".equals(testCase)) { + tester.clientStreaming(); + } else if ("server_streaming".equals(testCase)) { + tester.serverStreaming(); + } else if ("ping_pong".equals(testCase)) { + tester.pingPong(); + } else if ("empty_stream".equals(testCase)) { + tester.emptyStream(); + } else if ("cancel_after_begin".equals(testCase)) { + tester.cancelAfterBegin(); + } else if ("cancel_after_first_response".equals(testCase)) { + tester.cancelAfterFirstResponse(); + } else if ("full_duplex_call_should_succeed".equals(testCase)) { + tester.fullDuplexCallShouldSucceed(); + } else if ("half_duplex_call_should_succeed".equals(testCase)) { + tester.halfDuplexCallShouldSucceed(); + } else if ("server_streaming_should_be_flow_controlled".equals(testCase)) { + tester.serverStreamingShouldBeFlowControlled(); + } else if ("very_large_request".equals(testCase)) { + try { + tester.veryLargeRequest(); + } catch (AssumptionViolatedException e) { + // This test case requires more memory than most Android devices have available + Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e); + } + } else if ("very_large_response".equals(testCase)) { + try { + tester.veryLargeResponse(); + } catch (AssumptionViolatedException e) { + // This test case requires more memory than most Android devices have available + Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e); + } + } else if ("deadline_not_exceeded".equals(testCase)) { + tester.deadlineNotExceeded(); + } else if ("deadline_exceeded".equals(testCase)) { + tester.deadlineExceeded(); + } else if ("deadline_exceeded_server_streaming".equals(testCase)) { + tester.deadlineExceededServerStreaming(); + } else if ("unimplemented_method".equals(testCase)) { + tester.unimplementedMethod(); + } else if ("timeout_on_sleeping_server".equals(testCase)) { + tester.timeoutOnSleepingServer(); + } else if ("graceful_shutdown".equals(testCase)) { + tester.gracefulShutdown(); + } else { + throw new IllegalArgumentException("Unimplemented/Unknown test case: " + testCase); + } + } + + private static class Tester extends AbstractInteropTest { + + private Tester(ManagedChannel channel) { + this.channel = channel; + } + + @Override + protected ManagedChannel createChannel() { + return channel; + } + + @Override + protected ManagedChannelBuilder createChannelBuilder() { + throw new UnsupportedOperationException(); + } + + @Override + protected boolean metricsExpected() { + return false; + } + } +} diff --git a/android-interop-testing/src/main/java/io/grpc/android/integrationtest/TesterActivity.java b/android-interop-testing/src/main/java/io/grpc/android/integrationtest/TesterActivity.java index 004950e7380..17c7e24cbfa 100644 --- a/android-interop-testing/src/main/java/io/grpc/android/integrationtest/TesterActivity.java +++ b/android-interop-testing/src/main/java/io/grpc/android/integrationtest/TesterActivity.java @@ -18,8 +18,8 @@ import android.content.Context; import android.content.Intent; +import android.net.LocalSocketAddress.Namespace; import android.os.Bundle; -import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -28,22 +28,34 @@ import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; import com.google.android.gms.security.ProviderInstaller; import io.grpc.ManagedChannel; +import io.grpc.android.UdsChannelBuilder; +import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; public class TesterActivity extends AppCompatActivity - implements ProviderInstaller.ProviderInstallListener, InteropTask.Listener { + implements ProviderInstaller.ProviderInstallListener { private static final String LOG_TAG = "GrpcTesterActivity"; private List