mirror of https://github.com/grpc/grpc-java.git
Compare commits
21 Commits
Author | SHA1 | Date |
---|---|---|
|
56d1c63802 | |
|
4a5605cea3 | |
|
4b01c907bc | |
|
92b4faed40 | |
|
1bf518af12 | |
|
5369df13a5 | |
|
6d21d71a25 | |
|
e955afe50a | |
|
5c09616aae | |
|
7d5d25d34e | |
|
e988f84d14 | |
|
abdb6980ec | |
|
61ec299352 | |
|
9f26b7dd08 | |
|
fefa2d9b16 | |
|
882a27bcb6 | |
|
2e41c9a5cb | |
|
132bf3e573 | |
|
85ce900dfc | |
|
bb39ca3ec9 | |
|
051e3971de |
|
@ -1,41 +0,0 @@
|
|||
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
|
||||
|
|
@ -9,5 +9,5 @@ jobs:
|
|||
name: "Gradle wrapper validation"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: gradle/actions/wrapper-validation@v4
|
||||
- uses: actions/checkout@v3
|
||||
- uses: gradle/wrapper-validation-action@v1
|
||||
|
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v5
|
||||
- uses: dessant/lock-threads@v4
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-inactive-days: 90
|
||||
|
|
|
@ -17,18 +17,18 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
jre: [8, 11, 17]
|
||||
jre: [8, 11]
|
||||
fail-fast: false # Should swap to true if we grow a large matrix
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: ${{ matrix.jre }}
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Gradle cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
|
@ -37,7 +37,7 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Maven cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.m2/repository
|
||||
|
@ -46,7 +46,7 @@ jobs:
|
|||
restore-keys: |
|
||||
${{ runner.os }}-maven-
|
||||
- name: Protobuf cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /tmp/protobuf-cache
|
||||
key: ${{ runner.os }}-maven-${{ hashFiles('buildscripts/make_dependencies.sh') }}
|
||||
|
@ -55,56 +55,16 @@ jobs:
|
|||
run: buildscripts/kokoro/unix.sh
|
||||
- name: Post Failure Upload Test Reports to Artifacts
|
||||
if: ${{ failure() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Test Reports (JRE ${{ matrix.jre }})
|
||||
path: |
|
||||
./*/build/reports/tests/**
|
||||
./*/*/build/reports/tests/**
|
||||
path: ./*/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
|
||||
run: ./gradlew :grpc-all:coveralls -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: 7.0.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 }}
|
||||
|
||||
- name: Run bazel test
|
||||
run: bazelisk test //... --enable_bzlmod=${{ matrix.bzlmod }}
|
||||
|
||||
- name: Run example bazel build
|
||||
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }}
|
||||
working-directory: ./examples
|
||||
uses: codecov/codecov-action@v3
|
||||
|
|
|
@ -15,7 +15,6 @@ bazel-genfiles
|
|||
bazel-grpc-java
|
||||
bazel-out
|
||||
bazel-testlogs
|
||||
MODULE.bazel.lock
|
||||
|
||||
# IntelliJ IDEA
|
||||
.idea
|
||||
|
|
16
BUILD.bazel
16
BUILD.bazel
|
@ -12,7 +12,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
load("@rules_jvm_external//:defs.bzl", "artifact")
|
||||
load(":java_grpc_library.bzl", "java_grpc_library")
|
||||
|
||||
java_proto_library(
|
||||
|
@ -33,9 +32,10 @@ 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 +46,9 @@ java_library(
|
|||
"//api",
|
||||
"//protobuf-lite",
|
||||
"//stub",
|
||||
artifact("com.google.code.findbugs:jsr305"),
|
||||
artifact("com.google.guava:guava"),
|
||||
"//stub:javax_annotation",
|
||||
"@com_google_code_findbugs_jsr305//jar",
|
||||
"@com_google_guava_guava//jar",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -55,7 +56,7 @@ java_plugin(
|
|||
name = "auto_value",
|
||||
generates_api = 1,
|
||||
processor_class = "com.google.auto.value.processor.AutoValueProcessor",
|
||||
deps = [artifact("com.google.auto.value:auto-value")],
|
||||
deps = ["@com_google_auto_value_auto_value//jar"],
|
||||
)
|
||||
|
||||
java_library(
|
||||
|
@ -64,6 +65,7 @@ java_library(
|
|||
neverlink = 1,
|
||||
visibility = ["//:__subpackages__"],
|
||||
exports = [
|
||||
artifact("com.google.auto.value:auto-value-annotations"),
|
||||
"@com_google_auto_value_auto_value_annotations//jar",
|
||||
"@org_apache_tomcat_annotations_api//jar", # @Generated for Java 9+
|
||||
],
|
||||
)
|
||||
|
|
|
@ -44,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 22.5 or later.
|
||||
The codegen plugin is C++ code and requires protobuf 21.7 or later.
|
||||
|
||||
For Linux, Mac and MinGW:
|
||||
```
|
||||
$ PROTOBUF_VERSION=22.5
|
||||
$ PROTOBUF_VERSION=21.7
|
||||
$ 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
|
||||
|
@ -68,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) don't have ``/usr/local`` in the
|
||||
Some versions of Mac OS X (e.g., 10.10) doesn'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:
|
||||
```
|
||||
|
|
|
@ -30,36 +30,56 @@ 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 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.
|
||||
|
||||
- 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.
|
||||
|
||||
- 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**.
|
||||
|
|
|
@ -10,26 +10,25 @@ for general contribution guidelines.
|
|||
## Maintainers (in alphabetical order)
|
||||
- [ejona86](https://github.com/ejona86), Google LLC
|
||||
- [jdcormie](https://github.com/jdcormie), Google LLC
|
||||
- [kannanjgithub](https://github.com/kannanjgithub), Google LLC
|
||||
- [larry-safran](https://github.com/larry-safran), Google LLC
|
||||
- [markb74](https://github.com/markb74), Google LLC
|
||||
- [ran-su](https://github.com/ran-su), Google LLC
|
||||
- [sanjaypujare](https://github.com/sanjaypujare), 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)
|
||||
- [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)
|
||||
- [carl-mastrangelo](https://github.com/carl-mastrangelo), Google LLC
|
||||
- [creamsoup](https://github.com/creamsoup), Google LLC
|
||||
- [dapengzhang0](https://github.com/dapengzhang0), Google LLC
|
||||
- [ericgribkoff](https://github.com/ericgribkoff), Google LLC
|
||||
- [jiangtaoli2016](https://github.com/jiangtaoli2016), 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
|
||||
- [srini100](https://github.com/srini100), Google LLC
|
||||
- [voidzcy](https://github.com/voidzcy), Google LLC
|
||||
- [zpencer](https://github.com/zpencer), Google LLC
|
||||
|
|
185
MODULE.bazel
185
MODULE.bazel
|
@ -1,185 +0,0 @@
|
|||
module(
|
||||
name = "grpc-java",
|
||||
compatibility_level = 0,
|
||||
repo_name = "io_grpc_grpc_java",
|
||||
version = "1.76.0-SNAPSHOT", # CURRENT_GRPC_VERSION
|
||||
)
|
||||
|
||||
# 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.59.2",
|
||||
"com.google.auth:google-auth-library-credentials:1.24.1",
|
||||
"com.google.auth:google-auth-library-oauth2-http:1.24.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.11.0",
|
||||
"com.google.errorprone:error_prone_annotations:2.30.0",
|
||||
"com.google.guava:failureaccess:1.0.1",
|
||||
"com.google.guava:guava:33.3.1-android",
|
||||
"com.google.re2j:re2j:1.8",
|
||||
"com.google.s2a.proto.v2:s2a-proto:0.1.2",
|
||||
"com.google.truth:truth:1.4.2",
|
||||
"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.124.Final",
|
||||
"io.netty:netty-codec-http2:4.1.124.Final",
|
||||
"io.netty:netty-codec-http:4.1.124.Final",
|
||||
"io.netty:netty-codec-socks:4.1.124.Final",
|
||||
"io.netty:netty-codec:4.1.124.Final",
|
||||
"io.netty:netty-common:4.1.124.Final",
|
||||
"io.netty:netty-handler-proxy:4.1.124.Final",
|
||||
"io.netty:netty-handler:4.1.124.Final",
|
||||
"io.netty:netty-resolver:4.1.124.Final",
|
||||
"io.netty:netty-tcnative-boringssl-static:2.0.70.Final",
|
||||
"io.netty:netty-tcnative-classes:2.0.70.Final",
|
||||
"io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.124.Final",
|
||||
"io.netty:netty-transport-native-unix-common:4.1.124.Final",
|
||||
"io.netty:netty-transport:4.1.124.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.checkerframework:checker-qual:3.12.0",
|
||||
"org.codehaus.mojo:animal-sniffer-annotations:1.24",
|
||||
]
|
||||
# GRPC_DEPS_END
|
||||
|
||||
bazel_dep(name = "bazel_jar_jar", version = "0.1.7")
|
||||
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
||||
bazel_dep(name = "googleapis", repo_name = "com_google_googleapis", version = "0.0.0-20240326-1c8d509c5")
|
||||
bazel_dep(name = "grpc-proto", repo_name = "io_grpc_grpc_proto", version = "0.0.0-20240627-ec30f58")
|
||||
# Protobuf 25.5+ is incompatible with Bazel 7 with bzlmod
|
||||
bazel_dep(name = "protobuf", repo_name = "com_google_protobuf", version = "24.4")
|
||||
bazel_dep(name = "rules_cc", version = "0.0.9")
|
||||
bazel_dep(name = "rules_java", version = "5.3.5")
|
||||
bazel_dep(name = "rules_jvm_external", version = "6.0")
|
||||
bazel_dep(name = "rules_proto", version = "5.3.0-21.7")
|
||||
|
||||
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",
|
||||
)
|
58
README.md
58
README.md
|
@ -13,14 +13,14 @@ gRPC-Java - An RPC library and framework
|
|||
</table>
|
||||
|
||||
[](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://github.com/grpc/grpc-java/actions/workflows/testing.yml?branch=master)
|
||||
[](https://travis-ci.org/grpc/grpc-java)
|
||||
[](https://coveralls.io/github/grpc/grpc-java?branch=master)
|
||||
[](https://codecov.io/gh/grpc/grpc-java)
|
||||
|
||||
Supported Platforms
|
||||
-------------------
|
||||
|
||||
gRPC-Java supports Java 8 and later. Android minSdkVersion 21 (Lollipop) and
|
||||
gRPC-Java supports Java 8 and later. Android minSdkVersion 19 (KitKat) and
|
||||
later are supported with [Java 8 language desugaring][android-java-8].
|
||||
|
||||
TLS usage on Android typically requires Play Services Dynamic Security Provider.
|
||||
|
@ -44,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.75.0/examples) and the
|
||||
[Android example](https://github.com/grpc/grpc-java/tree/v1.75.0/examples/android)
|
||||
The [examples](https://github.com/grpc/grpc-java/tree/v1.54.1/examples) and the
|
||||
[Android example](https://github.com/grpc/grpc-java/tree/v1.54.1/examples/android)
|
||||
are standalone projects that showcase the usage of gRPC.
|
||||
|
||||
Download
|
||||
|
@ -56,18 +56,18 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
|
|||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-netty-shaded</artifactId>
|
||||
<version>1.75.0</version>
|
||||
<version>1.54.1</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-protobuf</artifactId>
|
||||
<version>1.75.0</version>
|
||||
<version>1.54.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-stub</artifactId>
|
||||
<version>1.75.0</version>
|
||||
<version>1.54.1</version>
|
||||
</dependency>
|
||||
<dependency> <!-- necessary for Java 9+ -->
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
|
@ -79,30 +79,26 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
|
|||
|
||||
Or for Gradle with non-Android, add to your dependencies:
|
||||
```gradle
|
||||
runtimeOnly 'io.grpc:grpc-netty-shaded:1.75.0'
|
||||
implementation 'io.grpc:grpc-protobuf:1.75.0'
|
||||
implementation 'io.grpc:grpc-stub:1.75.0'
|
||||
runtimeOnly 'io.grpc:grpc-netty-shaded:1.54.1'
|
||||
implementation 'io.grpc:grpc-protobuf:1.54.1'
|
||||
implementation 'io.grpc:grpc-stub:1.54.1'
|
||||
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
|
||||
```
|
||||
|
||||
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.75.0'
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.75.0'
|
||||
implementation 'io.grpc:grpc-stub:1.75.0'
|
||||
implementation 'io.grpc:grpc-okhttp:1.54.1'
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.54.1'
|
||||
implementation 'io.grpc:grpc-stub:1.54.1'
|
||||
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
|
||||
```
|
||||
|
||||
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.75.0
|
||||
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.54.1
|
||||
|
||||
Development snapshots are available in [Sonatypes's snapshot
|
||||
repository](https://central.sonatype.com/repository/maven-snapshots/).
|
||||
repository](https://oss.sonatype.org/content/repositories/snapshots/).
|
||||
|
||||
Generated Code
|
||||
--------------
|
||||
|
@ -129,9 +125,9 @@ For protobuf-based codegen integrated with the Maven build system, you can use
|
|||
<artifactId>protobuf-maven-plugin</artifactId>
|
||||
<version>0.6.1</version>
|
||||
<configuration>
|
||||
<protocArtifact>com.google.protobuf:protoc:3.25.5:exe:${os.detected.classifier}</protocArtifact>
|
||||
<protocArtifact>com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier}</protocArtifact>
|
||||
<pluginId>grpc-java</pluginId>
|
||||
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.75.0:exe:${os.detected.classifier}</pluginArtifact>
|
||||
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.54.1:exe:${os.detected.classifier}</pluginArtifact>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@ -152,16 +148,16 @@ 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.9.5'
|
||||
id 'com.google.protobuf' version '0.9.1'
|
||||
}
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = "com.google.protobuf:protoc:3.25.5"
|
||||
artifact = "com.google.protobuf:protoc:3.21.7"
|
||||
}
|
||||
plugins {
|
||||
grpc {
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.54.1'
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -185,16 +181,16 @@ use protobuf-gradle-plugin but specify the 'lite' options:
|
|||
|
||||
```gradle
|
||||
plugins {
|
||||
id 'com.google.protobuf' version '0.9.5'
|
||||
id 'com.google.protobuf' version '0.9.1'
|
||||
}
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = "com.google.protobuf:protoc:3.25.5"
|
||||
artifact = "com.google.protobuf:protoc:3.21.7"
|
||||
}
|
||||
plugins {
|
||||
grpc {
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.54.1'
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -211,11 +207,6 @@ protobuf {
|
|||
|
||||
```
|
||||
|
||||
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
|
||||
-------------
|
||||
|
||||
|
@ -269,9 +260,6 @@ gRPC comes with multiple Transport implementations:
|
|||
|
||||
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.
|
||||
|
|
237
RELEASING.md
237
RELEASING.md
|
@ -16,12 +16,10 @@ 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=(
|
||||
MODULE.bazel
|
||||
$ MAJOR=1 MINOR=7 PATCH=0 # Set appropriately for new release
|
||||
$ VERSION_FILES=(
|
||||
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
|
||||
|
@ -50,26 +48,25 @@ would be used to create all `v1.7` tags (e.g. `v1.7.0`, `v1.7.1`).
|
|||
``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"
|
||||
```
|
||||
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
|
||||
```
|
||||
5. Continue with Google-internal steps at go/grpc-java/releasing, but stop
|
||||
before `Auto releasing using kokoro`.
|
||||
5. Continue with Google-internal steps at go/grpc/java/releasing.
|
||||
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
|
||||
|
@ -77,8 +74,8 @@ 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 -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 "## 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 && echo && echo "Backported commits in previous release:" && \
|
||||
git log --oneline "$(git merge-base v$MAJOR.$((MINOR-1)).0 upstream/v$MAJOR.$MINOR.x)"..v$MAJOR.$((MINOR-1)).0^
|
||||
```
|
||||
|
@ -93,160 +90,132 @@ Tagging the 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.
|
||||
2. Ensure that Google-internal steps completed at go/grpc/java/releasing#before-tagging-a-release.
|
||||
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-v$MAJOR.$MINOR.$PATCH
|
||||
|
||||
$ git checkout v$MAJOR.$MINOR.x
|
||||
$ git pull upstream v$MAJOR.$MINOR.x
|
||||
$ git checkout -b release
|
||||
# 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"
|
||||
$ ${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"
|
||||
```
|
||||
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"
|
||||
```
|
||||
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"
|
||||
git push -u origin release-v$MAJOR.$MINOR.$PATCH
|
||||
$ ./gradlew build
|
||||
$ git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT"
|
||||
```
|
||||
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-v$MAJOR.$MINOR.$PATCH
|
||||
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
|
||||
$ git push upstream v$MAJOR.$MINOR.x
|
||||
$ git push upstream v$MAJOR.$MINOR.$PATCH
|
||||
```
|
||||
7. Close the release milestone.
|
||||
|
||||
8. Trigger build as described in "Auto releasing using kokoro" at
|
||||
go/grpc-java/releasing.
|
||||
Build Artifacts
|
||||
---------------
|
||||
|
||||
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.
|
||||
Trigger build as described in "Auto releasing using kokoro" at
|
||||
go/grpc/java/releasing.
|
||||
|
||||
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).
|
||||
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.
|
||||
|
||||
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
|
||||
Releasing on Maven Central
|
||||
--------------------------
|
||||
|
||||
# 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
|
||||
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).
|
||||
|
||||
# Commit the changes
|
||||
git commit --all -m "[interop] Add grpc-java $MAJOR.$MINOR.$PATCH to client_matrix.py"
|
||||
Build interop container image
|
||||
-----------------------------
|
||||
|
||||
# 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
|
||||
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).
|
||||
|
||||
11. Update gh-pages with the new Javadoc. Generally the file is on repo1
|
||||
15 minutes after publishing:
|
||||
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.
|
||||
|
||||
```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.
|
||||
|
||||
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
|
||||
./gradlew checkForUpdates
|
||||
```
|
||||
$ git checkout -b bump-readme master
|
||||
$ git cherry-pick v$MAJOR.$MINOR.$PATCH^
|
||||
```
|
||||
|
||||
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.
|
||||
Update version referenced by tutorials
|
||||
--------------------------------------
|
||||
|
||||
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/`.
|
||||
Update `params.grpc_vers.java` 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 <tag> Released`).
|
||||
|
||||
Update Hosted Javadoc
|
||||
---------------------
|
||||
|
||||
Now we need to update gh-pages with the new Javadoc:
|
||||
|
||||
```bash
|
||||
git checkout gh-pages
|
||||
git pull --ff-only upstream gh-pages
|
||||
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"
|
||||
```
|
||||
|
||||
Push gh-pages to the main repository and verify the current version is [live
|
||||
on grpc.io](https://grpc.io/grpc-java/javadoc/).
|
||||
|
|
152
SECURITY.md
152
SECURITY.md
|
@ -1,16 +1,10 @@
|
|||
# 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
|
||||
For information on gRPC Security Policy and reporting potentional security issues, please see [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)
|
||||
|
||||
|
@ -25,28 +19,25 @@ BoringSSL](#tls-with-netty-tcnative-on-boringssl).
|
|||
## TLS on Android
|
||||
|
||||
On Android we recommend the use of the [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][config-psdsp].
|
||||
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).
|
||||
|
||||
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 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
|
||||
*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.*
|
||||
|
||||
### 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][conscrypt-maven].
|
||||
on [Maven
|
||||
Central](https://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.conscrypt%20a%3Aconscrypt-android).
|
||||
|
||||
Like the Play Services Dynamic Security Provider, you must still "install"
|
||||
Conscrypt before use.
|
||||
|
@ -59,12 +50,10 @@ 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
|
||||
|
||||
OpenJDK versions prior to Java 8u252 do not support ALPN. Java 8 has 10% the
|
||||
performance of OpenSSL.
|
||||
JDK versions prior to Java 9 do not support ALPN and are either missing AES GCM
|
||||
support or have 2% 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
|
||||
|
@ -84,7 +73,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 simplicity and low occurrence of security
|
||||
We recommend BoringSSL for its simplicitly and low occurrence of security
|
||||
vulnerabilities relative to OpenSSL. BoringSSL is used by Conscrypt as well.
|
||||
|
||||
### TLS with netty-tcnative on BoringSSL
|
||||
|
@ -254,6 +243,37 @@ import java.security.Security;
|
|||
Security.insertProviderAt(Conscrypt.newProvider(), 1);
|
||||
```
|
||||
|
||||
### 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
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<!-- Must be done in jetty-env.xml, since jetty-web.xml is loaded too late. -->
|
||||
<!-- Removing ALPN from the blacklisted server classes (using "-" to remove). -->
|
||||
<!-- Must prepend to the blacklist since order matters. -->
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.alpn.</Arg>
|
||||
</Call>
|
||||
</Configure>
|
||||
```
|
||||
## Enabling TLS on a server
|
||||
|
||||
To use TLS on the server, a certificate chain and private key need to be
|
||||
|
@ -261,36 +281,35 @@ specified in PEM format. The standard TLS port is 443, but we use 8443 below to
|
|||
avoid needing extra permissions from the OS.
|
||||
|
||||
```java
|
||||
ServerCredentials creds = TlsServerCredentials.create(certChainFile, privateKeyFile);
|
||||
Server server = Grpc.newServerBuilderForPort(8443, creds)
|
||||
Server server = ServerBuilder.forPort(8443)
|
||||
// Enable TLS
|
||||
.useTransportSecurity(certChainFile, privateKeyFile)
|
||||
.addService(serviceImplementation)
|
||||
.build()
|
||||
.start();
|
||||
.build();
|
||||
server.start();
|
||||
```
|
||||
|
||||
If the issuing certificate authority is not known to the client then a properly
|
||||
configured trust manager should be provided to TlsChannelCredentials and used to
|
||||
construct the channel.
|
||||
configured SslContext or SSLSocketFactory should be provided to the
|
||||
NettyChannelBuilder or OkHttpChannelBuilder, respectively.
|
||||
|
||||
## 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
|
||||
ServerCredentials creds = TlsServerCredentials.newBuilder()
|
||||
.keyManager(certChainFile, privateKeyFile)
|
||||
.trustManager(clientCAsFile)
|
||||
.clientAuth(TlsServerCredentials.ClientAuth.REQUIRE)
|
||||
.build();
|
||||
Server server = NettyServerBuilder.forPort(8443)
|
||||
.sslContext(GrpcSslContexts.forServer(certChainFile, privateKeyFile)
|
||||
.trustManager(clientCAsFile)
|
||||
.clientAuth(ClientAuth.REQUIRE)
|
||||
.build());
|
||||
```
|
||||
|
||||
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.
|
||||
Negotiated client certificates are available in the SSLSession, which is found in the `TRANSPORT_ATTR_SSL_SESSION` attribute of <a href="https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/Grpc.java">Grpc</a>. A server interceptor can provide details in the current Context.
|
||||
|
||||
```java
|
||||
// The application uses this in its handlers.
|
||||
public static final Context.Key<MySecurityInfo> SECURITY_INFO = Context.key("my.security.Info");
|
||||
// The application uses this in its handlers
|
||||
public final static Context.Key<SSLSession> SSL_SESSION_CONTEXT = Context.key("SSLSession");
|
||||
|
||||
@Override
|
||||
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
|
||||
|
@ -299,12 +318,8 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, Re
|
|||
if (sslSession == null) {
|
||||
return next.startCall(call, headers);
|
||||
}
|
||||
// This interceptor can provide a centralized policy to process the client's
|
||||
// certificate. Avoid exposing low-level details (like SSLSession) and
|
||||
// instead provide a higher-level concept like "authenticated user."
|
||||
MySecurityInfo info = process(sslSession);
|
||||
return Contexts.interceptCall(
|
||||
Context.current().withValue(SECURITY_INFO, info), call, headers, next);
|
||||
Context.current().withValue(SSL_SESSION_CONTEXT, sslSession), call, headers, next);
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -343,6 +358,10 @@ If on Fedora 30 or later and you see "libcrypt.so.1: cannot open shared object
|
|||
file: No such file or directory". Run `dnf -y install libxcrypt-compat` to
|
||||
install the necessary dependency.
|
||||
|
||||
If you are running inside of an embedded Tomcat runtime (e.g., Spring Boot),
|
||||
then some versions of `netty-tcnative-boringssl-static` will have conflicts and
|
||||
won't work. You must use gRPC 1.4.0 or later.
|
||||
|
||||
Most dependency versioning problems can be solved by using
|
||||
`io.grpc:grpc-netty-shaded` instead of `io.grpc:grpc-netty`, although this also
|
||||
limits your usage of the Netty-specific APIs. `io.grpc:grpc-netty-shaded`
|
||||
|
@ -394,24 +413,24 @@ grpc-netty version | netty-handler version | netty-tcnative-boringssl-static ver
|
|||
1.44.x-1.47.x | 4.1.72.Final | 2.0.46.Final
|
||||
1.48.x-1.49.x | 4.1.77.Final | 2.0.53.Final
|
||||
1.50.x-1.53.x | 4.1.79.Final | 2.0.54.Final
|
||||
1.54.x-1.55.x | 4.1.87.Final | 2.0.56.Final
|
||||
1.56.x | 4.1.87.Final | 2.0.61.Final
|
||||
1.57.x-1.58.x | 4.1.93.Final | 2.0.61.Final
|
||||
1.59.x | 4.1.97.Final | 2.0.61.Final
|
||||
1.60.x-1.66.x | 4.1.100.Final | 2.0.61.Final
|
||||
1.67.x-1.70.x | 4.1.110.Final | 2.0.65.Final
|
||||
1.71.x-1.74.x | 4.1.110.Final | 2.0.70.Final
|
||||
1.75.x- | 4.1.124.Final | 2.0.72.Final
|
||||
1.54.x- | 4.1.87.Final | 2.0.56.Final
|
||||
|
||||
_(grpc-netty-shaded avoids issues with keeping these versions in sync.)_
|
||||
|
||||
### OkHttp
|
||||
If you are using gRPC on Android devices, you are most likely using
|
||||
`grpc-okhttp` transport.
|
||||
If you are using gRPC on Android devices, you are most likely using `grpc-okhttp` transport.
|
||||
|
||||
Find the dependency tree (e.g., `mvn dependency:tree`), and look for
|
||||
`io.grpc:grpc-okhttp`. If you don't have `grpc-okhttp`, you should add it as a
|
||||
dependency.
|
||||
Find the dependency tree (e.g., `mvn dependency:tree`), and look for versions of:
|
||||
- `io.grpc:grpc-okhttp`
|
||||
- `com.squareup.okhttp:okhttp`
|
||||
|
||||
If you don't have `grpc-okhttp`, you should add it as a dependency.
|
||||
|
||||
If you have both `io.grpc:grpc-netty` and `io.grpc:grpc-okhttp`, you may also have issues. Remove `grpc-netty` if you are on Android.
|
||||
|
||||
If you have `okhttp` version below 2.5.0, then it may not work with gRPC.
|
||||
|
||||
It is OK to have both `okhttp` 2.x and 3.x since they have different group name and under different packages.
|
||||
|
||||
# gRPC over plaintext
|
||||
|
||||
|
@ -422,12 +441,17 @@ An option is provided to use gRPC over plaintext without TLS. While this is conv
|
|||
The following code snippet shows how you can call the Google Cloud PubSub API using gRPC with a service account. The credentials are loaded from a key stored in a well-known location or by detecting that the application is running in an environment that can provide one automatically, e.g. Google Compute Engine. While this example is specific to Google and it's services, similar patterns can be followed for other service providers.
|
||||
|
||||
```java
|
||||
// Use the default credentials from the environment
|
||||
ChannelCredentials creds = GoogleDefaultChannelCredentials.create();
|
||||
// Create a channel to the service
|
||||
ManagedChannel channel = Grpc.newChannelBuilder("dns:///pubsub.googleapis.com", creds)
|
||||
// Create a channel to the test service.
|
||||
ManagedChannel channel = ManagedChannelBuilder.forTarget("dns:///pubsub.googleapis.com")
|
||||
.build();
|
||||
// Create a stub and send an RPC
|
||||
PublisherGrpc.PublisherBlockingStub publisherStub = PublisherGrpc.newBlockingStub(channel);
|
||||
// Get the default credentials from the environment
|
||||
GoogleCredentials creds = GoogleCredentials.getApplicationDefault();
|
||||
// Down-scope the credential to just the scopes required by the service
|
||||
creds = creds.createScoped(Arrays.asList("https://www.googleapis.com/auth/pubsub"));
|
||||
// Create an instance of {@link io.grpc.CallCredentials}
|
||||
CallCredentials callCreds = MoreCallCredentials.from(creds);
|
||||
// Create a stub with credential
|
||||
PublisherGrpc.PublisherBlockingStub publisherStub =
|
||||
PublisherGrpc.newBlockingStub(channel).withCallCredentials(callCreds);
|
||||
publisherStub.publish(someMessage);
|
||||
```
|
||||
|
|
26
WORKSPACE
26
WORKSPACE
|
@ -2,17 +2,11 @@ workspace(name = "io_grpc_grpc_java")
|
|||
|
||||
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "rules_java",
|
||||
url = "https://github.com/bazelbuild/rules_java/releases/download/5.3.5/rules_java-5.3.5.tar.gz",
|
||||
sha256 = "c73336802d0b4882e40770666ad055212df4ea62cfa6edf9cb0f9d29828a0934",
|
||||
)
|
||||
|
||||
http_archive(
|
||||
name = "rules_jvm_external",
|
||||
sha256 = "d31e369b854322ca5098ea12c69d7175ded971435e55c18dd9dd5f29cc5249ac",
|
||||
strip_prefix = "rules_jvm_external-5.3",
|
||||
url = "https://github.com/bazelbuild/rules_jvm_external/releases/download/5.3/rules_jvm_external-5.3.tar.gz",
|
||||
sha256 = "c21ce8b8c4ccac87c809c317def87644cdc3a9dd650c74f41698d761c95175f3",
|
||||
strip_prefix = "rules_jvm_external-1498ac6ccd3ea9cdb84afed65aa257c57abf3e0a",
|
||||
url = "https://github.com/bazelbuild/rules_jvm_external/archive/1498ac6ccd3ea9cdb84afed65aa257c57abf3e0a.zip",
|
||||
)
|
||||
|
||||
load("@rules_jvm_external//:defs.bzl", "maven_install")
|
||||
|
@ -22,26 +16,32 @@ load("//:repositories.bzl", "grpc_java_repositories")
|
|||
|
||||
grpc_java_repositories()
|
||||
|
||||
load("@bazel_jar_jar//:jar_jar.bzl", "jar_jar_repositories")
|
||||
|
||||
jar_jar_repositories()
|
||||
|
||||
load("@com_google_protobuf//:protobuf_deps.bzl", "PROTOBUF_MAVEN_ARTIFACTS")
|
||||
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
|
||||
|
||||
protobuf_deps()
|
||||
|
||||
load("@envoy_api//bazel:repositories.bzl", "api_dependencies")
|
||||
|
||||
api_dependencies()
|
||||
|
||||
load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
|
||||
|
||||
switched_rules_by_language(
|
||||
name = "com_google_googleapis_imports",
|
||||
java = True,
|
||||
)
|
||||
|
||||
maven_install(
|
||||
artifacts = IO_GRPC_GRPC_JAVA_ARTIFACTS + PROTOBUF_MAVEN_ARTIFACTS,
|
||||
generate_compat_repositories = True,
|
||||
override_targets = IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS,
|
||||
repositories = [
|
||||
"https://repo.maven.apache.org/maven2/",
|
||||
],
|
||||
strict_visibility = True,
|
||||
)
|
||||
|
||||
load("@maven//:compat.bzl", "compat_repositories")
|
||||
|
||||
compat_repositories()
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
# When using bzlmod this makes sure nothing from the legacy WORKSPACE is loaded
|
|
@ -10,13 +10,11 @@ description = "gRPC: All"
|
|||
def subprojects = [
|
||||
project(':grpc-api'),
|
||||
project(':grpc-auth'),
|
||||
project(':grpc-context'),
|
||||
project(':grpc-core'),
|
||||
project(':grpc-grpclb'),
|
||||
project(':grpc-gcp-csm-observability'),
|
||||
project(':grpc-inprocess'),
|
||||
project(':grpc-netty'),
|
||||
project(':grpc-okhttp'),
|
||||
project(':grpc-opentelemetry'),
|
||||
project(':grpc-protobuf'),
|
||||
project(':grpc-protobuf-lite'),
|
||||
project(':grpc-rls'),
|
||||
|
@ -25,7 +23,6 @@ def subprojects = [
|
|||
project(':grpc-servlet-jakarta'),
|
||||
project(':grpc-stub'),
|
||||
project(':grpc-testing'),
|
||||
project(':grpc-util'),
|
||||
project(':grpc-xds'),
|
||||
]
|
||||
|
||||
|
@ -39,7 +36,6 @@ evaluationDependsOn(':grpc-interop-testing')
|
|||
|
||||
dependencies {
|
||||
api subprojects.minus([project(':grpc-protobuf-lite')])
|
||||
implementation libraries.guava.jre // JRE required by transitive protobuf-java-util
|
||||
}
|
||||
|
||||
tasks.named("javadoc").configure {
|
||||
|
@ -51,15 +47,23 @@ tasks.named("javadoc").configure {
|
|||
continue;
|
||||
}
|
||||
source subproject.javadoc.source
|
||||
options.linksOffline.addAll subproject.javadoc.options.linksOffline
|
||||
options.links subproject.javadoc.options.links.toArray(new String[0])
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("jacocoTestReport").configure {
|
||||
tasks.register("jacocoMerge", JacocoMerge) {
|
||||
dependsOn(subprojects.jacocoTestReport.dependsOn)
|
||||
dependsOn(project(':grpc-interop-testing').jacocoTestReport.dependsOn)
|
||||
mustRunAfter(subprojects.jacocoTestReport.mustRunAfter)
|
||||
mustRunAfter(project(':grpc-interop-testing').jacocoTestReport.mustRunAfter)
|
||||
executionData.from files(subprojects.jacocoTestReport.executionData)
|
||||
destinationFile = file("${buildDir}/jacoco/test.exec")
|
||||
executionData = files(subprojects.jacocoTestReport.executionData)
|
||||
.plus(project(':grpc-interop-testing').jacocoTestReport.executionData)
|
||||
.filter { f -> f.exists() }
|
||||
}
|
||||
|
||||
tasks.named("jacocoTestReport").configure {
|
||||
dependsOn(jacocoMerge)
|
||||
reports {
|
||||
xml.required = true
|
||||
html.required = true
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
load("@rules_jvm_external//:defs.bzl", "artifact")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
load("//:java_grpc_library.bzl", "java_grpc_library")
|
||||
|
||||
|
@ -15,16 +14,16 @@ java_library(
|
|||
"//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",
|
||||
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"),
|
||||
"@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",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -36,18 +35,19 @@ java_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":alts_internal",
|
||||
":handshaker_java_grpc",
|
||||
":handshaker_java_proto",
|
||||
":handshaker_java_grpc",
|
||||
"//api",
|
||||
"//auth",
|
||||
"//core:internal",
|
||||
"//netty",
|
||||
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"),
|
||||
"@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",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -2,24 +2,24 @@ 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"
|
||||
|
||||
evaluationDependsOn(project(':grpc-core').path)
|
||||
|
||||
dependencies {
|
||||
api project(':grpc-api')
|
||||
api project(':grpc-core')
|
||||
implementation project(':grpc-auth'),
|
||||
project(':grpc-core'),
|
||||
project(":grpc-context"), // Override google-auth dependency with our newer version
|
||||
project(':grpc-grpclb'),
|
||||
project(':grpc-protobuf'),
|
||||
project(':grpc-stub'),
|
||||
libraries.protobuf.java,
|
||||
libraries.conscrypt,
|
||||
libraries.guava.jre, // JRE required by protobuf-java-util from grpclb
|
||||
libraries.guava,
|
||||
libraries.google.auth.oauth2Http
|
||||
def nettyDependency = implementation project(':grpc-netty')
|
||||
compileOnly libraries.javax.annotation
|
||||
|
@ -28,15 +28,16 @@ dependencies {
|
|||
shadow project(path: ':grpc-netty-shaded', configuration: 'shadow')
|
||||
|
||||
testImplementation project(':grpc-testing'),
|
||||
testFixtures(project(':grpc-core')),
|
||||
project(':grpc-inprocess'),
|
||||
project(':grpc-core').sourceSets.test.output,
|
||||
project(':grpc-testing-proto'),
|
||||
libraries.guava,
|
||||
libraries.junit,
|
||||
libraries.mockito.core,
|
||||
libraries.truth
|
||||
|
||||
testImplementation libraries.guava.testlib
|
||||
testImplementation (libraries.guava.testlib) {
|
||||
exclude group: 'junit', module: 'junit'
|
||||
}
|
||||
testRuntimeOnly libraries.netty.tcnative,
|
||||
libraries.netty.tcnative.classes
|
||||
testRuntimeOnly (libraries.netty.transport.epoll) {
|
||||
|
@ -44,11 +45,7 @@ dependencies {
|
|||
classifier = "linux-x86_64"
|
||||
}
|
||||
}
|
||||
signature (libraries.signature.java) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
signature libraries.signature.java
|
||||
}
|
||||
|
||||
configureProtoCompilation()
|
||||
|
@ -56,6 +53,10 @@ configureProtoCompilation()
|
|||
import net.ltgt.gradle.errorprone.CheckSeverity
|
||||
|
||||
[tasks.named("compileJava"), tasks.named("compileTestJava")]*.configure {
|
||||
// protobuf calls valueof. Will be fixed in next release (google/protobuf#4046)
|
||||
options.compilerArgs += [
|
||||
"-Xlint:-deprecation"
|
||||
]
|
||||
// ALTS returns a lot of futures that we mostly don't care about.
|
||||
options.errorprone.check("FutureReturnValueIgnored", CheckSeverity.OFF)
|
||||
}
|
||||
|
@ -68,9 +69,6 @@ tasks.named("javadoc").configure {
|
|||
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
|
||||
|
@ -97,7 +95,8 @@ publishing {
|
|||
def dependencyNode = dependenciesNode.appendNode('dependency')
|
||||
dependencyNode.appendNode('groupId', dep.group)
|
||||
dependencyNode.appendNode('artifactId', dep.name)
|
||||
dependencyNode.appendNode('version', dep.version)
|
||||
def version = (dep.name == 'grpc-netty-shaded') ? '[' + dep.version + ']' : dep.version
|
||||
dependencyNode.appendNode('version', version)
|
||||
dependencyNode.appendNode('scope', 'compile')
|
||||
}
|
||||
asNode().dependencies[0].replaceNode(dependenciesNode)
|
||||
|
|
|
@ -4,12 +4,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
|
||||
/**
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.gcp.HandshakerService";
|
||||
public static final String SERVICE_NAME = "grpc.gcp.HandshakerService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.alts.internal.HandshakerReq,
|
||||
|
@ -57,21 +60,6 @@ public final class HandshakerServiceGrpc {
|
|||
return HandshakerServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static HandshakerServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<HandshakerServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<HandshakerServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -169,40 +157,6 @@ public final class HandshakerServiceGrpc {
|
|||
/**
|
||||
* A stub to allow clients to do synchronous rpc calls to service HandshakerService.
|
||||
*/
|
||||
public static final class HandshakerServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<HandshakerServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.alts.internal.HandshakerReq, io.grpc.alts.internal.HandshakerResp>
|
||||
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<HandshakerServiceBlockingStub> {
|
||||
private HandshakerServiceBlockingStub(
|
||||
|
@ -307,9 +261,9 @@ public final class HandshakerServiceGrpc {
|
|||
private static final class HandshakerServiceMethodDescriptorSupplier
|
||||
extends HandshakerServiceBaseDescriptorSupplier
|
||||
implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
|
||||
private final java.lang.String methodName;
|
||||
private final String methodName;
|
||||
|
||||
HandshakerServiceMethodDescriptorSupplier(java.lang.String methodName) {
|
||||
HandshakerServiceMethodDescriptorSupplier(String methodName) {
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ package io.grpc.alts;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.grpc.ExperimentalApi;
|
||||
import io.grpc.ForwardingChannelBuilder2;
|
||||
import io.grpc.ForwardingChannelBuilder;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import io.grpc.internal.GrpcUtil;
|
||||
|
@ -29,16 +29,16 @@ import javax.annotation.Nullable;
|
|||
|
||||
/**
|
||||
* ALTS version of {@code ManagedChannelBuilder}. This class sets up a secure and authenticated
|
||||
* communication between two cloud VMs using ALTS.
|
||||
* commmunication between two cloud VMs using ALTS.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151")
|
||||
public final class AltsChannelBuilder extends ForwardingChannelBuilder2<AltsChannelBuilder> {
|
||||
public final class AltsChannelBuilder extends ForwardingChannelBuilder<AltsChannelBuilder> {
|
||||
private final NettyChannelBuilder delegate;
|
||||
private final AltsChannelCredentials.Builder credentialsBuilder =
|
||||
new AltsChannelCredentials.Builder();
|
||||
|
||||
/** "Overrides" the static method in {@link ManagedChannelBuilder}. */
|
||||
public static AltsChannelBuilder forTarget(String target) {
|
||||
public static final AltsChannelBuilder forTarget(String target) {
|
||||
return new AltsChannelBuilder(target);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ import java.util.logging.Level;
|
|||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Provides secure and authenticated communication between two cloud VMs using ALTS.
|
||||
* Provides secure and authenticated commmunication between two cloud VMs using ALTS.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151")
|
||||
public final class AltsChannelCredentials {
|
||||
|
|
|
@ -14,10 +14,9 @@
|
|||
* 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;
|
||||
|
@ -30,36 +29,14 @@ public final class AltsContextUtil {
|
|||
private AltsContextUtil() {}
|
||||
|
||||
/**
|
||||
* Creates an {@link AltsContext} from ALTS context information in the {@link ServerCall}.
|
||||
* Creates a {@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);
|
||||
public static AltsContext createFrom(ServerCall<?,?> call) {
|
||||
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
|
||||
if (!(authContext instanceof AltsInternalContext)) {
|
||||
throw new IllegalArgumentException("No ALTS context information found");
|
||||
}
|
||||
|
@ -72,28 +49,8 @@ public final class AltsContextUtil {
|
|||
* @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);
|
||||
public static boolean check(ServerCall<?,?> call) {
|
||||
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
|
||||
return authContext instanceof AltsInternalContext;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public final class ComputeEngineChannelBuilder
|
|||
}
|
||||
|
||||
/** "Overrides" the static method in {@link ManagedChannelBuilder}. */
|
||||
public static ComputeEngineChannelBuilder forTarget(String target) {
|
||||
public static final ComputeEngineChannelBuilder forTarget(String target) {
|
||||
return new ComputeEngineChannelBuilder(target);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@ public final class ComputeEngineChannelBuilder
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI.
|
||||
protected NettyChannelBuilder delegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,4 +38,7 @@ final class FailingCallCredentials extends CallCredentials {
|
|||
CallCredentials.MetadataApplier applier) {
|
||||
applier.fail(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thisUsesUnstableApi() {}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public final class GoogleDefaultChannelBuilder
|
|||
}
|
||||
|
||||
/** "Overrides" the static method in {@link ManagedChannelBuilder}. */
|
||||
public static GoogleDefaultChannelBuilder forTarget(String target) {
|
||||
public static final GoogleDefaultChannelBuilder forTarget(String target) {
|
||||
return new GoogleDefaultChannelBuilder(target);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@ public final class GoogleDefaultChannelBuilder
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI.
|
||||
protected NettyChannelBuilder delegate() {
|
||||
return delegate;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,6 @@ public final class GoogleDefaultChannelCredentials {
|
|||
*/
|
||||
public static final class Builder {
|
||||
private CallCredentials callCredentials;
|
||||
private CallCredentials altsCallCredentials;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
|
@ -73,32 +72,23 @@ public final class GoogleDefaultChannelCredentials {
|
|||
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));
|
||||
}
|
||||
if (callCredentials != null) {
|
||||
return CompositeChannelCredentials.create(nettyCredentials, callCredentials);
|
||||
}
|
||||
CallCredentials callCreds;
|
||||
try {
|
||||
callCreds = MoreCallCredentials.from(GoogleCredentials.getApplicationDefault());
|
||||
} catch (IOException e) {
|
||||
callCreds =
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,14 +21,12 @@ import io.grpc.Channel;
|
|||
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;
|
||||
|
||||
/**
|
||||
|
@ -46,9 +44,6 @@ final class HandshakerServiceChannel {
|
|||
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<Channel> {
|
||||
private final String target;
|
||||
|
||||
|
@ -61,16 +56,12 @@ final class HandshakerServiceChannel {
|
|||
/* Use its own event loop thread pool to avoid blocking. */
|
||||
EventLoopGroup eventGroup =
|
||||
new NioEventLoopGroup(1, new DefaultThreadFactory("handshaker pool", true));
|
||||
NettyChannelBuilder channelBuilder =
|
||||
NettyChannelBuilder.forTarget(target)
|
||||
.channelType(NioSocketChannel.class, InetSocketAddress.class)
|
||||
ManagedChannel channel = NettyChannelBuilder.forTarget(target)
|
||||
.channelType(NioSocketChannel.class)
|
||||
.directExecutor()
|
||||
.eventLoopGroup(eventGroup)
|
||||
.usePlaintext();
|
||||
if (EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS) {
|
||||
channelBuilder.keepAliveTime(10, TimeUnit.MINUTES).keepAliveTimeout(10, TimeUnit.SECONDS);
|
||||
}
|
||||
ManagedChannel channel = channelBuilder.build();
|
||||
.usePlaintext()
|
||||
.build();
|
||||
return new EventLoopHoldingChannel(channel, eventGroup);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ class AltsHandshakerStub {
|
|||
private final HandshakerServiceStub serviceStub;
|
||||
private final ArrayBlockingQueue<Optional<HandshakerResp>> responseQueue =
|
||||
new ArrayBlockingQueue<>(1);
|
||||
private final AtomicReference<ThrowableInfo> exceptionMessage = new AtomicReference<>();
|
||||
private final AtomicReference<String> exceptionMessage = new AtomicReference<>();
|
||||
|
||||
private static final long HANDSHAKE_RPC_DEADLINE_SECS = 20;
|
||||
|
||||
|
@ -72,7 +72,7 @@ class AltsHandshakerStub {
|
|||
}
|
||||
|
||||
if (exceptionMessage.get() != null) {
|
||||
throw new IOException(exceptionMessage.get().info, exceptionMessage.get().throwable);
|
||||
throw new IOException(exceptionMessage.get());
|
||||
} else {
|
||||
throw new IOException("No handshaker response received");
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ class AltsHandshakerStub {
|
|||
/** Throw exception if there is an outstanding exception. */
|
||||
private void maybeThrowIoException() throws IOException {
|
||||
if (exceptionMessage.get() != null) {
|
||||
throw new IOException(exceptionMessage.get().info, exceptionMessage.get().throwable);
|
||||
throw new IOException(exceptionMessage.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ class AltsHandshakerStub {
|
|||
AltsHandshakerStub.this.responseQueue.add(Optional.of(resp));
|
||||
} catch (IllegalStateException e) {
|
||||
AltsHandshakerStub.this.exceptionMessage.compareAndSet(
|
||||
null, new ThrowableInfo(e, "Received an unexpected response."));
|
||||
null, "Received an unexpected response.");
|
||||
AltsHandshakerStub.this.close();
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ class AltsHandshakerStub {
|
|||
@Override
|
||||
public void onError(Throwable t) {
|
||||
AltsHandshakerStub.this.exceptionMessage.compareAndSet(
|
||||
null, new ThrowableInfo(t, "Received a terminating error."));
|
||||
null, "Received a terminating error: " + t.toString());
|
||||
// Trigger the release of any blocked send.
|
||||
Optional<HandshakerResp> result = Optional.absent();
|
||||
AltsHandshakerStub.this.responseQueue.offer(result);
|
||||
|
@ -126,22 +126,10 @@ class AltsHandshakerStub {
|
|||
/** Receive the closing message from the server. */
|
||||
@Override
|
||||
public void onCompleted() {
|
||||
AltsHandshakerStub.this.exceptionMessage.compareAndSet(
|
||||
null, new ThrowableInfo(null, "Response stream closed."));
|
||||
AltsHandshakerStub.this.exceptionMessage.compareAndSet(null, "Response stream closed.");
|
||||
// Trigger the release of any blocked send.
|
||||
Optional<HandshakerResp> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,12 +54,10 @@ import javax.annotation.Nullable;
|
|||
// TODO(carl-mastrangelo): rename this AltsProtocolNegotiators.
|
||||
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());
|
||||
// Avoid performing too many handshakes in parallel, as it may cause queuing in the handshake
|
||||
// server and cause unbounded blocking on the event loop (b/168808426). This is a workaround until
|
||||
// there is an async TSI handshaking API to avoid the blocking.
|
||||
private static final AsyncSemaphore handshakeSemaphore = new AsyncSemaphore(32);
|
||||
|
||||
@Grpc.TransportAttr
|
||||
public static final Attributes.Key<TsiPeer> TSI_PEER_KEY =
|
||||
|
@ -426,30 +424,5 @@ public final class AltsProtocolNegotiator {
|
|||
}
|
||||
}
|
||||
|
||||
@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() {}
|
||||
}
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
|
||||
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;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
|
||||
/** Provides a semaphore primitive, without blocking waiting on permits. */
|
||||
final class AsyncSemaphore {
|
||||
|
|
|
@ -78,7 +78,7 @@ public final class ProtectedPromise extends DefaultChannelPromise {
|
|||
if (!doneAllocating) {
|
||||
doneAllocating = true;
|
||||
if (successfulCount == expectedCount) {
|
||||
trySuccessInternal();
|
||||
trySuccessInternal(null);
|
||||
return super.setSuccess(null);
|
||||
}
|
||||
}
|
||||
|
@ -117,18 +117,18 @@ public final class ProtectedPromise extends DefaultChannelPromise {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ChannelPromise setSuccess(Void unused) {
|
||||
trySuccess(null);
|
||||
public ChannelPromise setSuccess(Void result) {
|
||||
trySuccess(result);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trySuccess(Void unused) {
|
||||
public boolean trySuccess(Void result) {
|
||||
if (awaitingPromises()) {
|
||||
++successfulCount;
|
||||
if (successfulCount == expectedCount && doneAllocating) {
|
||||
trySuccessInternal();
|
||||
return super.trySuccess(null);
|
||||
trySuccessInternal(result);
|
||||
return super.trySuccess(result);
|
||||
}
|
||||
// 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 final class ProtectedPromise extends DefaultChannelPromise {
|
|||
return false;
|
||||
}
|
||||
|
||||
private void trySuccessInternal() {
|
||||
private void trySuccessInternal(Void result) {
|
||||
for (int i = 0; i < unprotectedPromises.size(); ++i) {
|
||||
unprotectedPromises.get(i).trySuccess(null);
|
||||
unprotectedPromises.get(i).trySuccess(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ 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;
|
||||
|
@ -38,28 +37,27 @@ import org.junit.runners.JUnit4;
|
|||
/** Unit tests for {@link AltsContextUtil}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class AltsContextUtilTest {
|
||||
|
||||
private final ServerCall<?,?> call = mock(ServerCall.class);
|
||||
|
||||
@Test
|
||||
public void check_noAttributeValue() {
|
||||
assertFalse(AltsContextUtil.check(Attributes.newBuilder().build()));
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder().build());
|
||||
|
||||
assertFalse(AltsContextUtil.check(call));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void check_unexpectedAttributeValueType() {
|
||||
assertFalse(AltsContextUtil.check(Attributes.newBuilder()
|
||||
public void contains_unexpectedAttributeValueType() {
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new Object())
|
||||
.build()));
|
||||
.build());
|
||||
|
||||
assertFalse(AltsContextUtil.check(call));
|
||||
}
|
||||
|
||||
@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);
|
||||
public void contains_altsInternalContext() {
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
|
||||
.build());
|
||||
|
@ -68,67 +66,26 @@ public class AltsContextUtilTest {
|
|||
}
|
||||
|
||||
@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() {
|
||||
public void from_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))
|
||||
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());
|
||||
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());
|
||||
}
|
||||
public void from_noAttributeValue() {
|
||||
when(call.getAttributes()).thenReturn(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());
|
||||
AltsContextUtil.createFrom(call);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,7 +32,7 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public class AltsHandshakerStubTest {
|
||||
/** Mock status of handshaker service. */
|
||||
private enum Status {
|
||||
private static enum Status {
|
||||
OK,
|
||||
ERROR,
|
||||
COMPLETE
|
||||
|
@ -68,7 +68,6 @@ public class AltsHandshakerStubTest {
|
|||
fail("Exception expected");
|
||||
} catch (IOException ex) {
|
||||
assertThat(ex).hasMessageThat().contains("Received a terminating error");
|
||||
assertThat(ex.getCause()).hasMessageThat().contains("Root cause message");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +152,7 @@ public class AltsHandshakerStubTest {
|
|||
reader.onNext(resp.setOutFrames(req.getNext().getInBytes()).build());
|
||||
break;
|
||||
case ERROR:
|
||||
reader.onError(new RuntimeException("Root cause message"));
|
||||
reader.onError(new RuntimeException());
|
||||
break;
|
||||
case COMPLETE:
|
||||
reader.onCompleted();
|
||||
|
|
|
@ -354,29 +354,6 @@ public class AltsProtocolNegotiatorTest {
|
|||
.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());
|
||||
|
|
|
@ -68,7 +68,6 @@ public class FakeTsiHandshaker implements TsiHandshaker {
|
|||
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];
|
||||
|
@ -148,7 +147,7 @@ public class FakeTsiHandshaker implements TsiHandshaker {
|
|||
return;
|
||||
}
|
||||
|
||||
// Prepare the next message, if needed.
|
||||
// Prepare the next message, if neeeded.
|
||||
if (sendBuffer == null) {
|
||||
if (sendState.next() != receiveState) {
|
||||
// We're still waiting for bytes from the peer, so bail.
|
||||
|
|
|
@ -36,7 +36,7 @@ import javax.crypto.AEADBadTagException;
|
|||
|
||||
/** 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() {}
|
||||
|
||||
|
|
|
@ -7,10 +7,10 @@ description = 'gRPC: Android Integration Testing'
|
|||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = 'io.grpc.android.integrationtest'
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
|
@ -29,19 +29,16 @@ android {
|
|||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
compileSdkVersion 34
|
||||
compileSdkVersion 29
|
||||
|
||||
defaultConfig {
|
||||
applicationId "io.grpc.android.integrationtest"
|
||||
// Held back to 20 as Gradle fails to build at the 21 level. This is
|
||||
// presumably a Gradle bug that can be revisited later.
|
||||
// Maybe this issue: https://github.com/gradle/gradle/issues/20778
|
||||
minSdkVersion 20
|
||||
targetSdkVersion 33
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled = true
|
||||
multiDexEnabled true
|
||||
}
|
||||
buildTypes {
|
||||
debug { minifyEnabled false }
|
||||
|
@ -51,13 +48,9 @@ android {
|
|||
}
|
||||
}
|
||||
lintOptions {
|
||||
disable 'InvalidPackage', 'HardcodedText', 'UsingOnClickInXml',
|
||||
disable 'InvalidPackage', 'HardcodedText',
|
||||
'MissingClass' // https://github.com/grpc/grpc-java/issues/8799
|
||||
}
|
||||
packagingOptions {
|
||||
exclude 'META-INF/INDEX.LIST'
|
||||
exclude 'META-INF/io.netty.versions.properties'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -66,21 +59,23 @@ dependencies {
|
|||
implementation libraries.androidx.annotation
|
||||
implementation 'com.google.android.gms:play-services-base:18.0.1'
|
||||
|
||||
implementation project(':grpc-android'),
|
||||
project(':grpc-core'),
|
||||
implementation project(':grpc-auth'),
|
||||
project(':grpc-census'),
|
||||
project(':grpc-okhttp'),
|
||||
project(':grpc-protobuf-lite'),
|
||||
project(':grpc-stub'),
|
||||
project(':grpc-testing'),
|
||||
libraries.hdrhistogram,
|
||||
libraries.junit,
|
||||
libraries.truth,
|
||||
libraries.androidx.test.rules,
|
||||
libraries.opencensus.contrib.grpc.metrics
|
||||
|
||||
implementation (libraries.google.auth.oauth2Http) {
|
||||
exclude group: 'org.apache.httpcomponents'
|
||||
}
|
||||
|
||||
implementation (project(':grpc-services')) {
|
||||
exclude group: 'com.google.protobuf'
|
||||
exclude group: 'com.google.guava'
|
||||
}
|
||||
|
||||
compileOnly libraries.javax.annotation
|
||||
|
@ -108,7 +103,7 @@ import net.ltgt.gradle.errorprone.CheckSeverity
|
|||
|
||||
tasks.withType(JavaCompile).configureEach {
|
||||
options.compilerArgs += [
|
||||
"-Xlint:-cast",
|
||||
"-Xlint:-cast"
|
||||
]
|
||||
appendToProperty(it.options.errorprone.excludedPaths, ".*/R.java", "|")
|
||||
appendToProperty(
|
||||
|
@ -117,16 +112,4 @@ tasks.withType(JavaCompile).configureEach {
|
|||
"|")
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
|
@ -21,7 +21,3 @@
|
|||
|
||||
# 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$* {
|
||||
*;
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.grpc.android.integrationtest.test" >
|
||||
|
||||
<instrumentation
|
||||
android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
|
|
|
@ -25,12 +25,10 @@ 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.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -46,7 +44,6 @@ public class InteropInstrumentationTest {
|
|||
private String serverHostOverride;
|
||||
private boolean useTestCa;
|
||||
private String testCase;
|
||||
private ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
@ -104,22 +101,26 @@ public class InteropInstrumentationTest {
|
|||
}
|
||||
|
||||
private void runTest(String testCase) throws Exception {
|
||||
final SettableFuture<String> resultFuture = SettableFuture.create();
|
||||
InteropTask.Listener listener =
|
||||
new Listener() {
|
||||
@Override
|
||||
public void onComplete(String result) {
|
||||
resultFuture.set(result);
|
||||
}
|
||||
};
|
||||
InputStream testCa;
|
||||
if (useTestCa) {
|
||||
testCa = ApplicationProvider.getApplicationContext().getResources().openRawResource(R.raw.ca);
|
||||
} else {
|
||||
testCa = null;
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,129 +0,0 @@
|
|||
/*
|
||||
* 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.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
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 ActivityTestRule<TesterActivity> activityRule =
|
||||
new ActivityTestRule<TesterActivity>(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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service used to obtain stats for verifying LB behavior.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.LoadBalancerStatsRequest,
|
||||
|
@ -89,21 +92,6 @@ public final class LoadBalancerStatsServiceGrpc {
|
|||
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<LoadBalancerStatsServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -224,46 +212,6 @@ public final class LoadBalancerStatsServiceGrpc {
|
|||
* A service used to obtain stats for verifying LB behavior.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class LoadBalancerStatsServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Gets the backend distribution for RPCs sent by a test client.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Gets the accumulated stats for RPCs sent by a test client.
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A service used to obtain stats for verifying LB behavior.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class LoadBalancerStatsServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingStub> {
|
||||
private LoadBalancerStatsServiceBlockingStub(
|
||||
|
|
|
@ -4,12 +4,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
|
||||
/**
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.MetricsService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.MetricsService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Metrics.EmptyMessage,
|
||||
|
@ -86,21 +89,6 @@ public final class MetricsServiceGrpc {
|
|||
return MetricsServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static MetricsServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -211,46 +199,6 @@ public final class MetricsServiceGrpc {
|
|||
/**
|
||||
* A stub to allow clients to do synchronous rpc calls to service MetricsService.
|
||||
*/
|
||||
public static final class MetricsServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<MetricsServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Returns the values of all the gauges that are currently being maintained by
|
||||
* the service
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Metrics.GaugeResponse>
|
||||
getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request) {
|
||||
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
|
||||
getChannel(), getGetAllGaugesMethod(), getCallOptions(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Returns the value of one gauge
|
||||
* </pre>
|
||||
*/
|
||||
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<MetricsServiceBlockingStub> {
|
||||
private MetricsServiceBlockingStub(
|
||||
|
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service used to control reconnect server.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.ReconnectService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.ReconnectService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ReconnectParams,
|
||||
|
@ -89,21 +92,6 @@ public final class ReconnectServiceGrpc {
|
|||
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<ReconnectServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -212,40 +200,6 @@ public final class ReconnectServiceGrpc {
|
|||
* A service used to control reconnect server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class ReconnectServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingV2Stub> {
|
||||
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.
|
||||
* <pre>
|
||||
* A service used to control reconnect server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class ReconnectServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingStub> {
|
||||
private ReconnectServiceBlockingStub(
|
||||
|
|
|
@ -8,12 +8,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* performance with various types of payload.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.TestService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.TestService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
|
||||
|
@ -270,21 +273,6 @@ public final class TestServiceGrpc {
|
|||
return TestServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static TestServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -555,125 +543,6 @@ public final class TestServiceGrpc {
|
|||
* performance with various types of payload.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class TestServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* One empty request followed by one empty response.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* One request followed by one response.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* One request followed by a sequence of responses (streamed download).
|
||||
* The server returns the payload with client desired type and sizes.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
|
||||
streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) {
|
||||
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
|
||||
getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* A sequence of requests followed by one response (streamed upload).
|
||||
* The server returns the aggregated size of client payload as the result.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingInputCallRequest, io.grpc.testing.integration.Messages.StreamingInputCallResponse>
|
||||
streamingInputCall() {
|
||||
return io.grpc.stub.ClientCalls.blockingClientStreamingCall(
|
||||
getChannel(), getStreamingInputCallMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
|
||||
fullDuplexCall() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getFullDuplexCallMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
|
||||
halfDuplexCall() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getHalfDuplexCallMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* The test server will not implement this method. It will be used
|
||||
* to test the behavior when clients call unimplemented methods.
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A simple service to test the various types of RPCs and experiment with
|
||||
* performance with various types of payload.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class TestServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingStub> {
|
||||
private TestServiceBlockingStub(
|
||||
|
|
|
@ -8,12 +8,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* that case.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.UnimplementedService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.UnimplementedService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
|
||||
|
@ -60,21 +63,6 @@ public final class UnimplementedServiceGrpc {
|
|||
return UnimplementedServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static UnimplementedServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -178,37 +166,6 @@ public final class UnimplementedServiceGrpc {
|
|||
* that case.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class UnimplementedServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* A call that no server should implement
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A simple service NOT implemented at servers so clients can test for
|
||||
* that case.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class UnimplementedServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingStub> {
|
||||
private UnimplementedServiceBlockingStub(
|
||||
|
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service to dynamically update the configuration of an xDS test client.
|
||||
* </pre>
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler",
|
||||
comments = "Source: grpc/testing/test.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class XdsUpdateClientConfigureServiceGrpc {
|
||||
|
||||
private XdsUpdateClientConfigureServiceGrpc() {}
|
||||
|
||||
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ClientConfigureRequest,
|
||||
|
@ -59,21 +62,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
|
|||
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<XdsUpdateClientConfigureServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -173,36 +161,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
|
|||
* A service to dynamically update the configuration of an xDS test client.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateClientConfigureServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Update the tes client's configuration.
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A service to dynamically update the configuration of an xDS test client.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateClientConfigureServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingStub> {
|
||||
private XdsUpdateClientConfigureServiceBlockingStub(
|
||||
|
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service to remotely control health status of an xDS test server.
|
||||
* </pre>
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler",
|
||||
comments = "Source: grpc/testing/test.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class XdsUpdateHealthServiceGrpc {
|
||||
|
||||
private XdsUpdateHealthServiceGrpc() {}
|
||||
|
||||
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
|
||||
|
@ -89,21 +92,6 @@ public final class XdsUpdateHealthServiceGrpc {
|
|||
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<XdsUpdateHealthServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -212,40 +200,6 @@ public final class XdsUpdateHealthServiceGrpc {
|
|||
* A service to remotely control health status of an xDS test server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateHealthServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingV2Stub> {
|
||||
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.
|
||||
* <pre>
|
||||
* A service to remotely control health status of an xDS test server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateHealthServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingStub> {
|
||||
private XdsUpdateHealthServiceBlockingStub(
|
||||
|
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service used to obtain stats for verifying LB behavior.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.LoadBalancerStatsRequest,
|
||||
|
@ -89,21 +92,6 @@ public final class LoadBalancerStatsServiceGrpc {
|
|||
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<LoadBalancerStatsServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -224,46 +212,6 @@ public final class LoadBalancerStatsServiceGrpc {
|
|||
* A service used to obtain stats for verifying LB behavior.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class LoadBalancerStatsServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Gets the backend distribution for RPCs sent by a test client.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Gets the accumulated stats for RPCs sent by a test client.
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A service used to obtain stats for verifying LB behavior.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class LoadBalancerStatsServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingStub> {
|
||||
private LoadBalancerStatsServiceBlockingStub(
|
||||
|
|
|
@ -4,12 +4,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
|
||||
/**
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.MetricsService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.MetricsService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Metrics.EmptyMessage,
|
||||
|
@ -86,21 +89,6 @@ public final class MetricsServiceGrpc {
|
|||
return MetricsServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static MetricsServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -211,46 +199,6 @@ public final class MetricsServiceGrpc {
|
|||
/**
|
||||
* A stub to allow clients to do synchronous rpc calls to service MetricsService.
|
||||
*/
|
||||
public static final class MetricsServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<MetricsServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Returns the values of all the gauges that are currently being maintained by
|
||||
* the service
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Metrics.GaugeResponse>
|
||||
getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request) {
|
||||
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
|
||||
getChannel(), getGetAllGaugesMethod(), getCallOptions(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Returns the value of one gauge
|
||||
* </pre>
|
||||
*/
|
||||
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<MetricsServiceBlockingStub> {
|
||||
private MetricsServiceBlockingStub(
|
||||
|
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service used to control reconnect server.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.ReconnectService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.ReconnectService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ReconnectParams,
|
||||
|
@ -89,21 +92,6 @@ public final class ReconnectServiceGrpc {
|
|||
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<ReconnectServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -212,40 +200,6 @@ public final class ReconnectServiceGrpc {
|
|||
* A service used to control reconnect server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class ReconnectServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingV2Stub> {
|
||||
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.
|
||||
* <pre>
|
||||
* A service used to control reconnect server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class ReconnectServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingStub> {
|
||||
private ReconnectServiceBlockingStub(
|
||||
|
|
|
@ -8,12 +8,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* performance with various types of payload.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.TestService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.TestService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
|
||||
|
@ -270,21 +273,6 @@ public final class TestServiceGrpc {
|
|||
return TestServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static TestServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -555,125 +543,6 @@ public final class TestServiceGrpc {
|
|||
* performance with various types of payload.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class TestServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* One empty request followed by one empty response.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* One request followed by one response.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* One request followed by a sequence of responses (streamed download).
|
||||
* The server returns the payload with client desired type and sizes.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
|
||||
streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) {
|
||||
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
|
||||
getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* A sequence of requests followed by one response (streamed upload).
|
||||
* The server returns the aggregated size of client payload as the result.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingInputCallRequest, io.grpc.testing.integration.Messages.StreamingInputCallResponse>
|
||||
streamingInputCall() {
|
||||
return io.grpc.stub.ClientCalls.blockingClientStreamingCall(
|
||||
getChannel(), getStreamingInputCallMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
|
||||
fullDuplexCall() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getFullDuplexCallMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* 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.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
|
||||
halfDuplexCall() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getHalfDuplexCallMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* The test server will not implement this method. It will be used
|
||||
* to test the behavior when clients call unimplemented methods.
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A simple service to test the various types of RPCs and experiment with
|
||||
* performance with various types of payload.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class TestServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingStub> {
|
||||
private TestServiceBlockingStub(
|
||||
|
|
|
@ -8,12 +8,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* that case.
|
||||
* </pre>
|
||||
*/
|
||||
@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 java.lang.String SERVICE_NAME = "grpc.testing.UnimplementedService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.UnimplementedService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
|
||||
|
@ -60,21 +63,6 @@ public final class UnimplementedServiceGrpc {
|
|||
return UnimplementedServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static UnimplementedServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -178,37 +166,6 @@ public final class UnimplementedServiceGrpc {
|
|||
* that case.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class UnimplementedServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* A call that no server should implement
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A simple service NOT implemented at servers so clients can test for
|
||||
* that case.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class UnimplementedServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingStub> {
|
||||
private UnimplementedServiceBlockingStub(
|
||||
|
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service to dynamically update the configuration of an xDS test client.
|
||||
* </pre>
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler",
|
||||
comments = "Source: grpc/testing/test.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class XdsUpdateClientConfigureServiceGrpc {
|
||||
|
||||
private XdsUpdateClientConfigureServiceGrpc() {}
|
||||
|
||||
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ClientConfigureRequest,
|
||||
|
@ -59,21 +62,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
|
|||
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<XdsUpdateClientConfigureServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -173,36 +161,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
|
|||
* A service to dynamically update the configuration of an xDS test client.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateClientConfigureServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingV2Stub> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Update the tes client's configuration.
|
||||
* </pre>
|
||||
*/
|
||||
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.
|
||||
* <pre>
|
||||
* A service to dynamically update the configuration of an xDS test client.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateClientConfigureServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingStub> {
|
||||
private XdsUpdateClientConfigureServiceBlockingStub(
|
||||
|
|
|
@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
* A service to remotely control health status of an xDS test server.
|
||||
* </pre>
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler",
|
||||
comments = "Source: grpc/testing/test.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class XdsUpdateHealthServiceGrpc {
|
||||
|
||||
private XdsUpdateHealthServiceGrpc() {}
|
||||
|
||||
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
|
||||
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
|
||||
|
||||
// Static method descriptors that strictly reflect the proto.
|
||||
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
|
||||
|
@ -89,21 +92,6 @@ public final class XdsUpdateHealthServiceGrpc {
|
|||
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<XdsUpdateHealthServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub>() {
|
||||
@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
|
||||
*/
|
||||
|
@ -212,40 +200,6 @@ public final class XdsUpdateHealthServiceGrpc {
|
|||
* A service to remotely control health status of an xDS test server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateHealthServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingV2Stub> {
|
||||
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.
|
||||
* <pre>
|
||||
* A service to remotely control health status of an xDS test server.
|
||||
* </pre>
|
||||
*/
|
||||
public static final class XdsUpdateHealthServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingStub> {
|
||||
private XdsUpdateHealthServiceBlockingStub(
|
||||
|
|
|
@ -1,22 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
package="io.grpc.android.integrationtest" >
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<!-- For UDS -->
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-sdk tools:overrideLibrary="io.grpc.android"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Base.V7.Theme.AppCompat.Light"
|
||||
android:name="androidx.multidex.MultiDexApplication">
|
||||
android:name="androidx.multidex.MultiDexApplication" >
|
||||
<activity
|
||||
android:name=".TesterActivity"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2023 The gRPC Authors
|
||||
* 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.
|
||||
|
@ -16,36 +16,49 @@
|
|||
|
||||
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.util.concurrent.Callable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import org.junit.AssumptionViolatedException;
|
||||
|
||||
/**
|
||||
* Used to run a single test case against a channel in a separate thread.
|
||||
*/
|
||||
public class TestCallable implements Callable<String> {
|
||||
private final ManagedChannel channel;
|
||||
private final String testCase;
|
||||
|
||||
/** AsyncTask for interop test cases. */
|
||||
final class InteropTask extends AsyncTask<Void, Void, String> {
|
||||
private static final String LOG_TAG = "GrpcInteropTask";
|
||||
|
||||
interface Listener {
|
||||
void onComplete(String result);
|
||||
}
|
||||
|
||||
static final String SUCCESS_MESSAGE = "Success!";
|
||||
|
||||
public TestCallable(ManagedChannel channel, String testCase) {
|
||||
this.channel = channel;
|
||||
private final WeakReference<Listener> listenerReference;
|
||||
private final String testCase;
|
||||
private final Tester tester;
|
||||
|
||||
InteropTask(
|
||||
Listener listener,
|
||||
ManagedChannel channel,
|
||||
String testCase) {
|
||||
this.listenerReference = new WeakReference<Listener>(listener);
|
||||
this.testCase = testCase;
|
||||
this.tester = new Tester(channel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String call() {
|
||||
Tester tester = new Tester(channel);
|
||||
protected void onPreExecute() {
|
||||
tester.setUp();
|
||||
}
|
||||
|
||||
@SuppressWarnings("Finally")
|
||||
@Override
|
||||
protected String doInBackground(Void... ignored) {
|
||||
try {
|
||||
runTest(tester, testCase);
|
||||
runTest(testCase);
|
||||
return SUCCESS_MESSAGE;
|
||||
} catch (Throwable t) {
|
||||
// Print the stack trace to logcat.
|
||||
|
@ -65,7 +78,7 @@ public class TestCallable implements Callable<String> {
|
|||
}
|
||||
}
|
||||
|
||||
private void runTest(Tester tester, String testCase) throws Exception {
|
||||
private void runTest(String testCase) throws Exception {
|
||||
Log.i(LOG_TAG, "Running test case: " + testCase);
|
||||
if ("empty_unary".equals(testCase)) {
|
||||
tester.emptyUnary();
|
||||
|
@ -125,6 +138,14 @@ public class TestCallable implements Callable<String> {
|
|||
}
|
||||
}
|
||||
|
||||
@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) {
|
|
@ -18,7 +18,6 @@ package io.grpc.android.integrationtest;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.LocalSocketAddress.Namespace;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
@ -31,31 +30,20 @@ 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 {
|
||||
implements ProviderInstaller.ProviderInstallListener, InteropTask.Listener {
|
||||
private static final String LOG_TAG = "GrpcTesterActivity";
|
||||
|
||||
private List<Button> buttons;
|
||||
private EditText hostEdit;
|
||||
private EditText portEdit;
|
||||
private CheckBox useUdsCheckBox;
|
||||
private EditText udsEdit;
|
||||
private TextView resultText;
|
||||
private CheckBox testCertCheckBox;
|
||||
|
||||
private UdsTcpEndpointConnector endpointConnector;
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -69,26 +57,12 @@ public class TesterActivity extends AppCompatActivity
|
|||
|
||||
hostEdit = (EditText) findViewById(R.id.host_edit_text);
|
||||
portEdit = (EditText) findViewById(R.id.port_edit_text);
|
||||
useUdsCheckBox = (CheckBox) findViewById(R.id.use_uds_checkbox);
|
||||
udsEdit = (EditText) findViewById(R.id.uds_proxy_edit_text);
|
||||
resultText = (TextView) findViewById(R.id.grpc_response_text);
|
||||
testCertCheckBox = (CheckBox) findViewById(R.id.test_cert_checkbox);
|
||||
|
||||
ProviderInstaller.installIfNeededAsync(this, this);
|
||||
// Disable buttons until the security provider installing finishes.
|
||||
enableButtons(false);
|
||||
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
/** Click handler for unix domain socket. */
|
||||
public void enableUds(View view) {
|
||||
boolean enabled = ((CheckBox) view).isChecked();
|
||||
udsEdit.setEnabled(enabled);
|
||||
testCertCheckBox.setEnabled(!enabled);
|
||||
if (enabled) {
|
||||
testCertCheckBox.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void startEmptyUnary(View view) {
|
||||
|
@ -117,6 +91,12 @@ public class TesterActivity extends AppCompatActivity
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(String result) {
|
||||
resultText.setText(result);
|
||||
enableButtons(true);
|
||||
}
|
||||
|
||||
private void startTest(String testCase) {
|
||||
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
|
||||
hostEdit.getWindowToken(), 0);
|
||||
|
@ -126,9 +106,6 @@ public class TesterActivity extends AppCompatActivity
|
|||
String host = hostEdit.getText().toString();
|
||||
String portStr = portEdit.getText().toString();
|
||||
int port = TextUtils.isEmpty(portStr) ? 8080 : Integer.valueOf(portStr);
|
||||
boolean udsEnabled = useUdsCheckBox.isChecked();
|
||||
String udsPath =
|
||||
TextUtils.isEmpty(udsEdit.getText()) ? "default" : udsEdit.getText().toString();
|
||||
|
||||
String serverHostOverride;
|
||||
InputStream testCert;
|
||||
|
@ -139,39 +116,10 @@ public class TesterActivity extends AppCompatActivity
|
|||
serverHostOverride = null;
|
||||
testCert = null;
|
||||
}
|
||||
ManagedChannel channel =
|
||||
TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, true, testCert);
|
||||
|
||||
// Create Channel
|
||||
ManagedChannel channel;
|
||||
if (udsEnabled) {
|
||||
channel = UdsChannelBuilder.forPath(udsPath, Namespace.ABSTRACT).build();
|
||||
} else {
|
||||
channel = TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, true, testCert);
|
||||
}
|
||||
|
||||
// Port-forward uds local port to server exposing tcp endpoint.
|
||||
if (udsEnabled) {
|
||||
endpointConnector = new UdsTcpEndpointConnector(udsPath, host, port);
|
||||
try {
|
||||
endpointConnector.start();
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "Failed to start UDS-TCP Endpoint Connector.");
|
||||
}
|
||||
}
|
||||
|
||||
// Start Test.
|
||||
String result = null;
|
||||
try {
|
||||
result = executor.submit(new TestCallable(channel, testCase)).get();
|
||||
} catch (ExecutionException | InterruptedException e) {
|
||||
result = e.getMessage();
|
||||
} finally {
|
||||
if (endpointConnector != null) {
|
||||
endpointConnector.shutDown();
|
||||
endpointConnector = null;
|
||||
}
|
||||
resultText.setText(result);
|
||||
enableButtons(true);
|
||||
}
|
||||
new InteropTask(this, channel, testCase).execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,198 +0,0 @@
|
|||
/*
|
||||
* 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 java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import android.net.LocalServerSocket;
|
||||
import android.net.LocalSocket;
|
||||
import android.util.Log;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Funnels traffic between a given UDS endpoint and a local TCP endpoint. A client binds to the UDS
|
||||
* endpoint, but effectively communicates with the TCP endpoint.
|
||||
*/
|
||||
public class UdsTcpEndpointConnector {
|
||||
|
||||
private static final String LOG_TAG = "EndpointConnector";
|
||||
|
||||
// Discard-policy, to allow dropping tasks that were received immediately after shutDown()
|
||||
private final ThreadPoolExecutor executor =
|
||||
new ThreadPoolExecutor(
|
||||
5,
|
||||
10,
|
||||
1,
|
||||
SECONDS,
|
||||
new LinkedBlockingQueue<>(),
|
||||
new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
|
||||
private final String udsPath;
|
||||
|
||||
private final String host;
|
||||
private final int port;
|
||||
private InetSocketAddress socketAddress;
|
||||
|
||||
private LocalServerSocket clientAcceptor;
|
||||
|
||||
private volatile boolean shutDownRequested = false;
|
||||
private volatile boolean shutDownComplete = false;
|
||||
|
||||
/** Listen on udsPath and forward connections to host:port. */
|
||||
public UdsTcpEndpointConnector(String udsPath, String host, int port) {
|
||||
this.udsPath = udsPath;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
/** Start listening and accept connections. */
|
||||
public void start() throws IOException {
|
||||
clientAcceptor = new LocalServerSocket(udsPath);
|
||||
executor.execute(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Log.i(LOG_TAG, "Starting connection from " + udsPath + " to " + socketAddress);
|
||||
socketAddress = new InetSocketAddress(host, port);
|
||||
while (!shutDownRequested) {
|
||||
try {
|
||||
LocalSocket clientSocket = clientAcceptor.accept();
|
||||
if (shutDownRequested) {
|
||||
// Check if shut down during blocking accept().
|
||||
clientSocket.close();
|
||||
shutDownComplete = true;
|
||||
break;
|
||||
}
|
||||
Socket serverSocket = new Socket();
|
||||
serverSocket.connect(socketAddress);
|
||||
startWorkers(clientSocket, serverSocket);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Stop listening and release resources. */
|
||||
public void shutDown() {
|
||||
Log.i(LOG_TAG, "Shutting down connection from " + udsPath + " to " + socketAddress);
|
||||
shutDownRequested = true;
|
||||
|
||||
try {
|
||||
// Upon clientAcceptor.close(), clientAcceptor.accept() continues to block.
|
||||
// Thus, once shutDownRequested=true, must send a connection request to unblock accept().
|
||||
LocalSocket localSocket = new LocalSocket();
|
||||
localSocket.connect(clientAcceptor.getLocalSocketAddress());
|
||||
localSocket.close();
|
||||
clientAcceptor.close();
|
||||
} catch (IOException e) {
|
||||
Log.w(LOG_TAG, "Failed to close LocalServerSocket", e);
|
||||
}
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
public boolean isShutdown() {
|
||||
return shutDownComplete && executor.isShutdown();
|
||||
}
|
||||
|
||||
private void startWorkers(LocalSocket clientSocket, Socket serverSocket) throws IOException {
|
||||
DataInputStream clientIn = new DataInputStream(clientSocket.getInputStream());
|
||||
DataOutputStream clientOut = new DataOutputStream(serverSocket.getOutputStream());
|
||||
DataInputStream serverIn = new DataInputStream(serverSocket.getInputStream());
|
||||
DataOutputStream serverOut = new DataOutputStream(clientSocket.getOutputStream());
|
||||
|
||||
AtomicInteger completionCount = new AtomicInteger(0);
|
||||
StreamConnector.Listener cleanupListener =
|
||||
new StreamConnector.Listener() {
|
||||
@Override
|
||||
public void onFinished() {
|
||||
if (completionCount.incrementAndGet() == 2) {
|
||||
try {
|
||||
serverSocket.close();
|
||||
clientSocket.close();
|
||||
} catch (IOException e) {
|
||||
Log.e(LOG_TAG, "Failed to clean up connected sockets.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
executor.execute(new StreamConnector(clientIn, clientOut).addListener(cleanupListener));
|
||||
executor.execute(new StreamConnector(serverIn, serverOut).addListener(cleanupListener));
|
||||
}
|
||||
|
||||
/**
|
||||
* Funnels everything that comes in to a DataInputStream into an DataOutputStream, until the
|
||||
* DataInputStream is closed. (detected by IOException).
|
||||
*/
|
||||
private static final class StreamConnector implements Runnable {
|
||||
|
||||
interface Listener {
|
||||
void onFinished();
|
||||
}
|
||||
|
||||
private static final int BUFFER_SIZE = 1000;
|
||||
|
||||
private final DataInputStream in;
|
||||
private final DataOutputStream out;
|
||||
private final byte[] buffer = new byte[BUFFER_SIZE];
|
||||
|
||||
private boolean finished = false;
|
||||
|
||||
private final Collection<Listener> listeners = new ArrayList<>();
|
||||
|
||||
StreamConnector(DataInputStream in, DataOutputStream out) {
|
||||
this.in = in;
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
StreamConnector addListener(Listener listener) {
|
||||
listeners.add(listener);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!finished) {
|
||||
int bytesRead;
|
||||
try {
|
||||
bytesRead = in.read(buffer);
|
||||
if (bytesRead == -1) {
|
||||
finished = true;
|
||||
out.close();
|
||||
continue;
|
||||
}
|
||||
out.write(buffer, 0, bytesRead);
|
||||
} catch (IOException e) {
|
||||
finished = true;
|
||||
}
|
||||
}
|
||||
for (StreamConnector.Listener listener : listeners) {
|
||||
listener.onFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="#AAA" android:state_focused="false"/>
|
||||
<item android:color="#000" android:state_focused="true"/>
|
||||
</selector>
|
|
@ -28,28 +28,6 @@
|
|||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<CheckBox android:id="@+id/use_uds_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="enableUds"
|
||||
android:textColor="@color/focus"
|
||||
android:text="Use UDS (SSL not supported)"
|
||||
tools:ignore="OnClick"
|
||||
/>
|
||||
<EditText
|
||||
android:id="@+id/uds_proxy_edit_text"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:enabled="false"
|
||||
android:inputType="text"
|
||||
android:hint="Enter Unix Domain Socket Abstract Namespace Address"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -58,7 +36,6 @@
|
|||
<CheckBox android:id="@+id/test_cert_checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/focus"
|
||||
android:text="Use Test Cert"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -2,45 +2,43 @@ plugins {
|
|||
id "maven-publish"
|
||||
|
||||
id "com.android.library"
|
||||
id "digital.wup.android-maven-publish"
|
||||
}
|
||||
|
||||
description = 'gRPC: Android'
|
||||
|
||||
android {
|
||||
namespace = 'io.grpc.android'
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
compileSdkVersion 34
|
||||
compileSdkVersion 29
|
||||
defaultConfig {
|
||||
minSdkVersion 22
|
||||
targetSdkVersion 33
|
||||
consumerProguardFiles "proguard-rules.txt"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
lintOptions { abortOnError = true }
|
||||
publishing {
|
||||
singleVariant('release') {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
lintOptions { abortOnError true }
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api project(':grpc-api')
|
||||
implementation project(':grpc-core')
|
||||
api project(':grpc-core')
|
||||
implementation libraries.guava
|
||||
testImplementation project('::grpc-okhttp')
|
||||
testImplementation libraries.androidx.test.core
|
||||
testImplementation libraries.junit
|
||||
testImplementation libraries.robolectric
|
||||
testImplementation (libraries.robolectric) {
|
||||
// Unreleased change: https://github.com/robolectric/robolectric/pull/5432
|
||||
exclude group: 'com.google.auto.service', module: 'auto-service'
|
||||
}
|
||||
testImplementation libraries.truth
|
||||
}
|
||||
|
||||
|
@ -74,9 +72,10 @@ tasks.register("sourcesJar", Jar) {
|
|||
publishing {
|
||||
publications {
|
||||
maven {
|
||||
afterEvaluate {
|
||||
from components.release
|
||||
}
|
||||
from components.android
|
||||
|
||||
artifact javadocJar
|
||||
artifact sourcesJar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
-keepclassmembers class io.grpc.okhttp.OkHttpChannelBuilder {
|
||||
io.grpc.okhttp.OkHttpChannelBuilder forTarget(java.lang.String);
|
||||
io.grpc.okhttp.OkHttpChannelBuilder scheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
|
||||
io.grpc.okhttp.OkHttpChannelBuilder sslSocketFactory(javax.net.ssl.SSLSocketFactory);
|
||||
io.grpc.okhttp.OkHttpChannelBuilder transportExecutor(java.util.concurrent.Executor);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="io.grpc.android">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ import android.util.Log;
|
|||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.errorprone.annotations.InlineMe;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.ClientCall;
|
||||
import io.grpc.ConnectivityState;
|
||||
|
@ -42,6 +41,7 @@ import io.grpc.MethodDescriptor;
|
|||
import io.grpc.internal.GrpcUtil;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
|
||||
/**
|
||||
* Builds a {@link ManagedChannel} that, when provided with a {@link Context}, will automatically
|
||||
|
@ -156,7 +156,6 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI.
|
||||
protected ManagedChannelBuilder<?> delegate() {
|
||||
return delegateBuilder;
|
||||
}
|
||||
|
@ -217,6 +216,7 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
|
|||
connectivityManager.registerDefaultNetworkCallback(defaultNetworkCallback);
|
||||
unregisterRunnable =
|
||||
new Runnable() {
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void run() {
|
||||
connectivityManager.unregisterNetworkCallback(defaultNetworkCallback);
|
||||
|
@ -230,6 +230,7 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
|
|||
context.registerReceiver(networkReceiver, networkIntentFilter);
|
||||
unregisterRunnable =
|
||||
new Runnable() {
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void run() {
|
||||
context.unregisterReceiver(networkReceiver);
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import android.net.LocalSocketAddress.Namespace;
|
||||
import io.grpc.ChannelCredentials;
|
||||
import io.grpc.ExperimentalApi;
|
||||
import io.grpc.InsecureChannelCredentials;
|
||||
import io.grpc.ManagedChannelBuilder;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
/**
|
||||
* Creates a UDS channel by passing in a specialized SocketFactory into an OkHttpChannelBuilder. The
|
||||
* UdsSockets produced by this factory communicate over Android's LocalSockets.
|
||||
*
|
||||
* <p>Example Usage <code>
|
||||
* Channel channel = UdsChannelBuilder.forPath("/data/data/my.app/app.socket",
|
||||
* Namespace.FILESYSTEM).build();
|
||||
* stub = MyService.newStub(channel);
|
||||
* </code>
|
||||
*
|
||||
* <p>This class uses a safe-for-production hack to workaround NameResolver's inability to safely
|
||||
* return non-IP SocketAddress types. The hack simply ignores the name resolver results and connects
|
||||
* to the UDS name provided during construction instead. This class is expected to be replaced with
|
||||
* a `unix:` name resolver when possible.
|
||||
*/
|
||||
@ExperimentalApi("A stopgap. Not intended to be stabilized")
|
||||
public final class UdsChannelBuilder {
|
||||
@Nullable
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static final Class<? extends ManagedChannelBuilder> OKHTTP_CHANNEL_BUILDER_CLASS =
|
||||
findOkHttp();
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private static Class<? extends ManagedChannelBuilder> findOkHttp() {
|
||||
try {
|
||||
return Class.forName("io.grpc.okhttp.OkHttpChannelBuilder")
|
||||
.asSubclass(ManagedChannelBuilder.class);
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a channel to the UDS endpoint specified by the file-path.
|
||||
*
|
||||
* @param path unix file system path to use for Unix Domain Socket.
|
||||
* @param namespace the type of the namespace that the path belongs to.
|
||||
*/
|
||||
public static ManagedChannelBuilder<?> forPath(String path, Namespace namespace) {
|
||||
if (OKHTTP_CHANNEL_BUILDER_CLASS == null) {
|
||||
throw new UnsupportedOperationException("OkHttpChannelBuilder not found on the classpath");
|
||||
}
|
||||
try {
|
||||
// Target 'dns:///127.0.0.1' is unused, but necessary as an argument for OkHttpChannelBuilder.
|
||||
// An IP address is used instead of localhost to avoid a DNS lookup (see #11442). This should
|
||||
// work even if IPv4 is unavailable, as the DNS resolver doesn't need working IPv4 to parse an
|
||||
// IPv4 address. Unavailable IPv4 fails when we connect(), not at resolution time.
|
||||
// TLS is unsupported because Conscrypt assumes the platform Socket implementation to improve
|
||||
// performance by using the file descriptor directly.
|
||||
Object o = OKHTTP_CHANNEL_BUILDER_CLASS
|
||||
.getMethod("forTarget", String.class, ChannelCredentials.class)
|
||||
.invoke(null, "dns:///127.0.0.1", InsecureChannelCredentials.create());
|
||||
ManagedChannelBuilder<?> builder = OKHTTP_CHANNEL_BUILDER_CLASS.cast(o);
|
||||
OKHTTP_CHANNEL_BUILDER_CLASS
|
||||
.getMethod("socketFactory", SocketFactory.class)
|
||||
.invoke(builder, new UdsSocketFactory(path, namespace));
|
||||
return builder;
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException("Failed to create OkHttpChannelBuilder", e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("Failed to create OkHttpChannelBuilder", e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException("Failed to create OkHttpChannelBuilder", e);
|
||||
}
|
||||
}
|
||||
|
||||
private UdsChannelBuilder() {}
|
||||
}
|
|
@ -1,312 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import android.net.LocalSocket;
|
||||
import android.net.LocalSocketAddress;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.FilterOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
/**
|
||||
* Adapter from Android's LocalSocket to Socket. This class is only needed by grpc-okhttp, so the
|
||||
* adapter only has to support the things that grcp-okhttp uses. It is fine to support trivial
|
||||
* things unused by the transport, to be less likely to break as the transport usage changes, but it
|
||||
* is also unnecessary. It's okay to stretch the truth or lie when necessary. For example, little
|
||||
* hurts with {@link #setTcpNoDelay(boolean)} being a noop since unix domain sockets don't have such
|
||||
* unnecessary delays.
|
||||
*/
|
||||
@SuppressWarnings("UnsynchronizedOverridesSynchronized") // Rely on LocalSocket's synchronization
|
||||
class UdsSocket extends Socket {
|
||||
|
||||
private final LocalSocket localSocket;
|
||||
private final LocalSocketAddress localSocketAddress;
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean closed = false;
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean inputShutdown = false;
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean outputShutdown = false;
|
||||
|
||||
public UdsSocket(LocalSocketAddress localSocketAddress) {
|
||||
this.localSocketAddress = localSocketAddress;
|
||||
localSocket = new LocalSocket();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(SocketAddress bindpoint) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void close() throws IOException {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
if (!inputShutdown) {
|
||||
shutdownInput();
|
||||
}
|
||||
if (!outputShutdown) {
|
||||
shutdownOutput();
|
||||
}
|
||||
localSocket.close();
|
||||
closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(SocketAddress endpoint) throws IOException {
|
||||
localSocket.connect(localSocketAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connect(SocketAddress endpoint, int timeout) throws IOException {
|
||||
localSocket.connect(localSocketAddress, timeout);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketChannel getChannel() {
|
||||
throw new UnsupportedOperationException("getChannel() not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetAddress getInetAddress() {
|
||||
throw new UnsupportedOperationException("getInetAddress() not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new FilterInputStream(localSocket.getInputStream()) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
UdsSocket.this.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getKeepAlive() {
|
||||
throw new UnsupportedOperationException("Unsupported operation getKeepAlive()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public InetAddress getLocalAddress() {
|
||||
throw new UnsupportedOperationException("Unsupported operation getLocalAddress()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLocalPort() {
|
||||
throw new UnsupportedOperationException("Unsupported operation getLocalPort()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketAddress getLocalSocketAddress() {
|
||||
return new SocketAddress() {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getOOBInline() {
|
||||
throw new UnsupportedOperationException("Unsupported operation getOOBInline()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return new FilterOutputStream(localSocket.getOutputStream()) {
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
UdsSocket.this.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
throw new UnsupportedOperationException("Unsupported operation getPort()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getReceiveBufferSize() throws SocketException {
|
||||
try {
|
||||
return localSocket.getReceiveBufferSize();
|
||||
} catch (IOException e) {
|
||||
throw toSocketException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocketAddress getRemoteSocketAddress() {
|
||||
return new SocketAddress() {};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getReuseAddress() {
|
||||
throw new UnsupportedOperationException("Unsupported operation getReuseAddress()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSendBufferSize() throws SocketException {
|
||||
try {
|
||||
return localSocket.getSendBufferSize();
|
||||
} catch (IOException e) {
|
||||
throw toSocketException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoLinger() {
|
||||
return -1; // unsupported
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSoTimeout() throws SocketException {
|
||||
try {
|
||||
return localSocket.getSoTimeout();
|
||||
} catch (IOException e) {
|
||||
throw toSocketException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getTcpNoDelay() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTrafficClass() {
|
||||
throw new UnsupportedOperationException("Unsupported operation getTrafficClass()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBound() {
|
||||
return localSocket.isBound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConnected() {
|
||||
return localSocket.isConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isInputShutdown() {
|
||||
return inputShutdown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isOutputShutdown() {
|
||||
return outputShutdown;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendUrgentData(int data) {
|
||||
throw new UnsupportedOperationException("Unsupported operation sendUrgentData()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setKeepAlive(boolean on) {
|
||||
throw new UnsupportedOperationException("Unsupported operation setKeepAlive()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOOBInline(boolean on) {
|
||||
throw new UnsupportedOperationException("Unsupported operation setOOBInline()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
|
||||
throw new UnsupportedOperationException("Unsupported operation setPerformancePreferences()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReceiveBufferSize(int size) throws SocketException {
|
||||
try {
|
||||
localSocket.setReceiveBufferSize(size);
|
||||
} catch (IOException e) {
|
||||
throw toSocketException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReuseAddress(boolean on) {
|
||||
throw new UnsupportedOperationException("Unsupported operation setReuseAddress()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSendBufferSize(int size) throws SocketException {
|
||||
try {
|
||||
localSocket.setSendBufferSize(size);
|
||||
} catch (IOException e) {
|
||||
throw toSocketException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoLinger(boolean on, int linger) {
|
||||
throw new UnsupportedOperationException("Unsupported operation setSoLinger()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSoTimeout(int timeout) throws SocketException {
|
||||
try {
|
||||
localSocket.setSoTimeout(timeout);
|
||||
} catch (IOException e) {
|
||||
throw toSocketException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTcpNoDelay(boolean on) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTrafficClass(int tc) {
|
||||
throw new UnsupportedOperationException("Unsupported operation setTrafficClass()");
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void shutdownInput() throws IOException {
|
||||
localSocket.shutdownInput();
|
||||
inputShutdown = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void shutdownOutput() throws IOException {
|
||||
localSocket.shutdownOutput();
|
||||
outputShutdown = true;
|
||||
}
|
||||
|
||||
private static SocketException toSocketException(Throwable e) {
|
||||
SocketException se = new SocketException();
|
||||
se.initCause(e);
|
||||
return se;
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import android.net.LocalSocketAddress;
|
||||
import android.net.LocalSocketAddress.Namespace;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
/**
|
||||
* A SocketFactory that produces {@link UdsSocket} instances. This is used to provide support for
|
||||
* gRPC channels with an underlying Unix Domain Socket transport.
|
||||
*/
|
||||
class UdsSocketFactory extends SocketFactory {
|
||||
|
||||
private final LocalSocketAddress localSocketAddress;
|
||||
|
||||
public UdsSocketFactory(String path, Namespace namespace) {
|
||||
localSocketAddress = new LocalSocketAddress(path, namespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket() throws IOException {
|
||||
return create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port) throws IOException {
|
||||
return createAndConnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
|
||||
throws IOException {
|
||||
return createAndConnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress host, int port) throws IOException {
|
||||
return createAndConnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
|
||||
throws IOException {
|
||||
return createAndConnect();
|
||||
}
|
||||
|
||||
private Socket create() {
|
||||
return new UdsSocket(localSocketAddress);
|
||||
}
|
||||
|
||||
private Socket createAndConnect() throws IOException {
|
||||
Socket socket = create();
|
||||
SocketAddress unusedAddress = new InetSocketAddress(0);
|
||||
socket.connect(unusedAddress);
|
||||
return socket;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,16 @@
|
|||
load("@rules_jvm_external//:defs.bzl", "artifact")
|
||||
|
||||
java_library(
|
||||
name = "api",
|
||||
srcs = glob([
|
||||
"src/main/java/**/*.java",
|
||||
"src/context/java/**/*.java",
|
||||
]),
|
||||
javacopts = ["-Xep:DoNotCall:OFF"], # Remove once requiring Bazel 3.4.0+; allows non-final
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
artifact("com.google.code.findbugs:jsr305"),
|
||||
artifact("com.google.errorprone:error_prone_annotations"),
|
||||
artifact("com.google.guava:failureaccess"), # future transitive dep of Guava. See #5214
|
||||
artifact("com.google.guava:guava"),
|
||||
"//context",
|
||||
"@com_google_code_findbugs_jsr305//jar",
|
||||
"@com_google_errorprone_error_prone_annotations//jar",
|
||||
"@com_google_guava_failureaccess//jar", # future transitive dep of Guava. See #5214
|
||||
"@com_google_guava_guava//jar",
|
||||
"@com_google_j2objc_j2objc_annotations//jar",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
plugins {
|
||||
id "java-library"
|
||||
id "java-test-fixtures"
|
||||
id "maven-publish"
|
||||
|
||||
id "me.champeau.jmh"
|
||||
|
@ -9,75 +8,27 @@ plugins {
|
|||
|
||||
description = 'gRPC: API'
|
||||
|
||||
sourceSets {
|
||||
context
|
||||
main {
|
||||
output.classesDirs.from(sourceSets.context.output.classesDirs)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("compileContextJava").configure {
|
||||
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_20)) {
|
||||
println("!!! Javac does not support generating Java 7 bytecode. Do not use for release builds !!!")
|
||||
} else if (JavaVersion.current().isJava9Compatible()) {
|
||||
options.release = 7
|
||||
} else {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("jar").configure {
|
||||
manifest {
|
||||
attributes('Automatic-Module-Name': 'io.grpc')
|
||||
}
|
||||
}
|
||||
evaluationDependsOn(project(':grpc-context').path)
|
||||
|
||||
dependencies {
|
||||
compileOnly sourceSets.context.output
|
||||
api libraries.jsr305,
|
||||
api project(':grpc-context'),
|
||||
libraries.jsr305,
|
||||
libraries.errorprone.annotations
|
||||
implementation libraries.guava
|
||||
|
||||
testFixturesApi libraries.truth
|
||||
testFixturesImplementation libraries.jsr305
|
||||
testFixturesImplementation libraries.guava,
|
||||
libraries.junit,
|
||||
libraries.mockito.core
|
||||
testImplementation project(':grpc-core')
|
||||
testImplementation project(':grpc-testing')
|
||||
testImplementation libraries.guava.testlib
|
||||
testImplementation libraries.truth
|
||||
|
||||
signature (libraries.signature.java) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
testImplementation project(':grpc-context').sourceSets.test.output,
|
||||
project(':grpc-testing'),
|
||||
project(':grpc-grpclb')
|
||||
testImplementation (libraries.guava.testlib) {
|
||||
exclude group: 'junit', module: 'junit'
|
||||
}
|
||||
signature (libraries.signature.android) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
}
|
||||
jmh project(':grpc-core')
|
||||
|
||||
animalsniffer {
|
||||
annotation = 'io.grpc.IgnoreJRERequirement'
|
||||
signature libraries.signature.java
|
||||
signature libraries.signature.android
|
||||
}
|
||||
|
||||
tasks.named("javadoc").configure {
|
||||
source sourceSets.context.allSource
|
||||
// We want io.grpc.Internal, but not io.grpc.Internal*
|
||||
exclude 'io/grpc/*MetricInstrument.java'
|
||||
exclude 'io/grpc/*MetricInstrumentRegistry.java'
|
||||
exclude 'io/grpc/Internal?*.java'
|
||||
exclude 'io/grpc/MetricRecorder.java'
|
||||
exclude 'io/grpc/MetricSink.java'
|
||||
}
|
||||
|
||||
tasks.named("sourcesJar").configure {
|
||||
from sourceSets.context.allSource
|
||||
}
|
||||
|
||||
components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
|
||||
components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }
|
||||
|
|
|
@ -236,12 +236,13 @@ public final class Attributes {
|
|||
}
|
||||
|
||||
/**
|
||||
* Removes the key and associated value from the attributes.
|
||||
* Removes the key and associated value from the attribtues.
|
||||
*
|
||||
* @since 1.22.0
|
||||
* @param key The key to remove
|
||||
* @return this
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/5777")
|
||||
public <T> Builder discard(Key<T> key) {
|
||||
if (base.data.containsKey(key)) {
|
||||
IdentityHashMap<Key<?>, Object> newBaseData = new IdentityHashMap<>(base.data);
|
||||
|
|
|
@ -43,7 +43,7 @@ public abstract class CallCredentials {
|
|||
* <p>It is called for each individual RPC, within the {@link Context} of the call, before the
|
||||
* stream is about to be created on a transport. Implementations should not block in this
|
||||
* method. If metadata is not immediately available, e.g., needs to be fetched from network, the
|
||||
* implementation may give the {@code appExecutor} an asynchronous task which will eventually call
|
||||
* implementation may give the {@code applier} to an asynchronous task which will eventually call
|
||||
* the {@code applier}. The RPC proceeds only after the {@code applier} is called.
|
||||
*
|
||||
* @param requestInfo request-related information
|
||||
|
@ -56,20 +56,18 @@ public abstract class CallCredentials {
|
|||
RequestInfo requestInfo, Executor appExecutor, CallCredentials.MetadataApplier applier);
|
||||
|
||||
/**
|
||||
* With this class now being stable this method moves from an abstract one to a normal one with
|
||||
* a no-op implementation. This method is marked deprecated to allow extenders time to remove the
|
||||
* method before it is removed here.
|
||||
* Should be a noop but never called; tries to make it clearer to implementors that they may break
|
||||
* in the future.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
|
||||
@Deprecated
|
||||
public void thisUsesUnstableApi() {
|
||||
}
|
||||
public abstract void thisUsesUnstableApi();
|
||||
|
||||
/**
|
||||
* The outlet of the produced headers. Not thread-safe.
|
||||
*
|
||||
* <p>Exactly one of its methods must be called to make the RPC proceed.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
|
||||
public abstract static class MetadataApplier {
|
||||
/**
|
||||
* Called when headers are successfully generated. They will be merged into the original
|
||||
|
@ -86,6 +84,7 @@ public abstract class CallCredentials {
|
|||
/**
|
||||
* The request-related information passed to {@code CallCredentials.applyRequestMetadata()}.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
|
||||
public abstract static class RequestInfo {
|
||||
/**
|
||||
* The method descriptor of this RPC.
|
||||
|
|
|
@ -17,18 +17,16 @@
|
|||
package io.grpc;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static io.grpc.TimeUtils.convertToNanos;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
@ -81,8 +79,6 @@ public final class CallOptions {
|
|||
private final Integer maxInboundMessageSize;
|
||||
@Nullable
|
||||
private final Integer maxOutboundMessageSize;
|
||||
@Nullable
|
||||
private final Integer onReadyThreshold;
|
||||
|
||||
private CallOptions(Builder builder) {
|
||||
this.deadline = builder.deadline;
|
||||
|
@ -95,7 +91,6 @@ public final class CallOptions {
|
|||
this.waitForReady = builder.waitForReady;
|
||||
this.maxInboundMessageSize = builder.maxInboundMessageSize;
|
||||
this.maxOutboundMessageSize = builder.maxOutboundMessageSize;
|
||||
this.onReadyThreshold = builder.onReadyThreshold;
|
||||
}
|
||||
|
||||
static class Builder {
|
||||
|
@ -110,7 +105,6 @@ public final class CallOptions {
|
|||
Boolean waitForReady;
|
||||
Integer maxInboundMessageSize;
|
||||
Integer maxOutboundMessageSize;
|
||||
Integer onReadyThreshold;
|
||||
|
||||
private CallOptions build() {
|
||||
return new CallOptions(this);
|
||||
|
@ -144,12 +138,13 @@ public final class CallOptions {
|
|||
|
||||
/**
|
||||
* Sets the compression to use for the call. The compressor must be a valid name known in the
|
||||
* {@link CompressorRegistry}. By default, the "gzip" compressor will be available.
|
||||
* {@link CompressorRegistry}.
|
||||
*
|
||||
* <p>It is only safe to call this if the server supports the compression format chosen. There is
|
||||
* no negotiation performed; if the server does not support the compression chosen, the call will
|
||||
* fail.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704")
|
||||
public CallOptions withCompression(@Nullable String compressorName) {
|
||||
Builder builder = toBuilder(this);
|
||||
builder.compressorName = compressorName;
|
||||
|
@ -178,11 +173,6 @@ public final class CallOptions {
|
|||
return withDeadline(Deadline.after(duration, unit));
|
||||
}
|
||||
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
|
||||
public CallOptions withDeadlineAfter(Duration duration) {
|
||||
return withDeadlineAfter(convertToNanos(duration), TimeUnit.NANOSECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the deadline or {@code null} if the deadline is not set.
|
||||
*/
|
||||
|
@ -214,49 +204,10 @@ public final class CallOptions {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies how many bytes must be queued before the call is
|
||||
* considered not ready to send more messages.
|
||||
*
|
||||
* @param numBytes The number of bytes that must be queued. Must be a
|
||||
* positive integer.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11021")
|
||||
public CallOptions withOnReadyThreshold(int numBytes) {
|
||||
checkArgument(numBytes > 0, "numBytes must be positive: %s", numBytes);
|
||||
Builder builder = toBuilder(this);
|
||||
builder.onReadyThreshold = numBytes;
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets to the default number of bytes that must be queued before the
|
||||
* call will leave the <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">
|
||||
* 'wait for ready'</a> state.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11021")
|
||||
public CallOptions clearOnReadyThreshold() {
|
||||
Builder builder = toBuilder(this);
|
||||
builder.onReadyThreshold = null;
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns to the default number of bytes that must be queued before the
|
||||
* call will leave the <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">
|
||||
* 'wait for ready'</a> state.
|
||||
*
|
||||
* @return null if the default threshold is used.
|
||||
*/
|
||||
@Nullable
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11021")
|
||||
public Integer getOnReadyThreshold() {
|
||||
return onReadyThreshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the compressor's name.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704")
|
||||
@Nullable
|
||||
public String getCompressor() {
|
||||
return compressorName;
|
||||
|
@ -519,7 +470,6 @@ public final class CallOptions {
|
|||
builder.waitForReady = other.waitForReady;
|
||||
builder.maxInboundMessageSize = other.maxInboundMessageSize;
|
||||
builder.maxOutboundMessageSize = other.maxOutboundMessageSize;
|
||||
builder.onReadyThreshold = other.onReadyThreshold;
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -535,7 +485,6 @@ public final class CallOptions {
|
|||
.add("waitForReady", isWaitForReady())
|
||||
.add("maxInboundMessageSize", maxInboundMessageSize)
|
||||
.add("maxOutboundMessageSize", maxOutboundMessageSize)
|
||||
.add("onReadyThreshold", onReadyThreshold)
|
||||
.add("streamTracerFactories", streamTracerFactories)
|
||||
.toString();
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Tagging interface for MetricInstruments that can be used with batch callbacks.
|
||||
*/
|
||||
@Internal
|
||||
public interface CallbackMetricInstrument extends MetricInstrument {}
|
|
@ -67,7 +67,7 @@ import javax.annotation.Nullable;
|
|||
* manner, and notifies gRPC library to receive additional response after one is consumed by
|
||||
* a fictional <code>processResponse()</code>.
|
||||
*
|
||||
* <pre>
|
||||
* <p><pre>
|
||||
* call = channel.newCall(bidiStreamingMethod, callOptions);
|
||||
* listener = new ClientCall.Listener<FooResponse>() {
|
||||
* @Override
|
||||
|
@ -270,6 +270,7 @@ public abstract class ClientCall<ReqT, RespT> {
|
|||
* encoding has been negotiated, this is a no-op. By default per-message compression is enabled,
|
||||
* but may not have any effect if compression is not enabled on the call.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1703")
|
||||
public void setMessageCompression(boolean enabled) {
|
||||
// noop
|
||||
}
|
||||
|
|
|
@ -236,11 +236,7 @@ public class ClientInterceptors {
|
|||
// to a NO-OP one to prevent the IllegalStateException. The user will finally get notified
|
||||
// about the error through the listener.
|
||||
delegate = (ClientCall<ReqT, RespT>) NOOP_CALL;
|
||||
Metadata trailers = Status.trailersFromThrowable(e);
|
||||
responseListener.onClose(
|
||||
Status.fromThrowable(e),
|
||||
trailers != null ? trailers : new Metadata()
|
||||
);
|
||||
responseListener.onClose(Status.fromThrowable(e), new Metadata());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,12 +27,6 @@ import javax.annotation.concurrent.ThreadSafe;
|
|||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
|
||||
@ThreadSafe
|
||||
public abstract class ClientStreamTracer extends StreamTracer {
|
||||
/**
|
||||
* Indicates how long the call was delayed, in nanoseconds, due to waiting for name resolution
|
||||
* result. If the call option is not set, the call did not experience name resolution delay.
|
||||
*/
|
||||
public static final CallOptions.Key<Long> NAME_RESOLUTION_DELAYED =
|
||||
CallOptions.Key.create("io.grpc.ClientStreamTracer.NAME_RESOLUTION_DELAYED");
|
||||
|
||||
/**
|
||||
* The stream is being created on a ready transport.
|
||||
|
@ -45,18 +39,6 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
|||
public void streamCreated(@Grpc.TransportAttr Attributes transportAttrs, Metadata headers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Name resolution is completed and the connection starts getting established. This method is only
|
||||
* invoked on the streams that encounter such delay.
|
||||
*
|
||||
* </p>gRPC buffers the client call if the remote address and configurations, e.g. timeouts and
|
||||
* retry policy, are not ready. Asynchronously gRPC internally does the name resolution to get
|
||||
* this information. The streams that are processed immediately on ready transports by the time
|
||||
* the RPC comes do not go through the pending process, thus this callback will not be invoked.
|
||||
*/
|
||||
public void createPendingStream() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Headers has been sent to the socket.
|
||||
*/
|
||||
|
@ -70,35 +52,15 @@ public abstract class ClientStreamTracer extends StreamTracer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Headers has been received from the server. This method does not pass ownership to {@code
|
||||
* headers}, so implementations must not access the metadata after returning. Modifications to the
|
||||
* metadata within this method will be seen by interceptors and the application.
|
||||
* Trailing metadata has been received from the server.
|
||||
*
|
||||
* @param headers the received header metadata
|
||||
*/
|
||||
public void inboundHeaders(Metadata headers) {
|
||||
inboundHeaders();
|
||||
}
|
||||
|
||||
/**
|
||||
* Trailing metadata has been received from the server. This method does not pass ownership to
|
||||
* {@code trailers}, so implementations must not access the metadata after returning.
|
||||
* Modifications to the metadata within this method will be seen by interceptors and the
|
||||
* application.
|
||||
*
|
||||
* @param trailers the received trailing metadata
|
||||
* @param trailers the mutable trailing metadata. Modifications to it will be seen by
|
||||
* interceptors and the application.
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public void inboundTrailers(Metadata trailers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Information providing context to the call became available.
|
||||
*/
|
||||
@Internal
|
||||
public void addOptionalLabel(String key, String value) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory class for {@link ClientStreamTracer}.
|
||||
*/
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Listens on the client transport life-cycle events. These filters do not have the capability
|
||||
* to modify the channels or transport life-cycle event behavior, but they can be useful hooks
|
||||
* for transport observability. Multiple filters may be registered to the client.
|
||||
*
|
||||
* @since 1.62.0
|
||||
*/
|
||||
@ExperimentalApi("https://gitub.com/grpc/grpc-java/issues/10652")
|
||||
public abstract class ClientTransportFilter {
|
||||
/**
|
||||
* Called when a transport is ready to accept traffic (when a connection has been established).
|
||||
* The default implementation is a no-op.
|
||||
*
|
||||
* @param transportAttrs current transport attributes
|
||||
*
|
||||
* @return new transport attributes. Default implementation returns the passed-in attributes
|
||||
* intact.
|
||||
*/
|
||||
public Attributes transportReady(Attributes transportAttrs) {
|
||||
return transportAttrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a transport completed shutting down. All resources have been released.
|
||||
* All streams have either been closed or transferred off this transport.
|
||||
* Default implementation is a no-op
|
||||
*
|
||||
* @param transportAttrs the effective transport attributes, which is what is returned by {@link
|
||||
* #transportReady} of the last executed filter.
|
||||
*/
|
||||
public void transportTerminated(Attributes transportAttrs) {
|
||||
}
|
||||
}
|
|
@ -40,6 +40,9 @@ public final class CompositeCallCredentials extends CallCredentials {
|
|||
new WrappingMetadataApplier(requestInfo, appExecutor, applier, Context.current()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void thisUsesUnstableApi() {}
|
||||
|
||||
private final class WrappingMetadataApplier extends MetadataApplier {
|
||||
private final RequestInfo requestInfo;
|
||||
private final Executor appExecutor;
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Provides hooks for modifying gRPC channels and servers during their construction.
|
||||
*/
|
||||
interface Configurator {
|
||||
/**
|
||||
* Allows implementations to modify the channel builder.
|
||||
*
|
||||
* @param channelBuilder the channel builder being constructed
|
||||
*/
|
||||
default void configureChannelBuilder(ManagedChannelBuilder<?> channelBuilder) {}
|
||||
|
||||
/**
|
||||
* Allows implementations to modify the server builder.
|
||||
*
|
||||
* @param serverBuilder the server builder being constructed
|
||||
*/
|
||||
default void configureServerBuilder(ServerBuilder<?> serverBuilder) {}
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A registry for {@link Configurator} instances.
|
||||
*
|
||||
* <p>This class is responsible for maintaining a list of configurators and providing access to
|
||||
* them. The default registry can be obtained using {@link #getDefaultRegistry()}.
|
||||
*/
|
||||
final class ConfiguratorRegistry {
|
||||
private static ConfiguratorRegistry instance;
|
||||
|
||||
@GuardedBy("this")
|
||||
private boolean wasConfiguratorsSet;
|
||||
@GuardedBy("this")
|
||||
private List<Configurator> configurators = Collections.emptyList();
|
||||
@GuardedBy("this")
|
||||
private int configuratorsCallCountBeforeSet = 0;
|
||||
|
||||
ConfiguratorRegistry() {}
|
||||
|
||||
/**
|
||||
* Returns the default global instance of the configurator registry.
|
||||
*/
|
||||
public static synchronized ConfiguratorRegistry getDefaultRegistry() {
|
||||
if (instance == null) {
|
||||
instance = new ConfiguratorRegistry();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the configurators in this registry. This method can only be called once.
|
||||
*
|
||||
* @param configurators the configurators to set
|
||||
* @throws IllegalStateException if this method is called more than once
|
||||
*/
|
||||
public synchronized void setConfigurators(List<? extends Configurator> configurators) {
|
||||
if (wasConfiguratorsSet) {
|
||||
throw new IllegalStateException("Configurators are already set");
|
||||
}
|
||||
this.configurators = Collections.unmodifiableList(new ArrayList<>(configurators));
|
||||
wasConfiguratorsSet = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of the configurators in this registry.
|
||||
*/
|
||||
public synchronized List<Configurator> getConfigurators() {
|
||||
if (!wasConfiguratorsSet) {
|
||||
configuratorsCallCountBeforeSet++;
|
||||
}
|
||||
return configurators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of times getConfigurators() was called before
|
||||
* setConfigurators() was successfully invoked.
|
||||
*/
|
||||
public synchronized int getConfiguratorsCallCountBeforeSet() {
|
||||
return configuratorsCallCountBeforeSet;
|
||||
}
|
||||
|
||||
public synchronized boolean wasSetConfiguratorsCalled() {
|
||||
return wasConfiguratorsSet;
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import java.io.InputStream;
|
|||
* with {@link HasByteBuffer}, a custom {@link io.grpc.MethodDescriptor.Marshaller} can take
|
||||
* over the ownership of buffers containing inbound data and perform delayed deserialization.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7387")
|
||||
public interface Detachable {
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a double-valued counter metric instrument.
|
||||
*/
|
||||
@Internal
|
||||
public final class DoubleCounterMetricInstrument extends PartialMetricInstrument {
|
||||
public DoubleCounterMetricInstrument(int index, String name, String description, String unit,
|
||||
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
|
||||
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
|
||||
}
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a double-valued histogram metric instrument.
|
||||
*/
|
||||
@Internal
|
||||
public final class DoubleHistogramMetricInstrument extends PartialMetricInstrument {
|
||||
private final List<Double> bucketBoundaries;
|
||||
|
||||
public DoubleHistogramMetricInstrument(int index, String name, String description, String unit,
|
||||
List<Double> bucketBoundaries, List<String> requiredLabelKeys, List<String> optionalLabelKeys,
|
||||
boolean enableByDefault) {
|
||||
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
|
||||
this.bucketBoundaries = bucketBoundaries;
|
||||
}
|
||||
|
||||
public List<Double> getBucketBoundaries() {
|
||||
return bucketBoundaries;
|
||||
}
|
||||
}
|
|
@ -128,9 +128,6 @@ public final class EquivalentAddressGroup {
|
|||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (this == other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof EquivalentAddressGroup)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.errorprone.annotations.DoNotCall;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
@ -26,39 +28,38 @@ import javax.annotation.Nullable;
|
|||
* A {@link ManagedChannelBuilder} that delegates all its builder methods to another builder by
|
||||
* default.
|
||||
*
|
||||
* <p>DEPRECATED: Use {@link ForwardingChannelBuilder2} instead!
|
||||
*
|
||||
* <p>This class mistakenly used {@code <T extends ForwardingChannelBuilder<T>>} which causes
|
||||
* return types to be {@link ForwardingChannelBuilder} instead of {@link ManagedChannelBuilder}.
|
||||
* This pollutes the ABI of its subclasses with undesired method signatures.
|
||||
* {@link ForwardingChannelBuilder2} generates correct return types; use it instead.
|
||||
*
|
||||
* @param <T> The type of the subclass extending this abstract class.
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/3363")
|
||||
public abstract class ForwardingChannelBuilder<T extends ForwardingChannelBuilder<T>>
|
||||
extends ForwardingChannelBuilder2<T> {
|
||||
extends ManagedChannelBuilder<T> {
|
||||
|
||||
/**
|
||||
* The default constructor.
|
||||
*/
|
||||
protected ForwardingChannelBuilder() {
|
||||
protected ForwardingChannelBuilder() {}
|
||||
|
||||
/**
|
||||
* This method serves to force sub classes to "hide" this static factory.
|
||||
*/
|
||||
@DoNotCall("Unsupported")
|
||||
public static ManagedChannelBuilder<?> forAddress(String name, int port) {
|
||||
throw new UnsupportedOperationException("Subclass failed to hide static factory");
|
||||
}
|
||||
|
||||
/**
|
||||
* This method serves to force sub classes to "hide" this static factory.
|
||||
*/
|
||||
@DoNotCall("Unsupported")
|
||||
public static ManagedChannelBuilder<?> forTarget(String target) {
|
||||
throw new UnsupportedOperationException("Subclass failed to hide static factory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the delegated {@code ManagedChannelBuilder}.
|
||||
*
|
||||
* <p>NOTE: this method is marked deprecated instead the class itself, so that classes extending
|
||||
* {@link ForwardingChannelBuilder2} won't need class-level
|
||||
* {@code @SuppressWarnings("deprecation")} annotation. Such annotation would suppress all
|
||||
* deprecation warnings in all methods, inadvertently hiding any real deprecation warnings needing
|
||||
* to be addressed. However, each child class is expected to implement {@code delegate()}.
|
||||
* Therefore, the {@code @Deprecated} annotation is added to this method, and not to the class.
|
||||
*
|
||||
* @deprecated As of 1.60.0, use {@link ForwardingChannelBuilder2} instead.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected abstract ManagedChannelBuilder<?> delegate();
|
||||
|
||||
@Override
|
||||
|
@ -128,6 +129,12 @@ public abstract class ForwardingChannelBuilder<T extends ForwardingChannelBuilde
|
|||
return thisT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T enableFullStreamDecompression() {
|
||||
delegate().enableFullStreamDecompression();
|
||||
return thisT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T decompressorRegistry(DecompressorRegistry registry) {
|
||||
delegate().decompressorRegistry(registry);
|
||||
|
@ -242,10 +249,24 @@ public abstract class ForwardingChannelBuilder<T extends ForwardingChannelBuilde
|
|||
return thisT();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ManagedChannel} built by the delegate by default. Overriding method can
|
||||
* return different value.
|
||||
*/
|
||||
@Override
|
||||
public ManagedChannel build() {
|
||||
return delegate().build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this).add("delegate", delegate()).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the correctly typed version of the builder.
|
||||
*/
|
||||
private T thisT() {
|
||||
protected final T thisT() {
|
||||
@SuppressWarnings("unchecked")
|
||||
T thisT = (T) this;
|
||||
return thisT;
|
||||
|
|
|
@ -30,6 +30,7 @@ import javax.annotation.Nullable;
|
|||
* @param <T> The type of the subclass extending this abstract class.
|
||||
* @since 1.34.0
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7393")
|
||||
public abstract class ForwardingServerBuilder<T extends ServerBuilder<T>> extends ServerBuilder<T> {
|
||||
|
||||
/** The default constructor. */
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* Copyright 2022 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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/** The collection of global interceptors and global server stream tracers. */
|
||||
@Internal
|
||||
final class GlobalInterceptors {
|
||||
private static List<ClientInterceptor> clientInterceptors = null;
|
||||
private static List<ServerInterceptor> serverInterceptors = null;
|
||||
private static List<ServerStreamTracer.Factory> serverStreamTracerFactories =
|
||||
null;
|
||||
private static boolean isGlobalInterceptorsTracersSet;
|
||||
private static boolean isGlobalInterceptorsTracersGet;
|
||||
|
||||
// Prevent instantiation
|
||||
private GlobalInterceptors() {}
|
||||
|
||||
/**
|
||||
* Sets the list of global interceptors and global server stream tracers.
|
||||
*
|
||||
* <p>If {@code setInterceptorsTracers()} is called again, this method will throw {@link
|
||||
* IllegalStateException}.
|
||||
*
|
||||
* <p>It is only safe to call early. This method throws {@link IllegalStateException} after any of
|
||||
* the get calls [{@link #getClientInterceptors()}, {@link #getServerInterceptors()} or {@link
|
||||
* #getServerStreamTracerFactories()}] has been called, in order to limit changes to the result of
|
||||
* {@code setInterceptorsTracers()}.
|
||||
*
|
||||
* @param clientInterceptorList list of {@link ClientInterceptor} that make up global Client
|
||||
* Interceptors.
|
||||
* @param serverInterceptorList list of {@link ServerInterceptor} that make up global Server
|
||||
* Interceptors.
|
||||
* @param serverStreamTracerFactoryList list of {@link ServerStreamTracer.Factory} that make up
|
||||
* global ServerStreamTracer factories.
|
||||
*/
|
||||
static synchronized void setInterceptorsTracers(
|
||||
List<ClientInterceptor> clientInterceptorList,
|
||||
List<ServerInterceptor> serverInterceptorList,
|
||||
List<ServerStreamTracer.Factory> serverStreamTracerFactoryList) {
|
||||
if (isGlobalInterceptorsTracersGet) {
|
||||
throw new IllegalStateException("Set cannot be called after any get call");
|
||||
}
|
||||
if (isGlobalInterceptorsTracersSet) {
|
||||
throw new IllegalStateException("Global interceptors and tracers are already set");
|
||||
}
|
||||
checkNotNull(clientInterceptorList);
|
||||
checkNotNull(serverInterceptorList);
|
||||
checkNotNull(serverStreamTracerFactoryList);
|
||||
clientInterceptors = Collections.unmodifiableList(new ArrayList<>(clientInterceptorList));
|
||||
serverInterceptors = Collections.unmodifiableList(new ArrayList<>(serverInterceptorList));
|
||||
serverStreamTracerFactories =
|
||||
Collections.unmodifiableList(new ArrayList<>(serverStreamTracerFactoryList));
|
||||
isGlobalInterceptorsTracersSet = true;
|
||||
}
|
||||
|
||||
/** Returns the list of global {@link ClientInterceptor}. If not set, this returns null. */
|
||||
static synchronized List<ClientInterceptor> getClientInterceptors() {
|
||||
isGlobalInterceptorsTracersGet = true;
|
||||
return clientInterceptors;
|
||||
}
|
||||
|
||||
/** Returns list of global {@link ServerInterceptor}. If not set, this returns null. */
|
||||
static synchronized List<ServerInterceptor> getServerInterceptors() {
|
||||
isGlobalInterceptorsTracersGet = true;
|
||||
return serverInterceptors;
|
||||
}
|
||||
|
||||
/** Returns list of global {@link ServerStreamTracer.Factory}. If not set, this returns null. */
|
||||
static synchronized List<ServerStreamTracer.Factory> getServerStreamTracerFactories() {
|
||||
isGlobalInterceptorsTracersGet = true;
|
||||
return serverStreamTracerFactories;
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ import javax.annotation.Nullable;
|
|||
* interface from an {@link java.io.InputStream} to {@link ByteBuffer}s, without copying the
|
||||
* content to a byte array and read from it.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7387")
|
||||
public interface HasByteBuffer {
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,7 @@ import javax.annotation.Nullable;
|
|||
/**
|
||||
* An {@link ProxiedSocketAddress} for making a connection to an endpoint via an HTTP CONNECT proxy.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/5279")
|
||||
public final class HttpConnectProxiedSocketAddress extends ProxiedSocketAddress {
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Disables Animal Sniffer's signature checking. This is our own package-private version to avoid
|
||||
* dependening on animalsniffer-annotations.
|
||||
*
|
||||
* <p>FIELD is purposefully not supported, as Android wouldn't be able to ignore a field. Instead,
|
||||
* the entire class would need to be avoided on Android.
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
|
||||
@interface IgnoreJRERequirement {}
|
|
@ -35,7 +35,7 @@ public abstract class InternalConfigSelector {
|
|||
= Attributes.Key.create("internal:io.grpc.config-selector");
|
||||
|
||||
// Use PickSubchannelArgs for SelectConfigArgs for now. May change over time.
|
||||
/** Selects the config for an RPC. */
|
||||
/** Selects the config for an PRC. */
|
||||
public abstract Result selectConfig(LoadBalancer.PickSubchannelArgs args);
|
||||
|
||||
public static final class Result {
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Internal access to Configurator API.
|
||||
*/
|
||||
@Internal
|
||||
public interface InternalConfigurator extends Configurator {}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Access internal global configurators.
|
||||
*/
|
||||
@Internal
|
||||
public final class InternalConfiguratorRegistry {
|
||||
private InternalConfiguratorRegistry() {}
|
||||
|
||||
public static void setConfigurators(List<InternalConfigurator> configurators) {
|
||||
ConfiguratorRegistry.getDefaultRegistry().setConfigurators(configurators);
|
||||
}
|
||||
|
||||
public static List<?> getConfigurators() {
|
||||
return ConfiguratorRegistry.getDefaultRegistry().getConfigurators();
|
||||
}
|
||||
|
||||
public static void configureChannelBuilder(ManagedChannelBuilder<?> channelBuilder) {
|
||||
for (Configurator configurator : ConfiguratorRegistry.getDefaultRegistry().getConfigurators()) {
|
||||
configurator.configureChannelBuilder(channelBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void configureServerBuilder(ServerBuilder<?> serverBuilder) {
|
||||
for (Configurator configurator : ConfiguratorRegistry.getDefaultRegistry().getConfigurators()) {
|
||||
configurator.configureServerBuilder(serverBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean wasSetConfiguratorsCalled() {
|
||||
return ConfiguratorRegistry.getDefaultRegistry().wasSetConfiguratorsCalled();
|
||||
}
|
||||
|
||||
public static int getConfiguratorsCallCountBeforeSet() {
|
||||
return ConfiguratorRegistry.getDefaultRegistry().getConfiguratorsCallCountBeforeSet();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2022 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Accessor to internal methods of {@link GlobalInterceptors}. */
|
||||
@Internal
|
||||
public final class InternalGlobalInterceptors {
|
||||
|
||||
public static void setInterceptorsTracers(
|
||||
List<ClientInterceptor> clientInterceptorList,
|
||||
List<ServerInterceptor> serverInterceptorList,
|
||||
List<ServerStreamTracer.Factory> serverStreamTracerFactoryList) {
|
||||
GlobalInterceptors.setInterceptorsTracers(
|
||||
clientInterceptorList, serverInterceptorList, serverStreamTracerFactoryList);
|
||||
}
|
||||
|
||||
public static List<ClientInterceptor> getClientInterceptors() {
|
||||
return GlobalInterceptors.getClientInterceptors();
|
||||
}
|
||||
|
||||
public static List<ServerInterceptor> getServerInterceptors() {
|
||||
return GlobalInterceptors.getServerInterceptors();
|
||||
}
|
||||
|
||||
public static List<ServerStreamTracer.Factory> getServerStreamTracerFactories() {
|
||||
return GlobalInterceptors.getServerStreamTracerFactories();
|
||||
}
|
||||
|
||||
private InternalGlobalInterceptors() {}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Internal accessors for {@link ManagedChannelBuilder}.
|
||||
*/
|
||||
@Internal
|
||||
public final class InternalManagedChannelBuilder {
|
||||
private InternalManagedChannelBuilder() {}
|
||||
|
||||
public static <T extends ManagedChannelBuilder<T>> T interceptWithTarget(
|
||||
ManagedChannelBuilder<T> builder, InternalInterceptorFactory factory) {
|
||||
return builder.interceptWithTarget(factory);
|
||||
}
|
||||
|
||||
public static <T extends ManagedChannelBuilder<T>> T addMetricSink(
|
||||
ManagedChannelBuilder<T> builder, MetricSink metricSink) {
|
||||
return builder.addMetricSink(metricSink);
|
||||
}
|
||||
|
||||
public interface InternalInterceptorFactory extends ManagedChannelBuilder.InterceptorFactory {}
|
||||
}
|
|
@ -30,12 +30,10 @@ public final class InternalMethodDescriptor {
|
|||
this.transport = checkNotNull(transport, "transport");
|
||||
}
|
||||
|
||||
@SuppressWarnings("EnumOrdinal")
|
||||
public Object geRawMethodName(MethodDescriptor<?, ?> descriptor) {
|
||||
return descriptor.getRawMethodName(transport.ordinal());
|
||||
}
|
||||
|
||||
@SuppressWarnings("EnumOrdinal")
|
||||
public void setRawMethodName(MethodDescriptor<?, ?> descriptor, Object o) {
|
||||
descriptor.setRawMethodName(transport.ordinal(), o);
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue