mirror of https://github.com/grpc/grpc-java.git
Compare commits
294 Commits
Author | SHA1 | Date |
---|---|---|
|
c7202c0db5 | |
|
028afbe352 | |
|
afdbecb235 | |
|
2039266ebc | |
|
43bef65cf9 | |
|
437e03dc98 | |
|
6462ef9a11 | |
|
95d16d85c8 | |
|
f50726d32e | |
|
06707f7c38 | |
|
efcdebb904 | |
|
f30964ab82 | |
|
7040417eee | |
|
a40c8cf5a4 | |
|
8b46ad58c3 | |
|
d947c80f99 | |
|
6ffcbd927e | |
|
36fe276a50 | |
|
ba0a7329da | |
|
28f14255ce | |
|
7e982e48a1 | |
|
c3ef1ab034 | |
|
8f09b96899 | |
|
42e1829b37 | |
|
c4256add4d | |
|
6ff8ecac09 | |
|
80217275db | |
|
2e96fbf1e8 | |
|
a37d3eb349 | |
|
1fc4ab0bb2 | |
|
6935d3a115 | |
|
d7d70c6905 | |
|
d352540a02 | |
|
5a8326f1c7 | |
|
a8de9f07ab | |
|
9d191b31b5 | |
|
01bd63d88f | |
|
94532a6b56 | |
|
6dfa03c51c | |
|
919370172d | |
|
ca99a8c478 | |
|
2ee4f9b488 | |
|
74aee11389 | |
|
64322c3243 | |
|
af7efeb9f5 | |
|
ebc6d3e932 | |
|
d374b26b68 | |
|
f99b2aaef8 | |
|
30d40a6179 | |
|
9a6bdc70af | |
|
e6e7bcadaf | |
|
922dc8a999 | |
|
d2d8ed8efa | |
|
f07eb47cac | |
|
2604ce8a55 | |
|
1c43098990 | |
|
d5b4fb51c2 | |
|
8974a306af | |
|
d88ef97a87 | |
|
240f731e00 | |
|
26bd0eee47 | |
|
6f69363d90 | |
|
6cc2ff1ced | |
|
13fe008044 | |
|
30f6a4db77 | |
|
297ab05efe | |
|
a16d655919 | |
|
6afacf589e | |
|
4ee662fbcf | |
|
1fd29bc804 | |
|
dc192f5c5e | |
|
c206428749 | |
|
4cd7881086 | |
|
4c73999102 | |
|
482dc5c1c3 | |
|
efe9ccc22c | |
|
48d08e643e | |
|
6bad600592 | |
|
379fbaa380 | |
|
8044a56ad2 | |
|
142e378cea | |
|
22cf7cf2ac | |
|
83538cdae3 | |
|
d124007ff4 | |
|
46485c8b62 | |
|
9406d3b2a0 | |
|
9d439d4a44 | |
|
f8700a13ad | |
|
2fb09578a8 | |
|
480640dc2f | |
|
b88536a17d | |
|
b089761486 | |
|
59adeb9d47 | |
|
6baac45bd2 | |
|
454f1c5c6a | |
|
64fe061ccd | |
|
80cc988b3c | |
|
3f5fdf1266 | |
|
be0247f501 | |
|
12aaf88d86 | |
|
25199e9df9 | |
|
7952afdd56 | |
|
6cd007d0d0 | |
|
9619453799 | |
|
53de8a72ca | |
|
7a08fdb7f9 | |
|
84bd01454b | |
|
65d0bb8a4d | |
|
f79ab2f16f | |
|
a6aec2769e | |
|
2db4852e23 | |
|
54d37839a3 | |
|
aae52de3b8 | |
|
a13fca2bf2 | |
|
edc2bf7346 | |
|
5ca4d852ae | |
|
d4c46a7f1f | |
|
c8d1e6e39c | |
|
84c7713b2f | |
|
908f9f19cd | |
|
8ca7c4ef1f | |
|
c28a7e3e06 | |
|
8f6a16f846 | |
|
2448c8b6b9 | |
|
2e260a4bbc | |
|
7507a9ec06 | |
|
a332eddc13 | |
|
350f90e1a3 | |
|
3961a923ac | |
|
1958e42370 | |
|
94f8e93691 | |
|
d60e6fc251 | |
|
d2d72cda83 | |
|
bb120a8cbb | |
|
bc3c764058 | |
|
a57c14a51e | |
|
e80c197455 | |
|
e388ef3975 | |
|
b69bd64ce7 | |
|
fca1d3cf43 | |
|
2f52a00364 | |
|
2191557582 | |
|
4933cddd00 | |
|
24b9f6ff0d | |
|
61a110d962 | |
|
f3f054a0a4 | |
|
d82613a74c | |
|
ca4819ac6d | |
|
a6a041e415 | |
|
602aece081 | |
|
12197065fe | |
|
c340f4a2f3 | |
|
1a2285b527 | |
|
cdab410b81 | |
|
57124d6b29 | |
|
110c1ff0d6 | |
|
f207be39a9 | |
|
892144dcac | |
|
68d79b5130 | |
|
60f6ea7b8e | |
|
2b87b01651 | |
|
713607056e | |
|
a132123c93 | |
|
16edf7ac4e | |
|
16d26726cf | |
|
9e54e8e5e9 | |
|
c1d703546a | |
|
57af63ad0a | |
|
a5347b2bc4 | |
|
41dd0c6d73 | |
|
5a7f350537 | |
|
7585b1607d | |
|
122b683717 | |
|
764a4e3f08 | |
|
ade2dd2038 | |
|
fc8571a0e5 | |
|
302342cfce | |
|
dc316f7fd9 | |
|
bd6af59221 | |
|
67fc2e156a | |
|
90b1c4fe94 | |
|
44e92e2c2c | |
|
3142928fa3 | |
|
199a7ea3e8 | |
|
ea3f644eef | |
|
4a10a38166 | |
|
b1bc0a9d24 | |
|
04f1cc5845 | |
|
c506190b0f | |
|
90aefb26e7 | |
|
7153ff8522 | |
|
b3db8c2489 | |
|
9e8629914f | |
|
87aa6deadf | |
|
67351c0c53 | |
|
bf8eb24a30 | |
|
0f5503ebb1 | |
|
495a8906b2 | |
|
fc86084df5 | |
|
a0a42fc8e6 | |
|
f299ef5e58 | |
|
b44ebce45d | |
|
4d8aff72dc | |
|
87c7b7a375 | |
|
87b27b1545 | |
|
228dcf7a01 | |
|
7162d2d661 | |
|
176f3eed12 | |
|
d65d3942e6 | |
|
82403b9bfa | |
|
70825adce6 | |
|
7b5d0692cc | |
|
73721acc0d | |
|
e61b03cb9f | |
|
ae109727d3 | |
|
1edc4d84d4 | |
|
4222f77587 | |
|
6c12c2bd24 | |
|
4a0f707331 | |
|
1cf1927d1a | |
|
9a712c3f77 | |
|
bac8b32043 | |
|
b272f634c1 | |
|
fdb9a5a94f | |
|
c96e926e65 | |
|
8c261c3f28 | |
|
5e8abc6774 | |
|
1126a8e30b | |
|
805cad3782 | |
|
aafab74087 | |
|
ebe2b48677 | |
|
6516c7387e | |
|
ea8c31c305 | |
|
7b29111cd0 | |
|
0b2d44098f | |
|
ef7c2d59c1 | |
|
7601afc213 | |
|
8ea3629378 | |
|
f8f613984f | |
|
8a5f7776db | |
|
fe752a290e | |
|
a0982ca0a1 | |
|
e8ff6da2cf | |
|
3b39a83621 | |
|
486b8ba67f | |
|
f1109e4215 | |
|
6055adca5a | |
|
210f9c083e | |
|
99a2696c48 | |
|
65b32e60e0 | |
|
c080b52f95 | |
|
f66d7fc54d | |
|
7f9c1f39f3 | |
|
ebb43a69e7 | |
|
0192bece47 | |
|
55cef6330f | |
|
229a010f55 | |
|
29dd9bad3f | |
|
a79982c7fd | |
|
20d09cee57 | |
|
92de2f34dc | |
|
32f4cf432a | |
|
e58c998a42 | |
|
6a92a2a22e | |
|
4ae04b7d94 | |
|
5431bf7e77 | |
|
1f159d7899 | |
|
4e8f7df589 | |
|
b1703345f7 | |
|
921f88ae30 | |
|
8237ae270a | |
|
546efd79f1 | |
|
5081e60626 | |
|
d6c80294a7 | |
|
76705c235c | |
|
a5db67d0cb | |
|
dae078c0a6 | |
|
664f1fcf8a | |
|
88596868a4 | |
|
1993e68b03 | |
|
ef1fe87373 | |
|
c167ead851 | |
|
3562380da5 | |
|
766b92379b | |
|
b5ef09c548 | |
|
1612536f86 | |
|
a431e3664b | |
|
9176b55286 | |
|
735b3f3fe6 | |
|
fe350cfd50 | |
|
0b2c17d0da | |
|
370e7ce27c | |
|
ba8ab796e7 | |
|
31dad6af49 |
|
@ -0,0 +1,41 @@
|
|||
name: GitHub Actions Branch Testing
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- 'v1.*'
|
||||
schedule:
|
||||
- cron: '54 19 * * SUN' # weekly at a "random" time
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
arm64:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
strategy:
|
||||
matrix:
|
||||
jre: [17]
|
||||
fail-fast: false # Should swap to true if we grow a large matrix
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: ${{ matrix.jre }}
|
||||
distribution: 'temurin'
|
||||
|
||||
- name: Gradle cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
|
||||
- name: Build
|
||||
run: ./gradlew -Dorg.gradle.parallel=true -Dorg.gradle.jvmargs='-Xmx1g' -PskipAndroid=true -PskipCodegen=true -PerrorProne=false test
|
||||
|
|
@ -77,8 +77,11 @@ jobs:
|
|||
|
||||
bazel:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
bzlmod: [true, false]
|
||||
env:
|
||||
USE_BAZEL_VERSION: 6.0.0
|
||||
USE_BAZEL_VERSION: 7.0.0
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
@ -97,19 +100,11 @@ jobs:
|
|||
key: ${{ runner.os }}-bazel-${{ env.USE_BAZEL_VERSION }}-${{ hashFiles('WORKSPACE', 'repositories.bzl') }}
|
||||
|
||||
- name: Run bazel build
|
||||
run: bazelisk build //... --enable_bzlmod=false
|
||||
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=false
|
||||
working-directory: ./examples
|
||||
|
||||
- name: Run bazel build (bzlmod)
|
||||
env:
|
||||
USE_BAZEL_VERSION: 7.0.0
|
||||
run: bazelisk build //... --enable_bzlmod=true
|
||||
|
||||
- name: Run example bazel build (bzlmod)
|
||||
env:
|
||||
USE_BAZEL_VERSION: 7.0.0
|
||||
run: bazelisk build //... --enable_bzlmod=true
|
||||
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }}
|
||||
working-directory: ./examples
|
||||
|
|
|
@ -33,7 +33,6 @@ java_library(
|
|||
"//api",
|
||||
"//protobuf",
|
||||
"//stub",
|
||||
"//stub:javax_annotation",
|
||||
"@com_google_protobuf//:protobuf_java",
|
||||
artifact("com.google.code.findbugs:jsr305"),
|
||||
artifact("com.google.guava:guava"),
|
||||
|
@ -47,7 +46,6 @@ java_library(
|
|||
"//api",
|
||||
"//protobuf-lite",
|
||||
"//stub",
|
||||
"//stub:javax_annotation",
|
||||
artifact("com.google.code.findbugs:jsr305"),
|
||||
artifact("com.google.guava:guava"),
|
||||
],
|
||||
|
@ -67,6 +65,5 @@ java_library(
|
|||
visibility = ["//:__subpackages__"],
|
||||
exports = [
|
||||
artifact("com.google.auto.value:auto-value-annotations"),
|
||||
artifact("org.apache.tomcat:annotations-api"), # @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 21.7 or later.
|
||||
The codegen plugin is C++ code and requires protobuf 22.5 or later.
|
||||
|
||||
For Linux, Mac and MinGW:
|
||||
```
|
||||
$ PROTOBUF_VERSION=21.7
|
||||
$ PROTOBUF_VERSION=22.5
|
||||
$ curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz
|
||||
$ tar xzf protobuf-all-$PROTOBUF_VERSION.tar.gz
|
||||
$ cd protobuf-$PROTOBUF_VERSION
|
||||
|
|
|
@ -11,8 +11,6 @@ for general contribution guidelines.
|
|||
- [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
|
||||
- [sergiitk](https://github.com/sergiitk), Google LLC
|
||||
- [temawi](https://github.com/temawi), Google LLC
|
||||
|
@ -26,7 +24,9 @@ for general contribution guidelines.
|
|||
- [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)
|
||||
|
|
72
MODULE.bazel
72
MODULE.bazel
|
@ -2,79 +2,61 @@ module(
|
|||
name = "grpc-java",
|
||||
compatibility_level = 0,
|
||||
repo_name = "io_grpc_grpc_java",
|
||||
version = "1.68.0-SNAPSHOT", # CURRENT_GRPC_VERSION
|
||||
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.29.0",
|
||||
"com.google.auth:google-auth-library-credentials:1.23.0",
|
||||
"com.google.auth:google-auth-library-oauth2-http:1.23.0",
|
||||
"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.28.0",
|
||||
"com.google.errorprone:error_prone_annotations:2.30.0",
|
||||
"com.google.guava:failureaccess:1.0.1",
|
||||
"com.google.guava:guava:33.2.1-android",
|
||||
"com.google.re2j:re2j:1.7",
|
||||
"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.110.Final",
|
||||
"io.netty:netty-codec-http2:4.1.110.Final",
|
||||
"io.netty:netty-codec-http:4.1.110.Final",
|
||||
"io.netty:netty-codec-socks:4.1.110.Final",
|
||||
"io.netty:netty-codec:4.1.110.Final",
|
||||
"io.netty:netty-common:4.1.110.Final",
|
||||
"io.netty:netty-handler-proxy:4.1.110.Final",
|
||||
"io.netty:netty-handler:4.1.110.Final",
|
||||
"io.netty:netty-resolver:4.1.110.Final",
|
||||
"io.netty:netty-tcnative-boringssl-static:2.0.65.Final",
|
||||
"io.netty:netty-tcnative-classes:2.0.65.Final",
|
||||
"io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.110.Final",
|
||||
"io.netty:netty-transport-native-unix-common:4.1.110.Final",
|
||||
"io.netty:netty-transport:4.1.110.Final",
|
||||
"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.apache.tomcat:annotations-api:6.0.53",
|
||||
"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")
|
||||
# CEL Spec may be removed when cncf/xds MODULE is no longer using protobuf 27.x
|
||||
bazel_dep(name = "cel-spec", repo_name = "dev_cel", version = "0.15.0")
|
||||
bazel_dep(name = "grpc", repo_name = "com_github_grpc_grpc", version = "1.56.3.bcr.1")
|
||||
bazel_dep(name = "grpc-proto", repo_name = "io_grpc_grpc_proto", version = "0.0.0-20240627-ec30f58")
|
||||
bazel_dep(name = "protobuf", repo_name = "com_google_protobuf", version = "23.1")
|
||||
# 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_go", repo_name = "io_bazel_rules_go", version = "0.46.0")
|
||||
bazel_dep(name = "rules_jvm_external", version = "6.0")
|
||||
bazel_dep(name = "rules_proto", version = "5.3.0-21.7")
|
||||
|
||||
non_module_deps = use_extension("//:repositories.bzl", "grpc_java_repositories_extension")
|
||||
|
||||
use_repo(
|
||||
non_module_deps,
|
||||
"com_github_cncf_xds",
|
||||
"envoy_api",
|
||||
)
|
||||
|
||||
grpc_repo_deps_ext = use_extension("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_repo_deps_ext")
|
||||
|
||||
use_repo(
|
||||
grpc_repo_deps_ext,
|
||||
"com_envoyproxy_protoc_gen_validate",
|
||||
"opencensus_proto",
|
||||
)
|
||||
|
||||
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
|
||||
|
||||
maven.install(
|
||||
|
@ -201,7 +183,3 @@ maven.override(
|
|||
coordinates = "io.grpc:grpc-util",
|
||||
target = "@io_grpc_grpc_java//util",
|
||||
)
|
||||
|
||||
switched_rules = use_extension("@com_google_googleapis//:extensions.bzl", "switched_rules")
|
||||
|
||||
switched_rules.use_languages(java = True)
|
||||
|
|
42
README.md
42
README.md
|
@ -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.67.1/examples) and the
|
||||
[Android example](https://github.com/grpc/grpc-java/tree/v1.67.1/examples/android)
|
||||
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)
|
||||
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.67.1</version>
|
||||
<version>1.75.0</version>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-protobuf</artifactId>
|
||||
<version>1.67.1</version>
|
||||
<version>1.75.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-stub</artifactId>
|
||||
<version>1.67.1</version>
|
||||
<version>1.75.0</version>
|
||||
</dependency>
|
||||
<dependency> <!-- necessary for Java 9+ -->
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
|
@ -79,18 +79,18 @@ 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.67.1'
|
||||
implementation 'io.grpc:grpc-protobuf:1.67.1'
|
||||
implementation 'io.grpc:grpc-stub:1.67.1'
|
||||
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'
|
||||
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.67.1'
|
||||
implementation 'io.grpc:grpc-protobuf-lite:1.67.1'
|
||||
implementation 'io.grpc:grpc-stub:1.67.1'
|
||||
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'
|
||||
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
|
||||
```
|
||||
|
||||
|
@ -99,10 +99,10 @@ For [Bazel](https://bazel.build), you can either
|
|||
(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.67.1
|
||||
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.75.0
|
||||
|
||||
Development snapshots are available in [Sonatypes's snapshot
|
||||
repository](https://oss.sonatype.org/content/repositories/snapshots/).
|
||||
repository](https://central.sonatype.com/repository/maven-snapshots/).
|
||||
|
||||
Generated Code
|
||||
--------------
|
||||
|
@ -129,9 +129,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.3:exe:${os.detected.classifier}</protocArtifact>
|
||||
<protocArtifact>com.google.protobuf:protoc:3.25.5:exe:${os.detected.classifier}</protocArtifact>
|
||||
<pluginId>grpc-java</pluginId>
|
||||
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.67.1:exe:${os.detected.classifier}</pluginArtifact>
|
||||
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.75.0:exe:${os.detected.classifier}</pluginArtifact>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
|
@ -152,16 +152,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.4'
|
||||
id 'com.google.protobuf' version '0.9.5'
|
||||
}
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = "com.google.protobuf:protoc:3.25.3"
|
||||
artifact = "com.google.protobuf:protoc:3.25.5"
|
||||
}
|
||||
plugins {
|
||||
grpc {
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.67.1'
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
@ -185,16 +185,16 @@ use protobuf-gradle-plugin but specify the 'lite' options:
|
|||
|
||||
```gradle
|
||||
plugins {
|
||||
id 'com.google.protobuf' version '0.9.4'
|
||||
id 'com.google.protobuf' version '0.9.5'
|
||||
}
|
||||
|
||||
protobuf {
|
||||
protoc {
|
||||
artifact = "com.google.protobuf:protoc:3.25.3"
|
||||
artifact = "com.google.protobuf:protoc:3.25.5"
|
||||
}
|
||||
plugins {
|
||||
grpc {
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.67.1'
|
||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
|
||||
}
|
||||
}
|
||||
generateProtoTasks {
|
||||
|
|
|
@ -160,21 +160,21 @@ Tagging the Release
|
|||
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).
|
||||
Central on the [OSSRH site](https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#deploying).
|
||||
|
||||
10. We have containers for each release to detect compatibility regressions with
|
||||
old releases. Generate one for the new release by following the [GCR image
|
||||
generation instructions][gcr-image]. Summary:
|
||||
```bash
|
||||
# If you haven't previously configured docker:
|
||||
gcloud auth configure-docker
|
||||
gcloud auth configure-docker us-docker.pkg.dev
|
||||
|
||||
# In main grpc repo, add the new version to matrix
|
||||
${EDITOR:-nano -w} tools/interop_matrix/client_matrix.py
|
||||
tools/interop_matrix/create_matrix_images.py --git_checkout --release=v$MAJOR.$MINOR.$PATCH \
|
||||
--upload_images --language java
|
||||
docker pull gcr.io/grpc-testing/grpc_interop_java:v$MAJOR.$MINOR.$PATCH
|
||||
docker_image=gcr.io/grpc-testing/grpc_interop_java:v$MAJOR.$MINOR.$PATCH \
|
||||
docker pull us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH
|
||||
docker_image=us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH \
|
||||
tools/interop_matrix/testcases/java__master
|
||||
|
||||
# Commit the changes
|
||||
|
|
|
@ -399,7 +399,9 @@ grpc-netty version | netty-handler version | netty-tcnative-boringssl-static ver
|
|||
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 | 4.1.110.Final | 2.0.65.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
|
||||
|
||||
_(grpc-netty-shaded avoids issues with keeping these versions in sync.)_
|
||||
|
||||
|
|
|
@ -22,20 +22,19 @@ 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(
|
||||
|
|
|
@ -18,6 +18,7 @@ java_library(
|
|||
"@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"),
|
||||
|
|
|
@ -2,8 +2,8 @@ plugins {
|
|||
id "java-library"
|
||||
id "maven-publish"
|
||||
|
||||
id "com.github.johnrengelman.shadow"
|
||||
id "com.google.protobuf"
|
||||
id "com.gradleup.shadow"
|
||||
id "ru.vyarus.animalsniffer"
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,11 @@ dependencies {
|
|||
classifier = "linux-x86_64"
|
||||
}
|
||||
}
|
||||
signature libraries.signature.java
|
||||
signature (libraries.signature.java) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configureProtoCompilation()
|
||||
|
|
|
@ -4,9 +4,6 @@ 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 {
|
||||
|
||||
|
@ -60,6 +57,21 @@ 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
|
||||
*/
|
||||
|
@ -157,6 +169,40 @@ 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(
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
* 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;
|
||||
|
@ -29,14 +30,36 @@ public final class AltsContextUtil {
|
|||
private AltsContextUtil() {}
|
||||
|
||||
/**
|
||||
* Creates a {@link AltsContext} from ALTS context information in the {@link ServerCall}.
|
||||
* Creates an {@link AltsContext} from ALTS context information in the {@link ServerCall}.
|
||||
*
|
||||
* @param call the {@link ServerCall} containing the ALTS information
|
||||
* @return the created {@link AltsContext}
|
||||
* @throws IllegalArgumentException if the {@link ServerCall} has no ALTS information.
|
||||
*/
|
||||
public static AltsContext createFrom(ServerCall<?,?> call) {
|
||||
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
|
||||
public static AltsContext createFrom(ServerCall<?, ?> call) {
|
||||
return createFrom(call.getAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link AltsContext} from ALTS context information in the {@link ClientCall}.
|
||||
*
|
||||
* @param call the {@link ClientCall} containing the ALTS information
|
||||
* @return the created {@link AltsContext}
|
||||
* @throws IllegalArgumentException if the {@link ClientCall} has no ALTS information.
|
||||
*/
|
||||
public static AltsContext createFrom(ClientCall<?, ?> call) {
|
||||
return createFrom(call.getAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@link AltsContext} from ALTS context information in the {@link Attributes}.
|
||||
*
|
||||
* @param attributes the {@link Attributes} containing the ALTS information
|
||||
* @return the created {@link AltsContext}
|
||||
* @throws IllegalArgumentException if the {@link Attributes} has no ALTS information.
|
||||
*/
|
||||
public static AltsContext createFrom(Attributes attributes) {
|
||||
Object authContext = attributes.get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
|
||||
if (!(authContext instanceof AltsInternalContext)) {
|
||||
throw new IllegalArgumentException("No ALTS context information found");
|
||||
}
|
||||
|
@ -49,8 +72,28 @@ 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) {
|
||||
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
|
||||
public static boolean check(ServerCall<?, ?> call) {
|
||||
return check(call.getAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the {@link ClientCall} contains ALTS information.
|
||||
*
|
||||
* @param call the {@link ClientCall} to check
|
||||
* @return true, if the {@link ClientCall} contains ALTS information and false otherwise.
|
||||
*/
|
||||
public static boolean check(ClientCall<?, ?> call) {
|
||||
return check(call.getAttributes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the {@link Attributes} contains ALTS information.
|
||||
*
|
||||
* @param attributes the {@link Attributes} to check
|
||||
* @return true, if the {@link Attributes} contains ALTS information and false otherwise.
|
||||
*/
|
||||
public static boolean check(Attributes attributes) {
|
||||
Object authContext = attributes.get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
|
||||
return authContext instanceof AltsInternalContext;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2024 The gRPC Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.grpc.alts;
|
||||
|
||||
import io.grpc.CallCredentials;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
/**
|
||||
* {@code CallCredentials} that will pick the right credentials based on whether the established
|
||||
* connection is ALTS or TLS.
|
||||
*/
|
||||
final class DualCallCredentials extends CallCredentials {
|
||||
private final CallCredentials tlsCallCredentials;
|
||||
private final CallCredentials altsCallCredentials;
|
||||
|
||||
public DualCallCredentials(CallCredentials tlsCallCreds, CallCredentials altsCallCreds) {
|
||||
tlsCallCredentials = tlsCallCreds;
|
||||
altsCallCredentials = altsCallCreds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyRequestMetadata(
|
||||
CallCredentials.RequestInfo requestInfo,
|
||||
Executor appExecutor,
|
||||
CallCredentials.MetadataApplier applier) {
|
||||
if (AltsContextUtil.check(requestInfo.getTransportAttrs())) {
|
||||
altsCallCredentials.applyRequestMetadata(requestInfo, appExecutor, applier);
|
||||
} else {
|
||||
tlsCallCredentials.applyRequestMetadata(requestInfo, appExecutor, applier);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -63,6 +63,7 @@ public final class GoogleDefaultChannelCredentials {
|
|||
*/
|
||||
public static final class Builder {
|
||||
private CallCredentials callCredentials;
|
||||
private CallCredentials altsCallCredentials;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
|
@ -72,23 +73,32 @@ 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());
|
||||
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 tlsCallCreds = callCredentials;
|
||||
if (tlsCallCreds == null) {
|
||||
try {
|
||||
tlsCallCreds = MoreCallCredentials.from(GoogleCredentials.getApplicationDefault());
|
||||
} catch (IOException e) {
|
||||
tlsCallCreds =
|
||||
new FailingCallCredentials(
|
||||
Status.UNAUTHENTICATED
|
||||
.withDescription("Failed to get Google default credentials")
|
||||
.withCause(e));
|
||||
}
|
||||
}
|
||||
CallCredentials callCreds =
|
||||
altsCallCredentials == null
|
||||
? tlsCallCreds
|
||||
: new DualCallCredentials(tlsCallCreds, altsCallCredentials);
|
||||
return CompositeChannelCredentials.create(nettyCredentials, callCreds);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ 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;
|
||||
|
@ -45,6 +46,9 @@ 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;
|
||||
|
||||
|
@ -57,12 +61,16 @@ final class HandshakerServiceChannel {
|
|||
/* Use its own event loop thread pool to avoid blocking. */
|
||||
EventLoopGroup eventGroup =
|
||||
new NioEventLoopGroup(1, new DefaultThreadFactory("handshaker pool", true));
|
||||
ManagedChannel channel = NettyChannelBuilder.forTarget(target)
|
||||
NettyChannelBuilder channelBuilder =
|
||||
NettyChannelBuilder.forTarget(target)
|
||||
.channelType(NioSocketChannel.class, InetSocketAddress.class)
|
||||
.directExecutor()
|
||||
.eventLoopGroup(eventGroup)
|
||||
.usePlaintext()
|
||||
.build();
|
||||
.usePlaintext();
|
||||
if (EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS) {
|
||||
channelBuilder.keepAliveTime(10, TimeUnit.MINUTES).keepAliveTimeout(10, TimeUnit.SECONDS);
|
||||
}
|
||||
ManagedChannel channel = channelBuilder.build();
|
||||
return new EventLoopHoldingChannel(channel, eventGroup);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -24,6 +24,7 @@ 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;
|
||||
|
@ -37,27 +38,28 @@ 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() {
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder().build());
|
||||
|
||||
assertFalse(AltsContextUtil.check(call));
|
||||
assertFalse(AltsContextUtil.check(Attributes.newBuilder().build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contains_unexpectedAttributeValueType() {
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
|
||||
public void check_unexpectedAttributeValueType() {
|
||||
assertFalse(AltsContextUtil.check(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new Object())
|
||||
.build());
|
||||
|
||||
assertFalse(AltsContextUtil.check(call));
|
||||
.build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contains_altsInternalContext() {
|
||||
public void check_altsInternalContext() {
|
||||
assertTrue(AltsContextUtil.check(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
|
||||
.build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkServer_altsInternalContext() {
|
||||
ServerCall<?,?> call = mock(ServerCall.class);
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
|
||||
.build());
|
||||
|
@ -66,26 +68,67 @@ public class AltsContextUtilTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void from_altsInternalContext() {
|
||||
public void checkClient_altsInternalContext() {
|
||||
ClientCall<?,?> call = mock(ClientCall.class);
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
|
||||
.build());
|
||||
|
||||
assertTrue(AltsContextUtil.check(call));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createFrom_altsInternalContext() {
|
||||
HandshakerResult handshakerResult =
|
||||
HandshakerResult.newBuilder()
|
||||
.setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer"))
|
||||
.setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer"))
|
||||
.build();
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult))
|
||||
.build());
|
||||
|
||||
AltsContext context = AltsContextUtil.createFrom(call);
|
||||
AltsContext context = AltsContextUtil.createFrom(Attributes.newBuilder()
|
||||
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult))
|
||||
.build());
|
||||
assertEquals("remote@peer", context.getPeerServiceAccount());
|
||||
assertEquals("local@peer", context.getLocalServiceAccount());
|
||||
assertEquals(SecurityLevel.INTEGRITY_AND_PRIVACY, context.getSecurityLevel());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void from_noAttributeValue() {
|
||||
when(call.getAttributes()).thenReturn(Attributes.newBuilder().build());
|
||||
public void createFrom_noAttributeValue() {
|
||||
AltsContextUtil.createFrom(Attributes.newBuilder().build());
|
||||
}
|
||||
|
||||
AltsContextUtil.createFrom(call);
|
||||
@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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright 2024 The gRPC Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.grpc.alts;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.CallCredentials;
|
||||
import io.grpc.CallCredentials.RequestInfo;
|
||||
import io.grpc.MethodDescriptor;
|
||||
import io.grpc.SecurityLevel;
|
||||
import io.grpc.alts.internal.AltsInternalContext;
|
||||
import io.grpc.alts.internal.AltsProtocolNegotiator;
|
||||
import io.grpc.testing.TestMethodDescriptors;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
/** Unit tests for {@link DualCallCredentials}. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class DualCallCredentialsTest {
|
||||
|
||||
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
@Mock CallCredentials tlsCallCredentials;
|
||||
|
||||
@Mock CallCredentials altsCallCredentials;
|
||||
|
||||
private static final String AUTHORITY = "testauthority";
|
||||
private static final SecurityLevel SECURITY_LEVEL = SecurityLevel.PRIVACY_AND_INTEGRITY;
|
||||
|
||||
@Test
|
||||
public void invokeTlsCallCredentials() {
|
||||
DualCallCredentials callCredentials =
|
||||
new DualCallCredentials(tlsCallCredentials, altsCallCredentials);
|
||||
RequestInfo requestInfo = new RequestInfoImpl(false);
|
||||
callCredentials.applyRequestMetadata(requestInfo, null, null);
|
||||
|
||||
verify(altsCallCredentials, never()).applyRequestMetadata(any(), any(), any());
|
||||
verify(tlsCallCredentials, times(1)).applyRequestMetadata(requestInfo, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeAltsCallCredentials() {
|
||||
DualCallCredentials callCredentials =
|
||||
new DualCallCredentials(tlsCallCredentials, altsCallCredentials);
|
||||
RequestInfo requestInfo = new RequestInfoImpl(true);
|
||||
callCredentials.applyRequestMetadata(requestInfo, null, null);
|
||||
|
||||
verify(altsCallCredentials, times(1)).applyRequestMetadata(requestInfo, null, null);
|
||||
verify(tlsCallCredentials, never()).applyRequestMetadata(any(), any(), any());
|
||||
}
|
||||
|
||||
private static final class RequestInfoImpl extends CallCredentials.RequestInfo {
|
||||
private Attributes attrs;
|
||||
|
||||
RequestInfoImpl(boolean hasAltsContext) {
|
||||
attrs =
|
||||
hasAltsContext
|
||||
? Attributes.newBuilder()
|
||||
.set(
|
||||
AltsProtocolNegotiator.AUTH_CONTEXT_KEY,
|
||||
AltsInternalContext.getDefaultInstance())
|
||||
.build()
|
||||
: Attributes.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodDescriptor<?, ?> getMethodDescriptor() {
|
||||
return TestMethodDescriptors.voidMethod();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityLevel getSecurityLevel() {
|
||||
return SECURITY_LEVEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthority() {
|
||||
return AUTHORITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Attributes getTransportAttrs() {
|
||||
return attrs;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,11 +7,10 @@ description = 'gRPC: Android Integration Testing'
|
|||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'io.grpc.android.integrationtest'
|
||||
namespace = 'io.grpc.android.integrationtest'
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
|
@ -42,7 +41,7 @@ android {
|
|||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
multiDexEnabled = true
|
||||
}
|
||||
buildTypes {
|
||||
debug { minifyEnabled false }
|
||||
|
@ -74,7 +73,6 @@ dependencies {
|
|||
project(':grpc-protobuf-lite'),
|
||||
project(':grpc-stub'),
|
||||
project(':grpc-testing'),
|
||||
libraries.hdrhistogram,
|
||||
libraries.junit,
|
||||
libraries.truth,
|
||||
libraries.androidx.test.rules,
|
||||
|
|
|
@ -7,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -92,6 +89,21 @@ 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
|
||||
*/
|
||||
|
@ -212,6 +224,46 @@ 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,9 +4,6 @@ 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 {
|
||||
|
||||
|
@ -89,6 +86,21 @@ 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
|
||||
*/
|
||||
|
@ -199,6 +211,46 @@ 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,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -92,6 +89,21 @@ 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
|
||||
*/
|
||||
|
@ -200,6 +212,40 @@ 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,9 +8,6 @@ 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 {
|
||||
|
||||
|
@ -273,6 +270,21 @@ 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
|
||||
*/
|
||||
|
@ -543,6 +555,125 @@ 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,9 +8,6 @@ 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 {
|
||||
|
||||
|
@ -63,6 +60,21 @@ 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
|
||||
*/
|
||||
|
@ -166,6 +178,37 @@ 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,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -62,6 +59,21 @@ 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
|
||||
*/
|
||||
|
@ -161,6 +173,36 @@ 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,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -92,6 +89,21 @@ 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
|
||||
*/
|
||||
|
@ -200,6 +212,40 @@ 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,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -92,6 +89,21 @@ 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
|
||||
*/
|
||||
|
@ -212,6 +224,46 @@ 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,9 +4,6 @@ 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 {
|
||||
|
||||
|
@ -89,6 +86,21 @@ 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
|
||||
*/
|
||||
|
@ -199,6 +211,46 @@ 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,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -92,6 +89,21 @@ 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
|
||||
*/
|
||||
|
@ -200,6 +212,40 @@ 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,9 +8,6 @@ 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 {
|
||||
|
||||
|
@ -273,6 +270,21 @@ 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
|
||||
*/
|
||||
|
@ -543,6 +555,125 @@ 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,9 +8,6 @@ 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 {
|
||||
|
||||
|
@ -63,6 +60,21 @@ 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
|
||||
*/
|
||||
|
@ -166,6 +178,37 @@ 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,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -62,6 +59,21 @@ 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
|
||||
*/
|
||||
|
@ -161,6 +173,36 @@ 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,9 +7,6 @@ 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 {
|
||||
|
||||
|
@ -92,6 +89,21 @@ 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
|
||||
*/
|
||||
|
@ -200,6 +212,40 @@ 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,20 +7,20 @@ plugins {
|
|||
description = 'gRPC: Android'
|
||||
|
||||
android {
|
||||
namespace 'io.grpc.android'
|
||||
namespace = 'io.grpc.android'
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
compileSdkVersion 34
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
minSdkVersion 22
|
||||
targetSdkVersion 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
lintOptions { abortOnError true }
|
||||
lintOptions { abortOnError = true }
|
||||
publishing {
|
||||
singleVariant('release') {
|
||||
withSourcesJar()
|
||||
|
@ -31,7 +31,6 @@ android {
|
|||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -28,6 +28,7 @@ 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;
|
||||
|
@ -41,7 +42,6 @@ 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
|
||||
|
@ -217,7 +217,6 @@ 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);
|
||||
|
@ -231,7 +230,6 @@ 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);
|
||||
|
|
|
@ -6,7 +6,6 @@ java_library(
|
|||
"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"),
|
||||
|
|
|
@ -47,9 +47,22 @@ dependencies {
|
|||
testImplementation project(':grpc-core')
|
||||
testImplementation project(':grpc-testing')
|
||||
testImplementation libraries.guava.testlib
|
||||
testImplementation libraries.truth
|
||||
|
||||
signature libraries.signature.java
|
||||
signature libraries.signature.android
|
||||
signature (libraries.signature.java) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
signature (libraries.signature.android) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
animalsniffer {
|
||||
annotation = 'io.grpc.IgnoreJRERequirement'
|
||||
}
|
||||
|
||||
tasks.named("javadoc").configure {
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import java.util.Arrays;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -33,7 +35,7 @@ import java.util.concurrent.TimeUnit;
|
|||
* passed to the various components unambiguously.
|
||||
*/
|
||||
public final class Deadline implements Comparable<Deadline> {
|
||||
private static final SystemTicker SYSTEM_TICKER = new SystemTicker();
|
||||
private static final Ticker SYSTEM_TICKER = new SystemTicker();
|
||||
// nanoTime has a range of just under 300 years. Only allow up to 100 years in the past or future
|
||||
// to prevent wraparound as long as process runs for less than ~100 years.
|
||||
private static final long MAX_OFFSET = TimeUnit.DAYS.toNanos(100 * 365);
|
||||
|
@ -91,7 +93,7 @@ public final class Deadline implements Comparable<Deadline> {
|
|||
* @since 1.24.0
|
||||
*/
|
||||
public static Deadline after(long duration, TimeUnit units, Ticker ticker) {
|
||||
checkNotNull(units, "units");
|
||||
requireNonNull(units, "units");
|
||||
return new Deadline(ticker, units.toNanos(duration), true);
|
||||
}
|
||||
|
||||
|
@ -191,8 +193,8 @@ public final class Deadline implements Comparable<Deadline> {
|
|||
* @return {@link ScheduledFuture} which can be used to cancel execution of the task
|
||||
*/
|
||||
public ScheduledFuture<?> runOnExpiration(Runnable task, ScheduledExecutorService scheduler) {
|
||||
checkNotNull(task, "task");
|
||||
checkNotNull(scheduler, "scheduler");
|
||||
requireNonNull(task, "task");
|
||||
requireNonNull(scheduler, "scheduler");
|
||||
return scheduler.schedule(task, deadlineNanos - ticker.nanoTime(), TimeUnit.NANOSECONDS);
|
||||
}
|
||||
|
||||
|
@ -225,37 +227,27 @@ public final class Deadline implements Comparable<Deadline> {
|
|||
@Override
|
||||
public int compareTo(Deadline that) {
|
||||
checkTicker(that);
|
||||
long diff = this.deadlineNanos - that.deadlineNanos;
|
||||
if (diff < 0) {
|
||||
return -1;
|
||||
} else if (diff > 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
return Long.compare(this.deadlineNanos, that.deadlineNanos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.asList(this.ticker, this.deadlineNanos).hashCode();
|
||||
return Objects.hash(this.ticker, this.deadlineNanos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this) {
|
||||
public boolean equals(final Object object) {
|
||||
if (object == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Deadline)) {
|
||||
if (!(object instanceof Deadline)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final Deadline other = (Deadline) o;
|
||||
if (this.ticker == null ? other.ticker != null : this.ticker != other.ticker) {
|
||||
final Deadline that = (Deadline) object;
|
||||
if (this.ticker == null ? that.ticker != null : this.ticker != that.ticker) {
|
||||
return false;
|
||||
}
|
||||
if (this.deadlineNanos != other.deadlineNanos) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return this.deadlineNanos == that.deadlineNanos;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,24 +267,17 @@ public final class Deadline implements Comparable<Deadline> {
|
|||
* @since 1.24.0
|
||||
*/
|
||||
public abstract static class Ticker {
|
||||
/** Returns the number of nanoseconds since this source's epoch. */
|
||||
/** Returns the number of nanoseconds elapsed since this ticker's reference point in time. */
|
||||
public abstract long nanoTime();
|
||||
}
|
||||
|
||||
private static class SystemTicker extends Ticker {
|
||||
private static final class SystemTicker extends Ticker {
|
||||
@Override
|
||||
public long nanoTime() {
|
||||
return System.nanoTime();
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T checkNotNull(T reference, Object errorMessage) {
|
||||
if (reference == null) {
|
||||
throw new NullPointerException(String.valueOf(errorMessage));
|
||||
}
|
||||
return reference;
|
||||
}
|
||||
|
||||
private void checkTicker(Deadline other) {
|
||||
if (ticker != other.ticker) {
|
||||
throw new AssertionError(
|
||||
|
|
|
@ -17,16 +17,18 @@
|
|||
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;
|
||||
|
||||
|
@ -176,6 +178,11 @@ 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.
|
||||
*/
|
||||
|
|
|
@ -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>.
|
||||
*
|
||||
* <p><pre>
|
||||
* <pre>
|
||||
* call = channel.newCall(bidiStreamingMethod, callOptions);
|
||||
* listener = new ClientCall.Listener<FooResponse>() {
|
||||
* @Override
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
|
||||
/**
|
||||
* A registry for {@link Configurator} instances.
|
||||
|
@ -33,9 +33,9 @@ final class ConfiguratorRegistry {
|
|||
@GuardedBy("this")
|
||||
private boolean wasConfiguratorsSet;
|
||||
@GuardedBy("this")
|
||||
private boolean configFrozen;
|
||||
@GuardedBy("this")
|
||||
private List<Configurator> configurators = Collections.emptyList();
|
||||
@GuardedBy("this")
|
||||
private int configuratorsCallCountBeforeSet = 0;
|
||||
|
||||
ConfiguratorRegistry() {}
|
||||
|
||||
|
@ -56,11 +56,10 @@ final class ConfiguratorRegistry {
|
|||
* @throws IllegalStateException if this method is called more than once
|
||||
*/
|
||||
public synchronized void setConfigurators(List<? extends Configurator> configurators) {
|
||||
if (configFrozen) {
|
||||
if (wasConfiguratorsSet) {
|
||||
throw new IllegalStateException("Configurators are already set");
|
||||
}
|
||||
this.configurators = Collections.unmodifiableList(new ArrayList<>(configurators));
|
||||
configFrozen = true;
|
||||
wasConfiguratorsSet = true;
|
||||
}
|
||||
|
||||
|
@ -68,10 +67,20 @@ final class ConfiguratorRegistry {
|
|||
* Returns a list of the configurators in this registry.
|
||||
*/
|
||||
public synchronized List<Configurator> getConfigurators() {
|
||||
configFrozen = true;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -263,6 +263,12 @@ public abstract class ForwardingChannelBuilder2<T extends ManagedChannelBuilder<
|
|||
return thisT();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> T setNameResolverArg(NameResolver.Args.Key<X> key, X value) {
|
||||
delegate().setNameResolverArg(key, value);
|
||||
return thisT();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ManagedChannel} built by the delegate by default. Overriding method can
|
||||
* return different value.
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 PRC. */
|
||||
/** Selects the config for an RPC. */
|
||||
public abstract Result selectConfig(LoadBalancer.PickSubchannelArgs args);
|
||||
|
||||
public static final class Result {
|
||||
|
|
|
@ -48,4 +48,8 @@ public final class InternalConfiguratorRegistry {
|
|||
public static boolean wasSetConfiguratorsCalled() {
|
||||
return ConfiguratorRegistry.getDefaultRegistry().wasSetConfiguratorsCalled();
|
||||
}
|
||||
|
||||
public static int getConfiguratorsCallCountBeforeSet() {
|
||||
return ConfiguratorRegistry.getDefaultRegistry().getConfiguratorsCallCountBeforeSet();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,12 +38,11 @@ public final class InternalStatus {
|
|||
public static final Metadata.Key<Status> CODE_KEY = Status.CODE_KEY;
|
||||
|
||||
/**
|
||||
* Create a new {@link StatusRuntimeException} with the internal option of skipping the filling
|
||||
* of the stack trace.
|
||||
* Create a new {@link StatusRuntimeException} skipping the filling of the stack trace.
|
||||
*/
|
||||
@Internal
|
||||
public static final StatusRuntimeException asRuntimeException(Status status,
|
||||
@Nullable Metadata trailers, boolean fillInStackTrace) {
|
||||
return new StatusRuntimeException(status, trailers, fillInStackTrace);
|
||||
public static StatusRuntimeException asRuntimeExceptionWithoutStacktrace(Status status,
|
||||
@Nullable Metadata trailers) {
|
||||
return new InternalStatusRuntimeException(status, trailers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2015 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 javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* StatusRuntimeException without stack trace, implemented as a subclass, as the
|
||||
* {@code String, Throwable, boolean, boolean} constructor is not available in the supported
|
||||
* version of Android.
|
||||
*
|
||||
* @see StatusRuntimeException
|
||||
*/
|
||||
class InternalStatusRuntimeException extends StatusRuntimeException {
|
||||
private static final long serialVersionUID = 0;
|
||||
|
||||
public InternalStatusRuntimeException(Status status, @Nullable Metadata trailers) {
|
||||
super(status, trailers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Throwable fillInStackTrace() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* 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.time.Duration;
|
||||
|
||||
@Internal
|
||||
public final class InternalTimeUtils {
|
||||
public static long convert(Duration duration) {
|
||||
return TimeUtils.convertToNanos(duration);
|
||||
}
|
||||
}
|
|
@ -212,7 +212,7 @@ public abstract class LoadBalancer {
|
|||
*
|
||||
* @since 1.21.0
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
|
||||
public static final class ResolvedAddresses {
|
||||
private final List<EquivalentAddressGroup> addresses;
|
||||
@NameResolver.ResolutionResultAttr
|
||||
|
@ -452,18 +452,6 @@ public abstract class LoadBalancer {
|
|||
* @since 1.3.0
|
||||
*/
|
||||
public abstract PickResult pickSubchannel(PickSubchannelArgs args);
|
||||
|
||||
/**
|
||||
* Tries to establish connections now so that the upcoming RPC may then just pick a ready
|
||||
* connection without having to connect first.
|
||||
*
|
||||
* <p>No-op if unsupported.
|
||||
*
|
||||
* @deprecated override {@link LoadBalancer#requestConnection} instead.
|
||||
* @since 1.11.0
|
||||
*/
|
||||
@Deprecated
|
||||
public void requestConnection() {}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -552,6 +540,7 @@ public abstract class LoadBalancer {
|
|||
private final Status status;
|
||||
// True if the result is created by withDrop()
|
||||
private final boolean drop;
|
||||
@Nullable private final String authorityOverride;
|
||||
|
||||
private PickResult(
|
||||
@Nullable Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory,
|
||||
|
@ -560,6 +549,17 @@ public abstract class LoadBalancer {
|
|||
this.streamTracerFactory = streamTracerFactory;
|
||||
this.status = checkNotNull(status, "status");
|
||||
this.drop = drop;
|
||||
this.authorityOverride = null;
|
||||
}
|
||||
|
||||
private PickResult(
|
||||
@Nullable Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory,
|
||||
Status status, boolean drop, @Nullable String authorityOverride) {
|
||||
this.subchannel = subchannel;
|
||||
this.streamTracerFactory = streamTracerFactory;
|
||||
this.status = checkNotNull(status, "status");
|
||||
this.drop = drop;
|
||||
this.authorityOverride = authorityOverride;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -639,6 +639,19 @@ public abstract class LoadBalancer {
|
|||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@code withSubchannel(subchannel, streamTracerFactory)} but with an authority name
|
||||
* to override in the host header.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11656")
|
||||
public static PickResult withSubchannel(
|
||||
Subchannel subchannel, @Nullable ClientStreamTracer.Factory streamTracerFactory,
|
||||
@Nullable String authorityOverride) {
|
||||
return new PickResult(
|
||||
checkNotNull(subchannel, "subchannel"), streamTracerFactory, Status.OK,
|
||||
false, authorityOverride);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@code withSubchannel(subchannel, null)}.
|
||||
*
|
||||
|
@ -682,6 +695,13 @@ public abstract class LoadBalancer {
|
|||
return NO_RESULT;
|
||||
}
|
||||
|
||||
/** Returns the authority override if any. */
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11656")
|
||||
@Nullable
|
||||
public String getAuthorityOverride() {
|
||||
return authorityOverride;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Subchannel if this result was created by {@link #withSubchannel withSubchannel()}, or
|
||||
* null otherwise.
|
||||
|
@ -736,6 +756,7 @@ public abstract class LoadBalancer {
|
|||
.add("streamTracerFactory", streamTracerFactory)
|
||||
.add("status", status)
|
||||
.add("drop", drop)
|
||||
.add("authority-override", authorityOverride)
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
@ -1000,8 +1021,8 @@ public abstract class LoadBalancer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Out-of-band channel for LoadBalancer’s own RPC needs, e.g., talking to an external
|
||||
* load-balancer service.
|
||||
* Create an out-of-band channel for the LoadBalancer’s own RPC needs, e.g., talking to an
|
||||
* external load-balancer service.
|
||||
*
|
||||
* <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
|
||||
* channels within {@link #shutdown}.
|
||||
|
@ -1011,7 +1032,12 @@ public abstract class LoadBalancer {
|
|||
public abstract ManagedChannel createOobChannel(EquivalentAddressGroup eag, String authority);
|
||||
|
||||
/**
|
||||
* Accept a list of EAG for multiple authorities: https://github.com/grpc/grpc-java/issues/4618
|
||||
* Create an out-of-band channel for the LoadBalancer's own RPC needs, e.g., talking to an
|
||||
* external load-balancer service. This version of the method allows multiple EAGs, so different
|
||||
* addresses can have different authorities.
|
||||
*
|
||||
* <p>The LoadBalancer is responsible for closing unused OOB channels, and closing all OOB
|
||||
* channels within {@link #shutdown}.
|
||||
* */
|
||||
public ManagedChannel createOobChannel(List<EquivalentAddressGroup> eag,
|
||||
String authority) {
|
||||
|
@ -1163,6 +1189,10 @@ public abstract class LoadBalancer {
|
|||
* Returns a {@link SynchronizationContext} that runs tasks in the same Synchronization Context
|
||||
* as that the callback methods on the {@link LoadBalancer} interface are run in.
|
||||
*
|
||||
* <p>Work added to the synchronization context might not run immediately, so LB implementations
|
||||
* must be careful to ensure that any assumptions still hold when it is executed. In particular,
|
||||
* the LB might have been shut down or subchannels might have changed state.
|
||||
*
|
||||
* <p>Pro-tip: in order to call {@link SynchronizationContext#schedule}, you need to provide a
|
||||
* {@link ScheduledExecutorService}. {@link #getScheduledExecutorService} is provided for your
|
||||
* convenience.
|
||||
|
|
|
@ -633,6 +633,23 @@ public abstract class ManagedChannelBuilder<T extends ManagedChannelBuilder<T>>
|
|||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a "custom" argument for the {@link NameResolver}, if applicable, replacing any 'value'
|
||||
* previously provided for 'key'.
|
||||
*
|
||||
* <p>NB: If the selected {@link NameResolver} does not understand 'key', or target URI resolution
|
||||
* isn't needed at all, your custom argument will be silently ignored.
|
||||
*
|
||||
* <p>See {@link NameResolver.Args#getArg(NameResolver.Args.Key)} for more.
|
||||
*
|
||||
* @param key identifies the argument in a type-safe manner
|
||||
* @param value the argument itself
|
||||
* @return this
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1770")
|
||||
public <X> T setNameResolverArg(NameResolver.Args.Key<X> key, X value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a channel using the given parameters.
|
||||
|
|
|
@ -18,6 +18,7 @@ package io.grpc;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
@ -30,7 +31,6 @@ import java.util.LinkedHashSet;
|
|||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,8 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -32,8 +34,6 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
@ -325,7 +325,7 @@ public final class Metadata {
|
|||
if (isEmpty()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<String> ks = new HashSet<>(size);
|
||||
Set<String> ks = Sets.newHashSetWithExpectedSize(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
ks.add(new String(name(i), 0 /* hibyte */));
|
||||
}
|
||||
|
@ -526,7 +526,7 @@ public final class Metadata {
|
|||
public void merge(Metadata other, Set<Key<?>> keys) {
|
||||
Preconditions.checkNotNull(other, "other");
|
||||
// Use ByteBuffer for equals and hashCode.
|
||||
Map<ByteBuffer, Key<?>> asciiKeys = new HashMap<>(keys.size());
|
||||
Map<ByteBuffer, Key<?>> asciiKeys = Maps.newHashMapWithExpectedSize(keys.size());
|
||||
for (Key<?> key : keys) {
|
||||
asciiKeys.put(ByteBuffer.wrap(key.asciiName()), key);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,9 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
|
|
@ -21,12 +21,12 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
|
||||
/**
|
||||
* A registry for globally registered metric instruments.
|
||||
|
|
|
@ -28,11 +28,13 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
/**
|
||||
|
@ -219,13 +221,15 @@ public abstract class NameResolver {
|
|||
@Override
|
||||
@Deprecated
|
||||
@InlineMe(
|
||||
replacement = "this.onResult2(ResolutionResult.newBuilder().setAddressesOrError("
|
||||
replacement = "this.onResult(ResolutionResult.newBuilder().setAddressesOrError("
|
||||
+ "StatusOr.fromValue(servers)).setAttributes(attributes).build())",
|
||||
imports = {"io.grpc.NameResolver.ResolutionResult", "io.grpc.StatusOr"})
|
||||
public final void onAddresses(
|
||||
List<EquivalentAddressGroup> servers, @ResolutionResultAttr Attributes attributes) {
|
||||
// TODO(jihuncho) need to promote Listener2 if we want to use ConfigOrError
|
||||
onResult2(
|
||||
// Calling onResult and not onResult2 because onResult2 can only be called from a
|
||||
// synchronization context.
|
||||
onResult(
|
||||
ResolutionResult.newBuilder().setAddressesOrError(
|
||||
StatusOr.fromValue(servers)).setAttributes(attributes).build());
|
||||
}
|
||||
|
@ -235,6 +239,9 @@ public abstract class NameResolver {
|
|||
* {@link ResolutionResult#getAddressesOrError()} is empty, {@link #onError(Status)} will be
|
||||
* called.
|
||||
*
|
||||
* <p>Newer NameResolver implementations should prefer calling onResult2. This method exists to
|
||||
* facilitate older {@link Listener} implementations to migrate to {@link Listener2}.
|
||||
*
|
||||
* @param resolutionResult the resolved server addresses, attributes, and Service Config.
|
||||
* @since 1.21.0
|
||||
*/
|
||||
|
@ -244,6 +251,10 @@ public abstract class NameResolver {
|
|||
* Handles a name resolving error from the resolver. The listener is responsible for eventually
|
||||
* invoking {@link NameResolver#refresh()} to re-attempt resolution.
|
||||
*
|
||||
* <p>New NameResolver implementations should prefer calling onResult2 which will have the
|
||||
* address resolution error in {@link ResolutionResult}'s addressesOrError. This method exists
|
||||
* to facilitate older implementations using {@link Listener} to migrate to {@link Listener2}.
|
||||
*
|
||||
* @param error a non-OK status
|
||||
* @since 1.21.0
|
||||
*/
|
||||
|
@ -251,9 +262,14 @@ public abstract class NameResolver {
|
|||
public abstract void onError(Status error);
|
||||
|
||||
/**
|
||||
* Handles updates on resolved addresses and attributes.
|
||||
* Handles updates on resolved addresses and attributes. Must be called from the same
|
||||
* {@link SynchronizationContext} available in {@link NameResolver.Args} that is passed
|
||||
* from the channel.
|
||||
*
|
||||
* @param resolutionResult the resolved server addresses, attributes, and Service Config.
|
||||
* @param resolutionResult the resolved server addresses or error in address resolution,
|
||||
* attributes, and Service Config or error
|
||||
* @return status indicating whether the resolutionResult was accepted by the listener,
|
||||
* typically the result from a load balancer.
|
||||
* @since 1.66
|
||||
*/
|
||||
public Status onResult2(ResolutionResult resolutionResult) {
|
||||
|
@ -271,10 +287,20 @@ public abstract class NameResolver {
|
|||
@Documented
|
||||
public @interface ResolutionResultAttr {}
|
||||
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11989")
|
||||
@ResolutionResultAttr
|
||||
public static final Attributes.Key<String> ATTR_BACKEND_SERVICE =
|
||||
Attributes.Key.create("io.grpc.NameResolver.ATTR_BACKEND_SERVICE");
|
||||
|
||||
/**
|
||||
* Information that a {@link Factory} uses to create a {@link NameResolver}.
|
||||
*
|
||||
* <p>Note this class doesn't override neither {@code equals()} nor {@code hashCode()}.
|
||||
* <p>Args applicable to all {@link NameResolver}s are defined here using ordinary setters and
|
||||
* getters. This container can also hold externally-defined "custom" args that aren't so widely
|
||||
* useful or that would be inappropriate dependencies for this low level API. See {@link
|
||||
* Args#getArg} for more.
|
||||
*
|
||||
* <p>Note this class overrides neither {@code equals()} nor {@code hashCode()}.
|
||||
*
|
||||
* @since 1.21.0
|
||||
*/
|
||||
|
@ -288,24 +314,23 @@ public abstract class NameResolver {
|
|||
@Nullable private final ChannelLogger channelLogger;
|
||||
@Nullable private final Executor executor;
|
||||
@Nullable private final String overrideAuthority;
|
||||
@Nullable private final MetricRecorder metricRecorder;
|
||||
@Nullable private final NameResolverRegistry nameResolverRegistry;
|
||||
@Nullable private final IdentityHashMap<Key<?>, Object> customArgs;
|
||||
|
||||
private Args(
|
||||
Integer defaultPort,
|
||||
ProxyDetector proxyDetector,
|
||||
SynchronizationContext syncContext,
|
||||
ServiceConfigParser serviceConfigParser,
|
||||
@Nullable ScheduledExecutorService scheduledExecutorService,
|
||||
@Nullable ChannelLogger channelLogger,
|
||||
@Nullable Executor executor,
|
||||
@Nullable String overrideAuthority) {
|
||||
this.defaultPort = checkNotNull(defaultPort, "defaultPort not set");
|
||||
this.proxyDetector = checkNotNull(proxyDetector, "proxyDetector not set");
|
||||
this.syncContext = checkNotNull(syncContext, "syncContext not set");
|
||||
this.serviceConfigParser = checkNotNull(serviceConfigParser, "serviceConfigParser not set");
|
||||
this.scheduledExecutorService = scheduledExecutorService;
|
||||
this.channelLogger = channelLogger;
|
||||
this.executor = executor;
|
||||
this.overrideAuthority = overrideAuthority;
|
||||
private Args(Builder builder) {
|
||||
this.defaultPort = checkNotNull(builder.defaultPort, "defaultPort not set");
|
||||
this.proxyDetector = checkNotNull(builder.proxyDetector, "proxyDetector not set");
|
||||
this.syncContext = checkNotNull(builder.syncContext, "syncContext not set");
|
||||
this.serviceConfigParser =
|
||||
checkNotNull(builder.serviceConfigParser, "serviceConfigParser not set");
|
||||
this.scheduledExecutorService = builder.scheduledExecutorService;
|
||||
this.channelLogger = builder.channelLogger;
|
||||
this.executor = builder.executor;
|
||||
this.overrideAuthority = builder.overrideAuthority;
|
||||
this.metricRecorder = builder.metricRecorder;
|
||||
this.nameResolverRegistry = builder.nameResolverRegistry;
|
||||
this.customArgs = cloneCustomArgs(builder.customArgs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,6 +339,7 @@ public abstract class NameResolver {
|
|||
*
|
||||
* @since 1.21.0
|
||||
*/
|
||||
// <p>TODO: Only meaningful for InetSocketAddress producers. Make this a custom arg?
|
||||
public int getDefaultPort() {
|
||||
return defaultPort;
|
||||
}
|
||||
|
@ -366,6 +392,30 @@ public abstract class NameResolver {
|
|||
return serviceConfigParser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of a custom arg named 'key', or {@code null} if it's not set.
|
||||
*
|
||||
* <p>While ordinary {@link Args} should be universally useful and meaningful, custom arguments
|
||||
* can apply just to resolvers of a certain URI scheme, just to resolvers producing a particular
|
||||
* type of {@link java.net.SocketAddress}, or even an individual {@link NameResolver} subclass.
|
||||
* Custom args are identified by an instance of {@link Args.Key} which should be a constant
|
||||
* defined in a java package and class appropriate for the argument's scope.
|
||||
*
|
||||
* <p>{@link Args} are normally reserved for information in *support* of name resolution, not
|
||||
* the name to be resolved itself. However, there are rare cases where all or part of the target
|
||||
* name can't be represented by any standard URI scheme or can't be encoded as a String at all.
|
||||
* Custom args, in contrast, can hold arbitrary Java types, making them a useful work around in
|
||||
* these cases.
|
||||
*
|
||||
* <p>Custom args can also be used simply to avoid adding inappropriate deps to the low level
|
||||
* io.grpc package.
|
||||
*/
|
||||
@SuppressWarnings("unchecked") // Cast is safe because all put()s go through the setArg() API.
|
||||
@Nullable
|
||||
public <T> T getArg(Key<T> key) {
|
||||
return customArgs != null ? (T) customArgs.get(key) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ChannelLogger} for the Channel served by this NameResolver.
|
||||
*
|
||||
|
@ -403,6 +453,26 @@ public abstract class NameResolver {
|
|||
return overrideAuthority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link MetricRecorder} that the channel uses to record metrics.
|
||||
*/
|
||||
@Nullable
|
||||
public MetricRecorder getMetricRecorder() {
|
||||
return metricRecorder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link NameResolverRegistry} that the Channel uses to look for {@link
|
||||
* NameResolver}s.
|
||||
*
|
||||
* @since 1.74.0
|
||||
*/
|
||||
public NameResolverRegistry getNameResolverRegistry() {
|
||||
if (nameResolverRegistry == null) {
|
||||
throw new IllegalStateException("NameResolverRegistry is not set in Builder");
|
||||
}
|
||||
return nameResolverRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -411,10 +481,13 @@ public abstract class NameResolver {
|
|||
.add("proxyDetector", proxyDetector)
|
||||
.add("syncContext", syncContext)
|
||||
.add("serviceConfigParser", serviceConfigParser)
|
||||
.add("customArgs", customArgs)
|
||||
.add("scheduledExecutorService", scheduledExecutorService)
|
||||
.add("channelLogger", channelLogger)
|
||||
.add("executor", executor)
|
||||
.add("overrideAuthority", overrideAuthority)
|
||||
.add("metricRecorder", metricRecorder)
|
||||
.add("nameResolverRegistry", nameResolverRegistry)
|
||||
.toString();
|
||||
}
|
||||
|
||||
|
@ -433,6 +506,9 @@ public abstract class NameResolver {
|
|||
builder.setChannelLogger(channelLogger);
|
||||
builder.setOffloadExecutor(executor);
|
||||
builder.setOverrideAuthority(overrideAuthority);
|
||||
builder.setMetricRecorder(metricRecorder);
|
||||
builder.setNameResolverRegistry(nameResolverRegistry);
|
||||
builder.customArgs = cloneCustomArgs(customArgs);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
@ -459,6 +535,9 @@ public abstract class NameResolver {
|
|||
private ChannelLogger channelLogger;
|
||||
private Executor executor;
|
||||
private String overrideAuthority;
|
||||
private MetricRecorder metricRecorder;
|
||||
private NameResolverRegistry nameResolverRegistry;
|
||||
private IdentityHashMap<Key<?>, Object> customArgs;
|
||||
|
||||
Builder() {
|
||||
}
|
||||
|
@ -545,16 +624,75 @@ public abstract class NameResolver {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** See {@link Args#getArg(Key)}. */
|
||||
public <T> Builder setArg(Key<T> key, T value) {
|
||||
checkNotNull(key, "key");
|
||||
checkNotNull(value, "value");
|
||||
if (customArgs == null) {
|
||||
customArgs = new IdentityHashMap<>();
|
||||
}
|
||||
customArgs.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link Args#getMetricRecorder()}. This is an optional field.
|
||||
*/
|
||||
public Builder setMetricRecorder(MetricRecorder metricRecorder) {
|
||||
this.metricRecorder = metricRecorder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link Args#getNameResolverRegistry}. This is an optional field.
|
||||
*
|
||||
* @since 1.74.0
|
||||
*/
|
||||
public Builder setNameResolverRegistry(NameResolverRegistry registry) {
|
||||
this.nameResolverRegistry = registry;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an {@link Args}.
|
||||
*
|
||||
* @since 1.21.0
|
||||
*/
|
||||
public Args build() {
|
||||
return
|
||||
new Args(
|
||||
defaultPort, proxyDetector, syncContext, serviceConfigParser,
|
||||
scheduledExecutorService, channelLogger, executor, overrideAuthority);
|
||||
return new Args(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies an externally-defined custom argument that can be stored in {@link Args}.
|
||||
*
|
||||
* <p>Uses reference equality so keys should be defined as global constants.
|
||||
*
|
||||
* @param <T> type of values that can be stored under this key
|
||||
*/
|
||||
@Immutable
|
||||
@SuppressWarnings("UnusedTypeParameter")
|
||||
public static final class Key<T> {
|
||||
private final String debugString;
|
||||
|
||||
private Key(String debugString) {
|
||||
this.debugString = debugString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return debugString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link Key}.
|
||||
*
|
||||
* @param debugString a string used to describe the key, used for debugging.
|
||||
* @param <T> Key type
|
||||
* @return a new instance of Key
|
||||
*/
|
||||
public static <T> Key<T> create(String debugString) {
|
||||
return new Key<>(debugString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -852,4 +990,10 @@ public abstract class NameResolver {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static IdentityHashMap<Args.Key<?>, Object> cloneCustomArgs(
|
||||
@Nullable IdentityHashMap<Args.Key<?>, Object> customArgs) {
|
||||
return customArgs != null ? new IdentityHashMap<>(customArgs) : null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
@ -31,7 +32,6 @@ import java.util.Map;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
/**
|
||||
|
@ -166,6 +166,11 @@ public final class NameResolverRegistry {
|
|||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.FINE, "Unable to find DNS NameResolver", e);
|
||||
}
|
||||
try {
|
||||
list.add(Class.forName("io.grpc.binder.internal.IntentNameResolverProvider"));
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.FINE, "Unable to find IntentNameResolverProvider", e);
|
||||
}
|
||||
return Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ package io.grpc;
|
|||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
@ -25,7 +26,6 @@ import java.util.LinkedHashSet;
|
|||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
|
||||
/**
|
||||
|
|
|
@ -23,6 +23,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
|
|||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import io.grpc.Metadata.TrustedAsciiMarshaller;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
@ -30,7 +31,6 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.TreeMap;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
|
|
|
@ -44,12 +44,7 @@ public class StatusException extends Exception {
|
|||
* @since 1.0.0
|
||||
*/
|
||||
public StatusException(Status status, @Nullable Metadata trailers) {
|
||||
this(status, trailers, /*fillInStackTrace=*/ true);
|
||||
}
|
||||
|
||||
StatusException(Status status, @Nullable Metadata trailers, boolean fillInStackTrace) {
|
||||
super(Status.formatThrowableMessage(status), status.getCause(),
|
||||
/* enableSuppression */ true, /* writableStackTrace */fillInStackTrace);
|
||||
super(Status.formatThrowableMessage(status), status.getCause());
|
||||
this.status = status;
|
||||
this.trailers = trailers;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,14 @@ public class StatusOr<T> {
|
|||
return status == null ? Status.OK : status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that StatusOr containing statuses, the equality comparision is delegated to
|
||||
* {@link Status#equals} which just does a reference equality check because equality on
|
||||
* Statuses is not well defined.
|
||||
* Instead, do comparison based on their Code with {@link Status#getCode}. The description and
|
||||
* cause of the Status are unlikely to be stable, and additional fields may be added to Status
|
||||
* in the future.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof StatusOr)) {
|
||||
|
|
|
@ -45,12 +45,7 @@ public class StatusRuntimeException extends RuntimeException {
|
|||
* @since 1.0.0
|
||||
*/
|
||||
public StatusRuntimeException(Status status, @Nullable Metadata trailers) {
|
||||
this(status, trailers, /*fillInStackTrace=*/ true);
|
||||
}
|
||||
|
||||
StatusRuntimeException(Status status, @Nullable Metadata trailers, boolean fillInStackTrace) {
|
||||
super(Status.formatThrowableMessage(status), status.getCause(),
|
||||
/* enable suppressions */ true, /* writableStackTrace */ fillInStackTrace);
|
||||
super(Status.formatThrowableMessage(status), status.getCause());
|
||||
this.status = status;
|
||||
this.trailers = trailers;
|
||||
}
|
||||
|
|
|
@ -18,8 +18,10 @@ package io.grpc;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static io.grpc.TimeUtils.convertToNanos;
|
||||
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.time.Duration;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Executor;
|
||||
|
@ -162,6 +164,12 @@ public final class SynchronizationContext implements Executor {
|
|||
return new ScheduledHandle(runnable, future);
|
||||
}
|
||||
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
|
||||
public final ScheduledHandle schedule(
|
||||
final Runnable task, Duration delay, ScheduledExecutorService timerService) {
|
||||
return schedule(task, convertToNanos(delay), TimeUnit.NANOSECONDS, timerService);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a task to be added and run via {@link #execute} after an initial delay and then
|
||||
* repeated after the delay until cancelled.
|
||||
|
@ -193,6 +201,14 @@ public final class SynchronizationContext implements Executor {
|
|||
return new ScheduledHandle(runnable, future);
|
||||
}
|
||||
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
|
||||
public final ScheduledHandle scheduleWithFixedDelay(
|
||||
final Runnable task, Duration initialDelay, Duration delay,
|
||||
ScheduledExecutorService timerService) {
|
||||
return scheduleWithFixedDelay(task, convertToNanos(initialDelay), convertToNanos(delay),
|
||||
TimeUnit.NANOSECONDS, timerService);
|
||||
}
|
||||
|
||||
|
||||
private static class ManagedRunnable implements Runnable {
|
||||
final Runnable task;
|
||||
|
@ -246,4 +262,4 @@ public final class SynchronizationContext implements Executor {
|
|||
return !(runnable.hasStarted || runnable.isCancelled);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.time.Duration;
|
||||
|
||||
final class TimeUtils {
|
||||
private TimeUtils() {}
|
||||
|
||||
@IgnoreJRERequirement
|
||||
static long convertToNanos(Duration duration) {
|
||||
try {
|
||||
return duration.toNanos();
|
||||
} catch (ArithmeticException tooBig) {
|
||||
return duration.isNegative() ? Long.MIN_VALUE : Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ import static org.mockito.Mockito.mock;
|
|||
import com.google.common.base.Objects;
|
||||
import io.grpc.ClientStreamTracer.StreamInfo;
|
||||
import io.grpc.internal.SerializingExecutor;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Executor;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -150,6 +151,15 @@ public class CallOptionsTest {
|
|||
assertAbout(deadline()).that(actual).isWithin(10, MILLISECONDS).of(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
@IgnoreJRERequirement
|
||||
public void withDeadlineAfterDuration() {
|
||||
Deadline actual = CallOptions.DEFAULT.withDeadlineAfter(Duration.ofMinutes(1L)).getDeadline();
|
||||
Deadline expected = Deadline.after(1, MINUTES);
|
||||
|
||||
assertAbout(deadline()).that(actual).isWithin(10, MILLISECONDS).of(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringMatches_noDeadline_default() {
|
||||
String actual = allSet
|
||||
|
|
|
@ -85,14 +85,12 @@ public class ConfiguratorRegistryTest {
|
|||
@Override
|
||||
public void run() {
|
||||
assertThat(ConfiguratorRegistry.getDefaultRegistry().getConfigurators()).isEmpty();
|
||||
|
||||
try {
|
||||
ConfiguratorRegistry.getDefaultRegistry()
|
||||
.setConfigurators(Arrays.asList(new NoopConfigurator()));
|
||||
fail("should have failed for invoking set call after get is already called");
|
||||
} catch (IllegalStateException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("Configurators are already set");
|
||||
}
|
||||
NoopConfigurator noopConfigurator = new NoopConfigurator();
|
||||
ConfiguratorRegistry.getDefaultRegistry()
|
||||
.setConfigurators(Arrays.asList(noopConfigurator));
|
||||
assertThat(ConfiguratorRegistry.getDefaultRegistry().getConfigurators())
|
||||
.containsExactly(noopConfigurator);
|
||||
assertThat(InternalConfiguratorRegistry.getConfiguratorsCallCountBeforeSet()).isEqualTo(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
|
@ -24,6 +25,7 @@ import static org.junit.Assert.assertFalse;
|
|||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
|
@ -37,9 +39,7 @@ import java.io.InputStream;
|
|||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.Locale;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
|
@ -49,9 +49,6 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public class MetadataTest {
|
||||
|
||||
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
||||
@Rule public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private static final Metadata.BinaryMarshaller<Fish> FISH_MARSHALLER =
|
||||
new Metadata.BinaryMarshaller<Fish>() {
|
||||
@Override
|
||||
|
@ -65,7 +62,7 @@ public class MetadataTest {
|
|||
}
|
||||
};
|
||||
|
||||
private static class FishStreamMarsaller implements Metadata.BinaryStreamMarshaller<Fish> {
|
||||
private static class FishStreamMarshaller implements Metadata.BinaryStreamMarshaller<Fish> {
|
||||
@Override
|
||||
public InputStream toStream(Fish fish) {
|
||||
return new ByteArrayInputStream(FISH_MARSHALLER.toBytes(fish));
|
||||
|
@ -82,7 +79,7 @@ public class MetadataTest {
|
|||
}
|
||||
|
||||
private static final Metadata.BinaryStreamMarshaller<Fish> FISH_STREAM_MARSHALLER =
|
||||
new FishStreamMarsaller();
|
||||
new FishStreamMarshaller();
|
||||
|
||||
/** A pattern commonly used to avoid unnecessary serialization of immutable objects. */
|
||||
private static final class FakeFishStream extends InputStream {
|
||||
|
@ -121,10 +118,9 @@ public class MetadataTest {
|
|||
|
||||
@Test
|
||||
public void noPseudoHeaders() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage("Invalid character");
|
||||
|
||||
Metadata.Key.of(":test-bin", FISH_MARSHALLER);
|
||||
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
|
||||
() -> Metadata.Key.of(":test-bin", FISH_MARSHALLER));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Invalid character ':' in key name ':test-bin'");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -186,8 +182,7 @@ public class MetadataTest {
|
|||
Iterator<Fish> i = metadata.getAll(KEY).iterator();
|
||||
assertEquals(lance, i.next());
|
||||
|
||||
thrown.expect(UnsupportedOperationException.class);
|
||||
i.remove();
|
||||
assertThrows(UnsupportedOperationException.class, i::remove);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -271,17 +266,15 @@ public class MetadataTest {
|
|||
|
||||
@Test
|
||||
public void shortBinaryKeyName() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
|
||||
Metadata.Key.of("-bin", FISH_MARSHALLER);
|
||||
assertThrows(IllegalArgumentException.class, () -> Metadata.Key.of("-bin", FISH_MARSHALLER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invalidSuffixBinaryKeyName() {
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage("Binary header is named");
|
||||
|
||||
Metadata.Key.of("nonbinary", FISH_MARSHALLER);
|
||||
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
|
||||
() -> Metadata.Key.of("nonbinary", FISH_MARSHALLER));
|
||||
assertThat(e).hasMessageThat()
|
||||
.isEqualTo("Binary header is named nonbinary. It must end with -bin");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -415,7 +408,7 @@ public class MetadataTest {
|
|||
h.put(KEY_STREAMED, salmon);
|
||||
|
||||
// Get using a different marshaller instance.
|
||||
Fish fish = h.get(copyKey(KEY_STREAMED, new FishStreamMarsaller()));
|
||||
Fish fish = h.get(copyKey(KEY_STREAMED, new FishStreamMarshaller()));
|
||||
assertEquals(salmon, fish);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@ import static org.junit.Assert.assertTrue;
|
|||
import io.grpc.MethodDescriptor.Marshaller;
|
||||
import io.grpc.MethodDescriptor.MethodType;
|
||||
import io.grpc.testing.TestMethodDescriptors;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
|
@ -37,10 +35,6 @@ import org.junit.runners.JUnit4;
|
|||
*/
|
||||
@RunWith(JUnit4.class)
|
||||
public class MethodDescriptorTest {
|
||||
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void createMethodDescriptor() {
|
||||
MethodDescriptor<String, String> descriptor = MethodDescriptor.<String, String>newBuilder()
|
||||
|
|
|
@ -47,9 +47,13 @@ public class NameResolverTest {
|
|||
private static final List<EquivalentAddressGroup> ADDRESSES =
|
||||
Collections.singletonList(
|
||||
new EquivalentAddressGroup(new FakeSocketAddress("fake-address-1"), Attributes.EMPTY));
|
||||
private static final Attributes.Key<String> YOLO_KEY = Attributes.Key.create("yolo");
|
||||
private static Attributes ATTRIBUTES = Attributes.newBuilder()
|
||||
.set(YOLO_KEY, "To be, or not to be?").build();
|
||||
private static final Attributes.Key<String> YOLO_ATTR_KEY = Attributes.Key.create("yolo");
|
||||
private static Attributes ATTRIBUTES =
|
||||
Attributes.newBuilder().set(YOLO_ATTR_KEY, "To be, or not to be?").build();
|
||||
private static final NameResolver.Args.Key<Integer> FOO_ARG_KEY =
|
||||
NameResolver.Args.Key.create("foo");
|
||||
private static final NameResolver.Args.Key<Integer> BAR_ARG_KEY =
|
||||
NameResolver.Args.Key.create("bar");
|
||||
private static ConfigOrError CONFIG = ConfigOrError.fromConfig("foo");
|
||||
|
||||
@Rule
|
||||
|
@ -64,6 +68,8 @@ public class NameResolverTest {
|
|||
private final ChannelLogger channelLogger = mock(ChannelLogger.class);
|
||||
private final Executor executor = Executors.newSingleThreadExecutor();
|
||||
private final String overrideAuthority = "grpc.io";
|
||||
private final MetricRecorder metricRecorder = new MetricRecorder() {};
|
||||
private final int customArgValue = 42;
|
||||
@Mock NameResolver.Listener mockListener;
|
||||
|
||||
@Test
|
||||
|
@ -77,6 +83,9 @@ public class NameResolverTest {
|
|||
assertThat(args.getChannelLogger()).isSameInstanceAs(channelLogger);
|
||||
assertThat(args.getOffloadExecutor()).isSameInstanceAs(executor);
|
||||
assertThat(args.getOverrideAuthority()).isSameInstanceAs(overrideAuthority);
|
||||
assertThat(args.getMetricRecorder()).isSameInstanceAs(metricRecorder);
|
||||
assertThat(args.getArg(FOO_ARG_KEY)).isEqualTo(customArgValue);
|
||||
assertThat(args.getArg(BAR_ARG_KEY)).isNull();
|
||||
|
||||
NameResolver.Args args2 = args.toBuilder().build();
|
||||
assertThat(args2.getDefaultPort()).isEqualTo(defaultPort);
|
||||
|
@ -87,6 +96,9 @@ public class NameResolverTest {
|
|||
assertThat(args2.getChannelLogger()).isSameInstanceAs(channelLogger);
|
||||
assertThat(args2.getOffloadExecutor()).isSameInstanceAs(executor);
|
||||
assertThat(args2.getOverrideAuthority()).isSameInstanceAs(overrideAuthority);
|
||||
assertThat(args.getMetricRecorder()).isSameInstanceAs(metricRecorder);
|
||||
assertThat(args.getArg(FOO_ARG_KEY)).isEqualTo(customArgValue);
|
||||
assertThat(args.getArg(BAR_ARG_KEY)).isNull();
|
||||
|
||||
assertThat(args2).isNotSameInstanceAs(args);
|
||||
assertThat(args2).isNotEqualTo(args);
|
||||
|
@ -102,6 +114,8 @@ public class NameResolverTest {
|
|||
.setChannelLogger(channelLogger)
|
||||
.setOffloadExecutor(executor)
|
||||
.setOverrideAuthority(overrideAuthority)
|
||||
.setMetricRecorder(metricRecorder)
|
||||
.setArg(FOO_ARG_KEY, customArgValue)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package io.grpc;
|
|||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.AdditionalAnswers.delegatesTo;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
|
@ -40,7 +41,6 @@ import org.junit.After;
|
|||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
|
@ -55,10 +55,6 @@ public class ServerInterceptorsTest {
|
|||
@Rule
|
||||
public final MockitoRule mocks = MockitoJUnit.rule();
|
||||
|
||||
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Mock
|
||||
private Marshaller<String> requestMarshaller;
|
||||
|
||||
|
@ -111,21 +107,21 @@ public class ServerInterceptorsTest {
|
|||
public void npeForNullServiceDefinition() {
|
||||
ServerServiceDefinition serviceDef = null;
|
||||
List<ServerInterceptor> interceptors = Arrays.asList();
|
||||
thrown.expect(NullPointerException.class);
|
||||
ServerInterceptors.intercept(serviceDef, interceptors);
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> ServerInterceptors.intercept(serviceDef, interceptors));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void npeForNullInterceptorList() {
|
||||
thrown.expect(NullPointerException.class);
|
||||
ServerInterceptors.intercept(serviceDefinition, (List<ServerInterceptor>) null);
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> ServerInterceptors.intercept(serviceDefinition, (List<ServerInterceptor>) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void npeForNullInterceptor() {
|
||||
List<ServerInterceptor> interceptors = Arrays.asList((ServerInterceptor) null);
|
||||
thrown.expect(NullPointerException.class);
|
||||
ServerInterceptors.intercept(serviceDefinition, interceptors);
|
||||
assertThrows(NullPointerException.class,
|
||||
() -> ServerInterceptors.intercept(serviceDefinition, interceptors));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -18,14 +18,13 @@ package io.grpc;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
|
@ -52,9 +51,6 @@ public class ServerServiceDefinitionTest {
|
|||
= ServerMethodDefinition.create(method1, methodHandler1);
|
||||
private ServerMethodDefinition<String, Integer> methodDef2
|
||||
= ServerMethodDefinition.create(method2, methodHandler2);
|
||||
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void noMethods() {
|
||||
|
@ -91,9 +87,7 @@ public class ServerServiceDefinitionTest {
|
|||
ServiceDescriptor sd = new ServiceDescriptor(serviceName, method1);
|
||||
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd)
|
||||
.addMethod(method1, methodHandler1);
|
||||
thrown.expect(IllegalStateException.class);
|
||||
ssd.addMethod(diffMethod1, methodHandler2)
|
||||
.build();
|
||||
assertThrows(IllegalStateException.class, () -> ssd.addMethod(diffMethod1, methodHandler2));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -101,8 +95,7 @@ public class ServerServiceDefinitionTest {
|
|||
ServiceDescriptor sd = new ServiceDescriptor(serviceName);
|
||||
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd)
|
||||
.addMethod(methodDef1);
|
||||
thrown.expect(IllegalStateException.class);
|
||||
ssd.build();
|
||||
assertThrows(IllegalStateException.class, ssd::build);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -110,16 +103,14 @@ public class ServerServiceDefinitionTest {
|
|||
ServiceDescriptor sd = new ServiceDescriptor(serviceName, method1);
|
||||
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd)
|
||||
.addMethod(diffMethod1, methodHandler1);
|
||||
thrown.expect(IllegalStateException.class);
|
||||
ssd.build();
|
||||
assertThrows(IllegalStateException.class, ssd::build);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildMisaligned_missingMethod() {
|
||||
ServiceDescriptor sd = new ServiceDescriptor(serviceName, method1);
|
||||
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd);
|
||||
thrown.expect(IllegalStateException.class);
|
||||
ssd.build();
|
||||
assertThrows(IllegalStateException.class, ssd::build);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -16,17 +16,18 @@
|
|||
|
||||
package io.grpc;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import com.google.common.truth.StringSubject;
|
||||
import io.grpc.MethodDescriptor.MethodType;
|
||||
import io.grpc.testing.TestMethodDescriptors;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
|
@ -36,32 +37,27 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public class ServiceDescriptorTest {
|
||||
|
||||
@SuppressWarnings("deprecation") // https://github.com/grpc/grpc-java/issues/7467
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
public void failsOnNullName() {
|
||||
thrown.expect(NullPointerException.class);
|
||||
thrown.expectMessage("name");
|
||||
|
||||
new ServiceDescriptor(null, Collections.<MethodDescriptor<?, ?>>emptyList());
|
||||
List<MethodDescriptor<?, ?>> methods = Collections.emptyList();
|
||||
NullPointerException e = assertThrows(NullPointerException.class,
|
||||
() -> new ServiceDescriptor(null, methods));
|
||||
assertThat(e).hasMessageThat().isEqualTo("name");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failsOnNullMethods() {
|
||||
thrown.expect(NullPointerException.class);
|
||||
thrown.expectMessage("methods");
|
||||
|
||||
new ServiceDescriptor("name", (Collection<MethodDescriptor<?, ?>>) null);
|
||||
NullPointerException e = assertThrows(NullPointerException.class,
|
||||
() -> new ServiceDescriptor("name", (Collection<MethodDescriptor<?, ?>>) null));
|
||||
assertThat(e).hasMessageThat().isEqualTo("methods");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failsOnNullMethod() {
|
||||
thrown.expect(NullPointerException.class);
|
||||
thrown.expectMessage("method");
|
||||
|
||||
new ServiceDescriptor("name", Collections.<MethodDescriptor<?, ?>>singletonList(null));
|
||||
List<MethodDescriptor<?, ?>> methods = Collections.singletonList(null);
|
||||
NullPointerException e = assertThrows(NullPointerException.class,
|
||||
() -> new ServiceDescriptor("name", methods));
|
||||
assertThat(e).hasMessageThat().isEqualTo("method");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -69,15 +65,17 @@ public class ServiceDescriptorTest {
|
|||
List<MethodDescriptor<?, ?>> descriptors = Collections.<MethodDescriptor<?, ?>>singletonList(
|
||||
MethodDescriptor.<Void, Void>newBuilder()
|
||||
.setType(MethodType.UNARY)
|
||||
.setFullMethodName(MethodDescriptor.generateFullMethodName("wrongservice", "method"))
|
||||
.setFullMethodName(MethodDescriptor.generateFullMethodName("wrongService", "method"))
|
||||
.setRequestMarshaller(TestMethodDescriptors.voidMarshaller())
|
||||
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
|
||||
.build());
|
||||
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage("service names");
|
||||
|
||||
new ServiceDescriptor("name", descriptors);
|
||||
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
|
||||
() -> new ServiceDescriptor("fooService", descriptors));
|
||||
StringSubject error = assertThat(e).hasMessageThat();
|
||||
error.contains("service names");
|
||||
error.contains("fooService");
|
||||
error.contains("wrongService");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -96,10 +94,9 @@ public class ServiceDescriptorTest {
|
|||
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
|
||||
.build());
|
||||
|
||||
thrown.expect(IllegalArgumentException.class);
|
||||
thrown.expectMessage("duplicate");
|
||||
|
||||
new ServiceDescriptor("name", descriptors);
|
||||
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
|
||||
() -> new ServiceDescriptor("name", descriptors));
|
||||
assertThat(e).hasMessageThat().isEqualTo("duplicate name name/method");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -28,14 +28,6 @@ import org.junit.runners.JUnit4;
|
|||
@RunWith(JUnit4.class)
|
||||
public class StatusExceptionTest {
|
||||
|
||||
@Test
|
||||
public void internalCtorRemovesStack() {
|
||||
StackTraceElement[] trace =
|
||||
new StatusException(Status.CANCELLED, null, false) {}.getStackTrace();
|
||||
|
||||
assertThat(trace).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void normalCtorKeepsStack() {
|
||||
StackTraceElement[] trace =
|
||||
|
|
|
@ -31,7 +31,7 @@ public class StatusRuntimeExceptionTest {
|
|||
@Test
|
||||
public void internalCtorRemovesStack() {
|
||||
StackTraceElement[] trace =
|
||||
new StatusRuntimeException(Status.CANCELLED, null, false) {}.getStackTrace();
|
||||
new InternalStatusRuntimeException(Status.CANCELLED, null) {}.getStackTrace();
|
||||
|
||||
assertThat(trace).isEmpty();
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify;
|
|||
|
||||
import com.google.common.util.concurrent.testing.TestingExecutors;
|
||||
import io.grpc.SynchronizationContext.ScheduledHandle;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
@ -72,7 +73,7 @@ public class SynchronizationContextTest {
|
|||
|
||||
@Mock
|
||||
private Runnable task3;
|
||||
|
||||
|
||||
@After public void tearDown() {
|
||||
assertThat(uncaughtErrors).isEmpty();
|
||||
}
|
||||
|
@ -246,6 +247,43 @@ public class SynchronizationContextTest {
|
|||
verify(task1).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IgnoreJRERequirement
|
||||
public void scheduleDuration() {
|
||||
MockScheduledExecutorService executorService = new MockScheduledExecutorService();
|
||||
ScheduledHandle handle =
|
||||
syncContext.schedule(task1, Duration.ofSeconds(10), executorService);
|
||||
|
||||
assertThat(executorService.delay)
|
||||
.isEqualTo(executorService.unit.convert(10, TimeUnit.SECONDS));
|
||||
assertThat(handle.isPending()).isTrue();
|
||||
verify(task1, never()).run();
|
||||
|
||||
executorService.command.run();
|
||||
|
||||
assertThat(handle.isPending()).isFalse();
|
||||
verify(task1).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
@IgnoreJRERequirement
|
||||
public void scheduleWithFixedDelayDuration() {
|
||||
MockScheduledExecutorService executorService = new MockScheduledExecutorService();
|
||||
ScheduledHandle handle =
|
||||
syncContext.scheduleWithFixedDelay(task1, Duration.ofSeconds(10),
|
||||
Duration.ofSeconds(10), executorService);
|
||||
|
||||
assertThat(executorService.delay)
|
||||
.isEqualTo(executorService.unit.convert(10, TimeUnit.SECONDS));
|
||||
assertThat(handle.isPending()).isTrue();
|
||||
verify(task1, never()).run();
|
||||
|
||||
executorService.command.run();
|
||||
|
||||
assertThat(handle.isPending()).isFalse();
|
||||
verify(task1).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scheduleDueImmediately() {
|
||||
MockScheduledExecutorService executorService = new MockScheduledExecutorService();
|
||||
|
@ -357,5 +395,13 @@ public class SynchronizationContextTest {
|
|||
this.unit = unit;
|
||||
return future = super.schedule(command, delay, unit);
|
||||
}
|
||||
|
||||
@Override public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long intialDelay,
|
||||
long delay, TimeUnit unit) {
|
||||
this.command = command;
|
||||
this.delay = delay;
|
||||
this.unit = unit;
|
||||
return future = super.scheduleWithFixedDelay(command, intialDelay, delay, unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.time.Duration;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for {@link TimeUtils}. */
|
||||
@RunWith(JUnit4.class)
|
||||
@IgnoreJRERequirement
|
||||
public class TimeUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testConvertNormalDuration() {
|
||||
Duration duration = Duration.ofSeconds(10);
|
||||
long expected = 10 * 1_000_000_000L;
|
||||
|
||||
assertEquals(expected, TimeUtils.convertToNanos(duration));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertNegativeDuration() {
|
||||
Duration duration = Duration.ofSeconds(-3);
|
||||
long expected = -3 * 1_000_000_000L;
|
||||
|
||||
assertEquals(expected, TimeUtils.convertToNanos(duration));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertTooLargeDuration() {
|
||||
Duration duration = Duration.ofSeconds(Long.MAX_VALUE / 1_000_000_000L + 1);
|
||||
|
||||
assertEquals(Long.MAX_VALUE, TimeUtils.convertToNanos(duration));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConvertTooLargeNegativeDuration() {
|
||||
Duration duration = Duration.ofSeconds(Long.MIN_VALUE / 1_000_000_000L - 1);
|
||||
|
||||
assertEquals(Long.MIN_VALUE, TimeUtils.convertToNanos(duration));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright 2025 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 static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import org.mockito.ArgumentMatcher;
|
||||
|
||||
/**
|
||||
* Mockito matcher for {@link Status}.
|
||||
*/
|
||||
public final class StatusMatcher implements ArgumentMatcher<Status> {
|
||||
public static StatusMatcher statusHasCode(ArgumentMatcher<Status.Code> codeMatcher) {
|
||||
return new StatusMatcher(codeMatcher, null);
|
||||
}
|
||||
|
||||
public static StatusMatcher statusHasCode(Status.Code code) {
|
||||
return statusHasCode(new EqualsMatcher<>(code));
|
||||
}
|
||||
|
||||
private final ArgumentMatcher<Status.Code> codeMatcher;
|
||||
private final ArgumentMatcher<String> descriptionMatcher;
|
||||
|
||||
private StatusMatcher(
|
||||
ArgumentMatcher<Status.Code> codeMatcher,
|
||||
ArgumentMatcher<String> descriptionMatcher) {
|
||||
this.codeMatcher = checkNotNull(codeMatcher, "codeMatcher");
|
||||
this.descriptionMatcher = descriptionMatcher;
|
||||
}
|
||||
|
||||
public StatusMatcher andDescription(ArgumentMatcher<String> descriptionMatcher) {
|
||||
checkState(this.descriptionMatcher == null, "Already has a description matcher");
|
||||
return new StatusMatcher(codeMatcher, descriptionMatcher);
|
||||
}
|
||||
|
||||
public StatusMatcher andDescription(String description) {
|
||||
return andDescription(new EqualsMatcher<>(description));
|
||||
}
|
||||
|
||||
public StatusMatcher andDescriptionContains(String substring) {
|
||||
return andDescription(new StringContainsMatcher(substring));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Status status) {
|
||||
return status != null
|
||||
&& codeMatcher.matches(status.getCode())
|
||||
&& (descriptionMatcher == null || descriptionMatcher.matches(status.getDescription()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("{code=");
|
||||
sb.append(codeMatcher);
|
||||
if (descriptionMatcher != null) {
|
||||
sb.append(", description=");
|
||||
sb.append(descriptionMatcher);
|
||||
}
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// Use instead of lambda for better error message.
|
||||
static final class EqualsMatcher<T> implements ArgumentMatcher<T> {
|
||||
private final T obj;
|
||||
|
||||
EqualsMatcher(T obj) {
|
||||
this.obj = checkNotNull(obj, "obj");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object other) {
|
||||
return obj.equals(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return obj.toString();
|
||||
}
|
||||
}
|
||||
|
||||
static final class StringContainsMatcher implements ArgumentMatcher<String> {
|
||||
private final String needle;
|
||||
|
||||
StringContainsMatcher(String needle) {
|
||||
this.needle = checkNotNull(needle, "needle");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String haystack) {
|
||||
if (haystack == null) {
|
||||
return false;
|
||||
}
|
||||
return haystack.contains(needle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "contains " + needle;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2025 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 org.mockito.ArgumentMatcher;
|
||||
|
||||
/**
|
||||
* Mockito matcher for {@link StatusOr}.
|
||||
*/
|
||||
public final class StatusOrMatcher<T> implements ArgumentMatcher<StatusOr<T>> {
|
||||
public static <T> StatusOrMatcher<T> hasValue(ArgumentMatcher<T> valueMatcher) {
|
||||
return new StatusOrMatcher<T>(checkNotNull(valueMatcher, "valueMatcher"), null);
|
||||
}
|
||||
|
||||
public static <T> StatusOrMatcher<T> hasStatus(ArgumentMatcher<Status> statusMatcher) {
|
||||
return new StatusOrMatcher<T>(null, checkNotNull(statusMatcher, "statusMatcher"));
|
||||
}
|
||||
|
||||
private final ArgumentMatcher<T> valueMatcher;
|
||||
private final ArgumentMatcher<Status> statusMatcher;
|
||||
|
||||
private StatusOrMatcher(ArgumentMatcher<T> valueMatcher, ArgumentMatcher<Status> statusMatcher) {
|
||||
this.valueMatcher = valueMatcher;
|
||||
this.statusMatcher = statusMatcher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(StatusOr<T> statusOr) {
|
||||
if (statusOr == null) {
|
||||
return false;
|
||||
}
|
||||
if (statusOr.hasValue() != (valueMatcher != null)) {
|
||||
return false;
|
||||
}
|
||||
if (valueMatcher != null) {
|
||||
return valueMatcher.matches(statusOr.getValue());
|
||||
} else {
|
||||
return statusMatcher.matches(statusOr.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (valueMatcher != null) {
|
||||
return "{value=" + valueMatcher + "}";
|
||||
} else {
|
||||
return "{status=" + statusMatcher + "}";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,9 +24,9 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||
import com.google.common.truth.ComparableSubject;
|
||||
import com.google.common.truth.FailureMetadata;
|
||||
import com.google.common.truth.Subject;
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import io.grpc.Deadline;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/** Propositions for {@link Deadline} subjects. */
|
||||
|
@ -67,7 +67,7 @@ public final class DeadlineSubject extends ComparableSubject {
|
|||
if (Math.abs(actualNanos - expectedNanos) > deltaNanos) {
|
||||
failWithoutActual(
|
||||
fact("expected", expectedNanos / NANOSECONDS_IN_A_SECOND),
|
||||
fact("but was", expectedNanos / NANOSECONDS_IN_A_SECOND),
|
||||
fact("but was", actualNanos / NANOSECONDS_IN_A_SECOND),
|
||||
fact("outside tolerance in seconds", deltaNanos / NANOSECONDS_IN_A_SECOND));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,14 @@ dependencies {
|
|||
project(':grpc-core'),
|
||||
project(":grpc-context"), // Override google-auth dependency with our newer version
|
||||
libraries.google.auth.oauth2Http
|
||||
signature libraries.signature.java
|
||||
signature libraries.signature.android
|
||||
signature (libraries.signature.java) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
signature (libraries.signature.android) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,10 +50,12 @@ import io.grpc.SecurityLevel;
|
|||
import io.grpc.Status;
|
||||
import io.grpc.internal.JsonParser;
|
||||
import io.grpc.testing.TestMethodDescriptors;
|
||||
import io.grpc.testing.TlsTesting;
|
||||
import io.grpc.util.CertificateUtils;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PrivateKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
@ -342,7 +344,10 @@ public class GoogleAuthLibraryCallCredentialsTest {
|
|||
|
||||
@Test
|
||||
public void serviceAccountToJwt() throws Exception {
|
||||
KeyPair pair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
|
||||
PrivateKey privateKey;
|
||||
try (InputStream server1Key = TlsTesting.loadCert("server1.key")) {
|
||||
privateKey = CertificateUtils.getPrivateKey(server1Key);
|
||||
}
|
||||
|
||||
HttpTransportFactory factory = Mockito.mock(HttpTransportFactory.class);
|
||||
Mockito.when(factory.create()).thenThrow(new AssertionError());
|
||||
|
@ -350,7 +355,7 @@ public class GoogleAuthLibraryCallCredentialsTest {
|
|||
ServiceAccountCredentials credentials =
|
||||
ServiceAccountCredentials.newBuilder()
|
||||
.setClientEmail("test-email@example.com")
|
||||
.setPrivateKey(pair.getPrivate())
|
||||
.setPrivateKey(privateKey)
|
||||
.setPrivateKeyId("test-private-key-id")
|
||||
.setHttpTransportFactory(factory)
|
||||
.build();
|
||||
|
@ -390,13 +395,16 @@ public class GoogleAuthLibraryCallCredentialsTest {
|
|||
|
||||
@Test
|
||||
public void jwtAccessCredentialsInRequestMetadata() throws Exception {
|
||||
KeyPair pair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
|
||||
PrivateKey privateKey;
|
||||
try (InputStream server1Key = TlsTesting.loadCert("server1.key")) {
|
||||
privateKey = CertificateUtils.getPrivateKey(server1Key);
|
||||
}
|
||||
|
||||
ServiceAccountCredentials credentials =
|
||||
ServiceAccountCredentials.newBuilder()
|
||||
.setClientId("test-client")
|
||||
.setClientEmail("test-email@example.com")
|
||||
.setPrivateKey(pair.getPrivate())
|
||||
.setPrivateKey(privateKey)
|
||||
.setPrivateKeyId("test-private-key-id")
|
||||
.setQuotaProjectId("test-quota-project-id")
|
||||
.build();
|
||||
|
|
|
@ -2,8 +2,8 @@ plugins {
|
|||
id "java-library"
|
||||
id "maven-publish"
|
||||
|
||||
id "com.github.johnrengelman.shadow"
|
||||
id "com.google.protobuf"
|
||||
id "com.gradleup.shadow"
|
||||
id "ru.vyarus.animalsniffer"
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,11 @@ dependencies {
|
|||
shadow configurations.implementation.getDependencies().minus([xdsDependency])
|
||||
shadow project(path: ':grpc-xds', configuration: 'shadow')
|
||||
|
||||
signature libraries.signature.java
|
||||
signature (libraries.signature.java) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.named("jar").configure {
|
||||
|
|
|
@ -43,7 +43,11 @@ dependencies {
|
|||
testImplementation libraries.junit,
|
||||
libraries.mockito.core
|
||||
|
||||
signature libraries.signature.java
|
||||
signature (libraries.signature.java) {
|
||||
artifact {
|
||||
extension = "signature"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
import net.ltgt.gradle.errorprone.CheckSeverity
|
||||
|
|
|
@ -4,9 +4,6 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
|
||||
/**
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler",
|
||||
comments = "Source: grpc/testing/services.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class BenchmarkServiceGrpc {
|
||||
|
||||
|
@ -184,6 +181,21 @@ public final class BenchmarkServiceGrpc {
|
|||
return BenchmarkServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static BenchmarkServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<BenchmarkServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<BenchmarkServiceBlockingV2Stub>() {
|
||||
@java.lang.Override
|
||||
public BenchmarkServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
return new BenchmarkServiceBlockingV2Stub(channel, callOptions);
|
||||
}
|
||||
};
|
||||
return BenchmarkServiceBlockingV2Stub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
|
||||
*/
|
||||
|
@ -367,6 +379,87 @@ public final class BenchmarkServiceGrpc {
|
|||
/**
|
||||
* A stub to allow clients to do synchronous rpc calls to service BenchmarkService.
|
||||
*/
|
||||
public static final class BenchmarkServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<BenchmarkServiceBlockingV2Stub> {
|
||||
private BenchmarkServiceBlockingV2Stub(
|
||||
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
super(channel, callOptions);
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
protected BenchmarkServiceBlockingV2Stub build(
|
||||
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
return new BenchmarkServiceBlockingV2Stub(channel, callOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* One request followed by one response.
|
||||
* The server returns the client payload as-is.
|
||||
* </pre>
|
||||
*/
|
||||
public io.grpc.benchmarks.proto.Messages.SimpleResponse unaryCall(io.grpc.benchmarks.proto.Messages.SimpleRequest request) throws io.grpc.StatusException {
|
||||
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
|
||||
getChannel(), getUnaryCallMethod(), getCallOptions(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Repeated sequence of one request followed by one response.
|
||||
* Should be called streaming ping-pong
|
||||
* The server returns the client payload as-is on each response
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.benchmarks.proto.Messages.SimpleRequest, io.grpc.benchmarks.proto.Messages.SimpleResponse>
|
||||
streamingCall() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getStreamingCallMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Single-sided unbounded streaming from client to server
|
||||
* The server returns the client payload as-is once the client does WritesDone
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.benchmarks.proto.Messages.SimpleRequest, io.grpc.benchmarks.proto.Messages.SimpleResponse>
|
||||
streamingFromClient() {
|
||||
return io.grpc.stub.ClientCalls.blockingClientStreamingCall(
|
||||
getChannel(), getStreamingFromClientMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Single-sided unbounded streaming from server to client
|
||||
* The server repeatedly returns the client payload as-is
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<?, io.grpc.benchmarks.proto.Messages.SimpleResponse>
|
||||
streamingFromServer(io.grpc.benchmarks.proto.Messages.SimpleRequest request) {
|
||||
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
|
||||
getChannel(), getStreamingFromServerMethod(), getCallOptions(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Two-sided unbounded streaming between server to client
|
||||
* Both sides send the content of their own choice to the other
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.benchmarks.proto.Messages.SimpleRequest, io.grpc.benchmarks.proto.Messages.SimpleResponse>
|
||||
streamingBothWays() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getStreamingBothWaysMethod(), getCallOptions());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A stub to allow clients to do limited synchronous rpc calls to service BenchmarkService.
|
||||
*/
|
||||
public static final class BenchmarkServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<BenchmarkServiceBlockingStub> {
|
||||
private BenchmarkServiceBlockingStub(
|
||||
|
|
|
@ -4,9 +4,6 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
|
||||
/**
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler",
|
||||
comments = "Source: grpc/testing/services.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class ReportQpsScenarioServiceGrpc {
|
||||
|
||||
|
@ -60,6 +57,21 @@ public final class ReportQpsScenarioServiceGrpc {
|
|||
return ReportQpsScenarioServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static ReportQpsScenarioServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<ReportQpsScenarioServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<ReportQpsScenarioServiceBlockingV2Stub>() {
|
||||
@java.lang.Override
|
||||
public ReportQpsScenarioServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
return new ReportQpsScenarioServiceBlockingV2Stub(channel, callOptions);
|
||||
}
|
||||
};
|
||||
return ReportQpsScenarioServiceBlockingV2Stub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
|
||||
*/
|
||||
|
@ -147,6 +159,33 @@ public final class ReportQpsScenarioServiceGrpc {
|
|||
/**
|
||||
* A stub to allow clients to do synchronous rpc calls to service ReportQpsScenarioService.
|
||||
*/
|
||||
public static final class ReportQpsScenarioServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<ReportQpsScenarioServiceBlockingV2Stub> {
|
||||
private ReportQpsScenarioServiceBlockingV2Stub(
|
||||
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
super(channel, callOptions);
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
protected ReportQpsScenarioServiceBlockingV2Stub build(
|
||||
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
return new ReportQpsScenarioServiceBlockingV2Stub(channel, callOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Report results of a QPS test benchmark scenario.
|
||||
* </pre>
|
||||
*/
|
||||
public io.grpc.benchmarks.proto.Control.Void reportScenario(io.grpc.benchmarks.proto.Control.ScenarioResult request) throws io.grpc.StatusException {
|
||||
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
|
||||
getChannel(), getReportScenarioMethod(), getCallOptions(), request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A stub to allow clients to do limited synchronous rpc calls to service ReportQpsScenarioService.
|
||||
*/
|
||||
public static final class ReportQpsScenarioServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<ReportQpsScenarioServiceBlockingStub> {
|
||||
private ReportQpsScenarioServiceBlockingStub(
|
||||
|
|
|
@ -4,9 +4,6 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
|
|||
|
||||
/**
|
||||
*/
|
||||
@javax.annotation.Generated(
|
||||
value = "by gRPC proto compiler",
|
||||
comments = "Source: grpc/testing/services.proto")
|
||||
@io.grpc.stub.annotations.GrpcGenerated
|
||||
public final class WorkerServiceGrpc {
|
||||
|
||||
|
@ -153,6 +150,21 @@ public final class WorkerServiceGrpc {
|
|||
return WorkerServiceStub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports all types of calls on the service
|
||||
*/
|
||||
public static WorkerServiceBlockingV2Stub newBlockingV2Stub(
|
||||
io.grpc.Channel channel) {
|
||||
io.grpc.stub.AbstractStub.StubFactory<WorkerServiceBlockingV2Stub> factory =
|
||||
new io.grpc.stub.AbstractStub.StubFactory<WorkerServiceBlockingV2Stub>() {
|
||||
@java.lang.Override
|
||||
public WorkerServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
return new WorkerServiceBlockingV2Stub(channel, callOptions);
|
||||
}
|
||||
};
|
||||
return WorkerServiceBlockingV2Stub.newStub(factory, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
|
||||
*/
|
||||
|
@ -323,6 +335,77 @@ public final class WorkerServiceGrpc {
|
|||
/**
|
||||
* A stub to allow clients to do synchronous rpc calls to service WorkerService.
|
||||
*/
|
||||
public static final class WorkerServiceBlockingV2Stub
|
||||
extends io.grpc.stub.AbstractBlockingStub<WorkerServiceBlockingV2Stub> {
|
||||
private WorkerServiceBlockingV2Stub(
|
||||
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
super(channel, callOptions);
|
||||
}
|
||||
|
||||
@java.lang.Override
|
||||
protected WorkerServiceBlockingV2Stub build(
|
||||
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
|
||||
return new WorkerServiceBlockingV2Stub(channel, callOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Start server with specified workload.
|
||||
* First request sent specifies the ServerConfig followed by ServerStatus
|
||||
* response. After that, a "Mark" can be sent anytime to request the latest
|
||||
* stats. Closing the stream will initiate shutdown of the test server
|
||||
* and once the shutdown has finished, the OK status is sent to terminate
|
||||
* this RPC.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.benchmarks.proto.Control.ServerArgs, io.grpc.benchmarks.proto.Control.ServerStatus>
|
||||
runServer() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getRunServerMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Start client with specified workload.
|
||||
* First request sent specifies the ClientConfig followed by ClientStatus
|
||||
* response. After that, a "Mark" can be sent anytime to request the latest
|
||||
* stats. Closing the stream will initiate shutdown of the test client
|
||||
* and once the shutdown has finished, the OK status is sent to terminate
|
||||
* this RPC.
|
||||
* </pre>
|
||||
*/
|
||||
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
|
||||
public io.grpc.stub.BlockingClientCall<io.grpc.benchmarks.proto.Control.ClientArgs, io.grpc.benchmarks.proto.Control.ClientStatus>
|
||||
runClient() {
|
||||
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
|
||||
getChannel(), getRunClientMethod(), getCallOptions());
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Just return the core count - unary call
|
||||
* </pre>
|
||||
*/
|
||||
public io.grpc.benchmarks.proto.Control.CoreResponse coreCount(io.grpc.benchmarks.proto.Control.CoreRequest request) throws io.grpc.StatusException {
|
||||
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
|
||||
getChannel(), getCoreCountMethod(), getCallOptions(), request);
|
||||
}
|
||||
|
||||
/**
|
||||
* <pre>
|
||||
* Quit this worker
|
||||
* </pre>
|
||||
*/
|
||||
public io.grpc.benchmarks.proto.Control.Void quitWorker(io.grpc.benchmarks.proto.Control.Void request) throws io.grpc.StatusException {
|
||||
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
|
||||
getChannel(), getQuitWorkerMethod(), getCallOptions(), request);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A stub to allow clients to do limited synchronous rpc calls to service WorkerService.
|
||||
*/
|
||||
public static final class WorkerServiceBlockingStub
|
||||
extends io.grpc.stub.AbstractBlockingStub<WorkerServiceBlockingStub> {
|
||||
private WorkerServiceBlockingStub(
|
||||
|
|
|
@ -6,33 +6,32 @@ plugins {
|
|||
description = 'gRPC BinderChannel'
|
||||
|
||||
android {
|
||||
namespace 'io.grpc.binder'
|
||||
namespace = 'io.grpc.binder'
|
||||
compileSdkVersion 34
|
||||
compileOptions {
|
||||
sourceCompatibility 1.8
|
||||
targetCompatibility 1.8
|
||||
}
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
minSdkVersion 22
|
||||
targetSdkVersion 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
multiDexEnabled = true
|
||||
}
|
||||
lintOptions { abortOnError false }
|
||||
lintOptions { abortOnError = false }
|
||||
publishing {
|
||||
singleVariant('release') {
|
||||
withSourcesJar()
|
||||
withJavadocJar()
|
||||
}
|
||||
}
|
||||
testFixtures { enable true }
|
||||
testFixtures { enable = true }
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -73,6 +72,7 @@ dependencies {
|
|||
androidTestImplementation testFixtures(project(':grpc-core'))
|
||||
|
||||
testFixturesImplementation libraries.guava.testlib
|
||||
testFixturesImplementation testFixtures(project(':grpc-core'))
|
||||
}
|
||||
|
||||
import net.ltgt.gradle.errorprone.CheckSeverity
|
||||
|
|
|
@ -11,11 +11,13 @@
|
|||
<service android:name="io.grpc.binder.HostServices$HostService1" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="action1"/>
|
||||
<data android:scheme="scheme" android:host="authority" android:path="/path"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service android:name="io.grpc.binder.HostServices$HostService2" android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="action2"/>
|
||||
<data android:scheme="scheme" android:host="authority" android:path="/path"/>
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
|
|
@ -23,6 +23,7 @@ import static java.util.concurrent.TimeUnit.SECONDS;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
@ -39,7 +40,6 @@ import io.grpc.ForwardingServerCall.SimpleForwardingServerCall;
|
|||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.MethodDescriptor;
|
||||
import io.grpc.NameResolverRegistry;
|
||||
import io.grpc.ServerCall;
|
||||
import io.grpc.ServerCall.Listener;
|
||||
import io.grpc.ServerCallHandler;
|
||||
|
@ -49,7 +49,6 @@ import io.grpc.ServerServiceDefinition;
|
|||
import io.grpc.Status.Code;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.grpc.internal.GrpcUtil;
|
||||
import io.grpc.internal.testing.FakeNameResolverProvider;
|
||||
import io.grpc.stub.ClientCalls;
|
||||
import io.grpc.stub.MetadataUtils;
|
||||
import io.grpc.stub.ServerCalls;
|
||||
|
@ -77,7 +76,6 @@ public final class BinderChannelSmokeTest {
|
|||
|
||||
private static final int SLIGHTLY_MORE_THAN_ONE_BLOCK = 16 * 1024 + 100;
|
||||
private static final String MSG = "Some text which will be repeated many many times";
|
||||
private static final String SERVER_TARGET_URI = "fake://server";
|
||||
private static final Metadata.Key<PoisonParcelable> POISON_KEY =
|
||||
ParcelableUtils.metadataKey("poison-bin", PoisonParcelable.CREATOR);
|
||||
|
||||
|
@ -99,7 +97,6 @@ public final class BinderChannelSmokeTest {
|
|||
.setType(MethodDescriptor.MethodType.BIDI_STREAMING)
|
||||
.build();
|
||||
|
||||
FakeNameResolverProvider fakeNameResolverProvider;
|
||||
ManagedChannel channel;
|
||||
AtomicReference<Metadata> headersCapture = new AtomicReference<>();
|
||||
AtomicReference<PeerUid> clientUidCapture = new AtomicReference<>();
|
||||
|
@ -138,8 +135,6 @@ public final class BinderChannelSmokeTest {
|
|||
PeerUids.newPeerIdentifyingServerInterceptor());
|
||||
|
||||
AndroidComponentAddress serverAddress = HostServices.allocateService(appContext);
|
||||
fakeNameResolverProvider = new FakeNameResolverProvider(SERVER_TARGET_URI, serverAddress);
|
||||
NameResolverRegistry.getDefaultRegistry().register(fakeNameResolverProvider);
|
||||
HostServices.configureService(
|
||||
serverAddress,
|
||||
HostServices.serviceParamsBuilder()
|
||||
|
@ -166,7 +161,6 @@ public final class BinderChannelSmokeTest {
|
|||
@After
|
||||
public void tearDown() throws Exception {
|
||||
channel.shutdownNow();
|
||||
NameResolverRegistry.getDefaultRegistry().deregister(fakeNameResolverProvider);
|
||||
HostServices.awaitServiceShutdown();
|
||||
}
|
||||
|
||||
|
@ -235,7 +229,11 @@ public final class BinderChannelSmokeTest {
|
|||
|
||||
@Test
|
||||
public void testConnectViaTargetUri() throws Exception {
|
||||
channel = BinderChannelBuilder.forTarget(SERVER_TARGET_URI, appContext).build();
|
||||
// Compare with the <intent-filter> mapping in AndroidManifest.xml.
|
||||
channel =
|
||||
BinderChannelBuilder.forTarget(
|
||||
"intent://authority/path#Intent;action=action1;scheme=scheme;end;", appContext)
|
||||
.build();
|
||||
assertThat(doCall("Hello").get()).isEqualTo("Hello");
|
||||
}
|
||||
|
||||
|
@ -245,7 +243,10 @@ public final class BinderChannelSmokeTest {
|
|||
channel =
|
||||
BinderChannelBuilder.forAddress(
|
||||
AndroidComponentAddress.forBindIntent(
|
||||
new Intent().setAction("action1").setPackage(appContext.getPackageName())),
|
||||
new Intent()
|
||||
.setAction("action1")
|
||||
.setData(Uri.parse("scheme://authority/path"))
|
||||
.setPackage(appContext.getPackageName())),
|
||||
appContext)
|
||||
.build();
|
||||
assertThat(doCall("Hello").get()).isEqualTo("Hello");
|
||||
|
|
|
@ -29,6 +29,7 @@ import android.os.RemoteException;
|
|||
import androidx.lifecycle.LifecycleService;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import io.grpc.Server;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
@ -38,7 +39,6 @@ import java.util.concurrent.Executor;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
|
||||
/**
|
||||
* A test helper class for creating android services to host gRPC servers.
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package io.grpc.binder.internal;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.DeadObjectException;
|
||||
|
@ -24,9 +25,9 @@ import android.os.Parcel;
|
|||
import android.os.RemoteException;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
import com.google.errorprone.annotations.CanIgnoreReturnValue;
|
||||
import com.google.errorprone.annotations.concurrent.GuardedBy;
|
||||
import com.google.protobuf.Empty;
|
||||
import io.grpc.CallOptions;
|
||||
import io.grpc.ClientStreamTracer;
|
||||
|
@ -37,13 +38,13 @@ import io.grpc.ServerServiceDefinition;
|
|||
import io.grpc.Status;
|
||||
import io.grpc.Status.Code;
|
||||
import io.grpc.binder.AndroidComponentAddress;
|
||||
import io.grpc.binder.AsyncSecurityPolicy;
|
||||
import io.grpc.binder.BinderServerBuilder;
|
||||
import io.grpc.binder.HostServices;
|
||||
import io.grpc.binder.SecurityPolicy;
|
||||
import io.grpc.binder.internal.OneWayBinderProxies.BlackHoleOneWayBinderProxy;
|
||||
import io.grpc.binder.internal.OneWayBinderProxies.BlockingBinderDecorator;
|
||||
import io.grpc.binder.internal.OneWayBinderProxies.ThrowingOneWayBinderProxy;
|
||||
import io.grpc.binder.internal.SettableAsyncSecurityPolicy.AuthRequest;
|
||||
import io.grpc.internal.ClientStream;
|
||||
import io.grpc.internal.ClientStreamListener;
|
||||
import io.grpc.internal.ClientTransportFactory.ClientTransportOptions;
|
||||
|
@ -62,9 +63,7 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -101,7 +100,7 @@ public final class BinderClientTransportTest {
|
|||
.build();
|
||||
|
||||
AndroidComponentAddress serverAddress;
|
||||
BinderTransport.BinderClientTransport transport;
|
||||
BinderClientTransport transport;
|
||||
BlockingSecurityPolicy blockingSecurityPolicy = new BlockingSecurityPolicy();
|
||||
|
||||
private final ObjectPool<ScheduledExecutorService> executorServicePool =
|
||||
|
@ -154,23 +153,32 @@ public final class BinderClientTransportTest {
|
|||
.setScheduledExecutorPool(executorServicePool)
|
||||
.setOffloadExecutorPool(offloadServicePool);
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public BinderClientTransportBuilder setSecurityPolicy(SecurityPolicy securityPolicy) {
|
||||
factoryBuilder.setSecurityPolicy(securityPolicy);
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public BinderClientTransportBuilder setBinderDecorator(
|
||||
OneWayBinderProxy.Decorator binderDecorator) {
|
||||
factoryBuilder.setBinderDecorator(binderDecorator);
|
||||
return this;
|
||||
}
|
||||
|
||||
@CanIgnoreReturnValue
|
||||
public BinderClientTransportBuilder setReadyTimeoutMillis(int timeoutMillis) {
|
||||
factoryBuilder.setReadyTimeoutMillis(timeoutMillis);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinderTransport.BinderClientTransport build() {
|
||||
@CanIgnoreReturnValue
|
||||
public BinderClientTransportBuilder setPreAuthorizeServer(boolean preAuthorizeServer) {
|
||||
factoryBuilder.setPreAuthorizeServers(preAuthorizeServer);
|
||||
return this;
|
||||
}
|
||||
|
||||
public BinderClientTransport build() {
|
||||
return factoryBuilder
|
||||
.buildClientTransportFactory()
|
||||
.newClientTransport(serverAddress, new ClientTransportOptions(), null);
|
||||
|
@ -189,7 +197,7 @@ public final class BinderClientTransportTest {
|
|||
private static void shutdownAndTerminate(ExecutorService executorService)
|
||||
throws InterruptedException {
|
||||
executorService.shutdownNow();
|
||||
if (!executorService.awaitTermination(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
|
||||
if (!executorService.awaitTermination(TIMEOUT_SECONDS, SECONDS)) {
|
||||
throw new AssertionError("executor failed to terminate promptly");
|
||||
}
|
||||
}
|
||||
|
@ -370,27 +378,58 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testBlackHoleSecurityPolicyConnectTimeout() throws Exception {
|
||||
public void testBlackHoleSecurityPolicyAuthTimeout() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setSecurityPolicy(blockingSecurityPolicy)
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.setPreAuthorizeServer(false)
|
||||
.setReadyTimeoutMillis(1_234)
|
||||
.build();
|
||||
transport.start(transportListener).run();
|
||||
// Take the next authRequest but don't respond to it, in order to trigger the ready timeout.
|
||||
AuthRequest authRequest = securityPolicy.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS);
|
||||
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.DEADLINE_EXCEEDED);
|
||||
assertThat(transportStatus.getDescription()).contains("1234");
|
||||
transportListener.awaitTermination();
|
||||
blockingSecurityPolicy.provideNextCheckAuthorizationResult(Status.OK);
|
||||
// If the transport gave up waiting on auth, it should cancel its request.
|
||||
assertThat(authRequest.isCancelled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncSecurityPolicyFailure() throws Exception {
|
||||
public void testBlackHoleSecurityPolicyPreAuthTimeout() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport = new BinderClientTransportBuilder().setSecurityPolicy(securityPolicy).build();
|
||||
RuntimeException exception = new NullPointerException();
|
||||
securityPolicy.setAuthorizationException(exception);
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.setPreAuthorizeServer(true)
|
||||
.setReadyTimeoutMillis(1_234)
|
||||
.build();
|
||||
transport.start(transportListener).run();
|
||||
// Take the next authRequest but don't respond to it, in order to trigger the ready timeout.
|
||||
AuthRequest preAuthRequest = securityPolicy.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS);
|
||||
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.DEADLINE_EXCEEDED);
|
||||
assertThat(transportStatus.getDescription()).contains("1234");
|
||||
transportListener.awaitTermination();
|
||||
// If the transport gave up waiting on auth, it should cancel its request.
|
||||
assertThat(preAuthRequest.isCancelled()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncSecurityPolicyAuthFailure() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setPreAuthorizeServer(false)
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.build();
|
||||
RuntimeException exception = new NullPointerException();
|
||||
transport.start(transportListener).run();
|
||||
securityPolicy.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS).setResult(exception);
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.INTERNAL);
|
||||
assertThat(transportStatus.getCause()).isEqualTo(exception);
|
||||
|
@ -398,19 +437,72 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncSecurityPolicySuccess() throws Exception {
|
||||
public void testAsyncSecurityPolicyPreAuthFailure() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport = new BinderClientTransportBuilder().setSecurityPolicy(securityPolicy).build();
|
||||
securityPolicy.setAuthorizationResult(Status.PERMISSION_DENIED);
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setPreAuthorizeServer(true)
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.build();
|
||||
RuntimeException exception = new NullPointerException();
|
||||
transport.start(transportListener).run();
|
||||
securityPolicy.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS).setResult(exception);
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.PERMISSION_DENIED);
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.INTERNAL);
|
||||
assertThat(transportStatus.getCause()).isEqualTo(exception);
|
||||
transportListener.awaitTermination();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncSecurityPolicyAuthSuccess() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setPreAuthorizeServer(false)
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.build();
|
||||
transport.start(transportListener).run();
|
||||
securityPolicy
|
||||
.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS)
|
||||
.setResult(Status.PERMISSION_DENIED.withDescription("xyzzy"));
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.PERMISSION_DENIED);
|
||||
assertThat(transportStatus.getDescription()).contains("xyzzy");
|
||||
transportListener.awaitTermination();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncSecurityPolicyPreAuthSuccess() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport =
|
||||
new BinderClientTransportBuilder()
|
||||
.setPreAuthorizeServer(true)
|
||||
.setSecurityPolicy(securityPolicy)
|
||||
.build();
|
||||
transport.start(transportListener).run();
|
||||
securityPolicy
|
||||
.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS)
|
||||
.setResult(Status.PERMISSION_DENIED.withDescription("xyzzy"));
|
||||
Status transportStatus = transportListener.awaitShutdown();
|
||||
assertThat(transportStatus.getCode()).isEqualTo(Code.PERMISSION_DENIED);
|
||||
assertThat(transportStatus.getDescription()).contains("xyzzy");
|
||||
transportListener.awaitTermination();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncSecurityPolicyCancelledUponExternalTermination() throws Exception {
|
||||
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
|
||||
transport = new BinderClientTransportBuilder().setSecurityPolicy(securityPolicy).build();
|
||||
transport.start(transportListener).run();
|
||||
AuthRequest authRequest = securityPolicy.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS);
|
||||
transport.shutdownNow(Status.UNAVAILABLE); // 'authRequest' remains unanswered!
|
||||
transportListener.awaitShutdown();
|
||||
transportListener.awaitTermination();
|
||||
assertThat(authRequest.isCancelled()).isTrue();
|
||||
}
|
||||
|
||||
private static void startAndAwaitReady(
|
||||
BinderTransport.BinderClientTransport transport, TestTransportListener transportListener)
|
||||
throws Exception {
|
||||
BinderClientTransport transport, TestTransportListener transportListener) throws Exception {
|
||||
transport.start(transportListener).run();
|
||||
transportListener.awaitReady();
|
||||
}
|
||||
|
@ -429,7 +521,7 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
|
||||
public Status awaitShutdown() throws Exception {
|
||||
return shutdownStatus.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
return shutdownStatus.get(TIMEOUT_SECONDS, SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -440,7 +532,7 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
|
||||
public void awaitTermination() throws Exception {
|
||||
isTerminated.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
isTerminated.get(TIMEOUT_SECONDS, SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -451,7 +543,7 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
|
||||
public void awaitReady() throws Exception {
|
||||
isReady.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
||||
isReady.get(TIMEOUT_SECONDS, SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -567,25 +659,4 @@ public final class BinderClientTransportTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** An AsyncSecurityPolicy that lets a test specify the outcome of checkAuthorizationAsync(). */
|
||||
static class SettableAsyncSecurityPolicy extends AsyncSecurityPolicy {
|
||||
private SettableFuture<Status> result = SettableFuture.create();
|
||||
|
||||
public void clearAuthorizationResult() {
|
||||
result = SettableFuture.create();
|
||||
}
|
||||
|
||||
public boolean setAuthorizationResult(Status status) {
|
||||
return result.set(status);
|
||||
}
|
||||
|
||||
public boolean setAuthorizationException(Throwable t) {
|
||||
return result.setException(t);
|
||||
}
|
||||
|
||||
public ListenableFuture<Status> checkAuthorizationAsync(int uid) {
|
||||
return Futures.nonCancellationPropagating(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,8 +106,7 @@ public final class BinderTransportTest extends AbstractTransportTest {
|
|||
options.setEagAttributes(eagAttrs());
|
||||
options.setChannelLogger(transportLogger());
|
||||
|
||||
return new BinderTransport.BinderClientTransport(
|
||||
builder.buildClientTransportFactory(), addr, options);
|
||||
return new BinderClientTransport(builder.buildClientTransportFactory(), addr, options);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -18,10 +18,14 @@ package io.grpc.binder;
|
|||
|
||||
import static android.content.Intent.URI_ANDROID_APP_SCHEME;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
import com.google.common.base.Objects;
|
||||
import io.grpc.ExperimentalApi;
|
||||
import java.net.SocketAddress;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -41,18 +45,25 @@ import javax.annotation.Nullable;
|
|||
* fields, namely, an action of {@link ApiConstants#ACTION_BIND}, an empty category set and null
|
||||
* type and data URI.
|
||||
*
|
||||
* <p>The semantics of {@link #equals(Object)} are the same as {@link Intent#filterEquals(Intent)}.
|
||||
* <p>Optionally contains a {@link UserHandle} that must be considered wherever the {@link Intent}
|
||||
* is evaluated.
|
||||
*
|
||||
* <p>{@link #equals(Object)} uses {@link Intent#filterEquals(Intent)} semantics to compare Intents.
|
||||
*/
|
||||
public final class AndroidComponentAddress extends SocketAddress {
|
||||
private static final long serialVersionUID = 0L;
|
||||
|
||||
private final Intent bindIntent; // "Explicit", having either a component or package restriction.
|
||||
|
||||
protected AndroidComponentAddress(Intent bindIntent) {
|
||||
@Nullable
|
||||
private final UserHandle targetUser; // null means the same user that hosts this process.
|
||||
|
||||
private AndroidComponentAddress(Intent bindIntent, @Nullable UserHandle targetUser) {
|
||||
checkArgument(
|
||||
bindIntent.getComponent() != null || bindIntent.getPackage() != null,
|
||||
"'bindIntent' must be explicit. Specify either a package or ComponentName.");
|
||||
this.bindIntent = bindIntent;
|
||||
this.targetUser = targetUser;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,7 +110,7 @@ public final class AndroidComponentAddress extends SocketAddress {
|
|||
* @throws IllegalArgumentException if 'intent' isn't "explicit"
|
||||
*/
|
||||
public static AndroidComponentAddress forBindIntent(Intent intent) {
|
||||
return new AndroidComponentAddress(intent.cloneFilter());
|
||||
return new AndroidComponentAddress(intent.cloneFilter(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -108,7 +119,7 @@ public final class AndroidComponentAddress extends SocketAddress {
|
|||
*/
|
||||
public static AndroidComponentAddress forComponent(ComponentName component) {
|
||||
return new AndroidComponentAddress(
|
||||
new Intent(ApiConstants.ACTION_BIND).setComponent(component));
|
||||
new Intent(ApiConstants.ACTION_BIND).setComponent(component), null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,6 +152,9 @@ public final class AndroidComponentAddress extends SocketAddress {
|
|||
/**
|
||||
* Returns this address as an explicit {@link Intent} suitable for passing to {@link
|
||||
* Context#bindService}.
|
||||
*
|
||||
* <p>NB: The returned Intent does not specify a target Android user. If {@link #getTargetUser()}
|
||||
* is non-null, {@link Context#bindServiceAsUser} should be called instead.
|
||||
*/
|
||||
public Intent asBindIntent() {
|
||||
return bindIntent.cloneFilter(); // Intent is mutable so return a copy.
|
||||
|
@ -177,13 +191,92 @@ public final class AndroidComponentAddress extends SocketAddress {
|
|||
public boolean equals(Object obj) {
|
||||
if (obj instanceof AndroidComponentAddress) {
|
||||
AndroidComponentAddress that = (AndroidComponentAddress) obj;
|
||||
return bindIntent.filterEquals(that.bindIntent);
|
||||
return bindIntent.filterEquals(that.bindIntent)
|
||||
&& Objects.equal(this.targetUser, that.targetUser);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AndroidComponentAddress[" + bindIntent + "]";
|
||||
StringBuilder builder = new StringBuilder("AndroidComponentAddress[");
|
||||
if (targetUser != null) {
|
||||
builder.append(targetUser);
|
||||
builder.append("@");
|
||||
}
|
||||
builder.append(bindIntent);
|
||||
builder.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies the Android user in which the bind Intent will be evaluated.
|
||||
*
|
||||
* <p>Returns the {@link UserHandle}, or null which means that the Android user hosting the
|
||||
* current process will be used.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/10173")
|
||||
@Nullable
|
||||
public UserHandle getTargetUser() {
|
||||
return targetUser;
|
||||
}
|
||||
|
||||
public static Builder newBuilder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
/** Fluently builds instances of {@link AndroidComponentAddress}. */
|
||||
public static class Builder {
|
||||
Intent bindIntent;
|
||||
UserHandle targetUser;
|
||||
|
||||
/**
|
||||
* Sets the binding {@link Intent} to one having the "filter matching" fields of 'intent'.
|
||||
*
|
||||
* <p>'intent' must be "explicit", i.e. having either a target component ({@link
|
||||
* Intent#getComponent()}) or package restriction ({@link Intent#getPackage()}).
|
||||
*/
|
||||
public Builder setBindIntent(Intent intent) {
|
||||
this.bindIntent = intent.cloneFilter();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the binding {@link Intent} to one with the specified 'component' and default values for
|
||||
* all other fields, for convenience.
|
||||
*/
|
||||
public Builder setBindIntentFromComponent(ComponentName component) {
|
||||
this.bindIntent = new Intent(ApiConstants.ACTION_BIND).setComponent(component);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the Android user in which the built Address' bind Intent will be evaluated.
|
||||
*
|
||||
* <p>Connecting to a server in a different Android user is uncommon and requires the client app
|
||||
* have runtime visibility of @SystemApi's and hold certain @SystemApi permissions.
|
||||
* The device must also be running Android SDK version 30 or higher.
|
||||
*
|
||||
* <p>See https://developer.android.com/guide/app-compatibility/restrictions-non-sdk-interfaces
|
||||
* for details on which apps can call the underlying @SystemApi's needed to make this type
|
||||
* of connection.
|
||||
*
|
||||
* <p>One of the "android.permission.INTERACT_ACROSS_XXX" permissions is required. The exact one
|
||||
* depends on the calling user's relationship to the target user, whether client and server are
|
||||
* in the same or different apps, and the version of Android in use. See {@link
|
||||
* Context#bindServiceAsUser}, the essential underlying Android API, for details.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/10173")
|
||||
public Builder setTargetUser(@Nullable UserHandle targetUser) {
|
||||
this.targetUser = targetUser;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AndroidComponentAddress build() {
|
||||
// We clone any incoming mutable intent in the setter, not here. AndroidComponentAddress
|
||||
// itself is immutable so multiple instances built from here can safely share 'bindIntent'.
|
||||
checkState(bindIntent != null, "Required property 'bindIntent' unset");
|
||||
return new AndroidComponentAddress(bindIntent, targetUser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
package io.grpc.binder;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
import io.grpc.Attributes;
|
||||
import io.grpc.EquivalentAddressGroup;
|
||||
import io.grpc.ExperimentalApi;
|
||||
import io.grpc.NameResolver;
|
||||
|
||||
/** Constant parts of the gRPC binder transport public API. */
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/8022")
|
||||
|
@ -29,4 +33,43 @@ public final class ApiConstants {
|
|||
* themselves in a {@link android.app.Service#onBind(Intent)} call.
|
||||
*/
|
||||
public static final String ACTION_BIND = "grpc.io.action.BIND";
|
||||
|
||||
/**
|
||||
* Gives a {@link NameResolver} access to its Channel's "source" {@link android.content.Context},
|
||||
* the entry point to almost every other Android API.
|
||||
*
|
||||
* <p>This argument is set automatically by {@link BinderChannelBuilder}. Any value passed to
|
||||
* {@link io.grpc.ManagedChannelBuilder#setNameResolverArg} will be ignored.
|
||||
*
|
||||
* <p>See {@link BinderChannelBuilder#forTarget(String, android.content.Context)} for more.
|
||||
*/
|
||||
public static final NameResolver.Args.Key<android.content.Context> SOURCE_ANDROID_CONTEXT =
|
||||
NameResolver.Args.Key.create("source-android-context");
|
||||
|
||||
/**
|
||||
* Specifies the Android user in which target URIs should be resolved.
|
||||
*
|
||||
* <p>{@link UserHandle} can't reasonably be encoded in a target URI string. Instead, all {@link
|
||||
* io.grpc.NameResolverProvider}s producing {@link AndroidComponentAddress}es should let clients
|
||||
* address servers in another Android user using this argument.
|
||||
*
|
||||
* <p>Connecting to a server in a different Android user is uncommon and can only be done by a
|
||||
* "system app" client with special permissions. See {@link
|
||||
* AndroidComponentAddress.Builder#setTargetUser(UserHandle)} for details.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/10173")
|
||||
public static final NameResolver.Args.Key<UserHandle> TARGET_ANDROID_USER =
|
||||
NameResolver.Args.Key.create("target-android-user");
|
||||
|
||||
/**
|
||||
* Lets you override a Channel's pre-auth configuration (see {@link
|
||||
* BinderChannelBuilder#preAuthorizeServers(boolean)}) for a given {@link EquivalentAddressGroup}.
|
||||
*
|
||||
* <p>A {@link NameResolver} that discovers servers from an untrusted source like PackageManager
|
||||
* can use this to force server pre-auth and prevent abuse.
|
||||
*/
|
||||
@EquivalentAddressGroup.Attr
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/12191")
|
||||
public static final Attributes.Key<Boolean> PRE_AUTH_SERVER_OVERRIDE =
|
||||
Attributes.Key.create("pre-auth-server-override");
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
package io.grpc.binder;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import io.grpc.ExperimentalApi;
|
||||
import io.grpc.Status;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
/**
|
||||
* Decides whether a given Android UID is authorized to access some resource.
|
||||
|
@ -67,4 +67,25 @@ public abstract class AsyncSecurityPolicy extends SecurityPolicy {
|
|||
* authorized.
|
||||
*/
|
||||
public abstract ListenableFuture<Status> checkAuthorizationAsync(int uid);
|
||||
|
||||
/**
|
||||
* Decides whether the given Android UID is authorized, without providing its raw integer value.
|
||||
*
|
||||
* <p>Calling this is equivalent to calling {@link SecurityPolicy#checkAuthorization(int)}, except
|
||||
* the caller provides a {@link PeerUid} wrapper instead of the raw integer uid (known only to the
|
||||
* transport). This allows a server to check additional application-layer security policy for
|
||||
* itself *after* the call itself is authorized by the transport layer. Cross cutting application-
|
||||
* layer checks could be done from a {@link io.grpc.ServerInterceptor}. Checks based on the
|
||||
* substance of a request message could be done by the individual RPC method implementations
|
||||
* themselves.
|
||||
*
|
||||
* <p>See #checkAuthorizationAsync(int) for details on the semantics. See {@link
|
||||
* PeerUids#newPeerIdentifyingServerInterceptor()} for how to get a {@link PeerUid}.
|
||||
*
|
||||
* @param uid The Android UID to authenticate.
|
||||
* @return A gRPC {@link Status} object, with OK indicating authorized.
|
||||
*/
|
||||
public final ListenableFuture<Status> checkAuthorizationAsync(PeerUid uid) {
|
||||
return checkAuthorizationAsync(uid.getUid());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,20 +236,28 @@ public final class BinderChannelBuilder extends ForwardingChannelBuilder<BinderC
|
|||
}
|
||||
|
||||
/**
|
||||
* Provides the target {@UserHandle} of the remote Android service.
|
||||
* Specifies the {@link UserHandle} to be searched for the remote Android Service by default.
|
||||
*
|
||||
* <p>When targetUserHandle is set, Context.bindServiceAsUser will used and additional Android
|
||||
* permissions will be required. If your usage does not require cross-user communications, please
|
||||
* do not set this field. It is the caller's responsibility to make sure that it holds the
|
||||
* corresponding permissions.
|
||||
* <p>Used only as a fallback if the direct or resolved {@link AndroidComponentAddress} doesn't
|
||||
* specify a {@link UserHandle}. If neither the Channel nor the {@link AndroidComponentAddress}
|
||||
* specifies a target user, the {@link UserHandle} of the current process will be used.
|
||||
*
|
||||
* <p>Connecting to a server in a different Android user is uncommon and can only be done by a
|
||||
* "system app" client with special permissions. See {@link
|
||||
* AndroidComponentAddress.Builder#setTargetUser(UserHandle)} for details.
|
||||
*
|
||||
* @deprecated This method's name is misleading because it implies an impersonated client identity
|
||||
* when it's actually specifying part of the server's location. It's also no longer necessary
|
||||
* since the target user is part of {@link AndroidComponentAddress}. Prefer to specify target
|
||||
* user in the address instead, either directly or via a {@link io.grpc.NameResolverProvider}.
|
||||
* @param targetUserHandle the target user to bind into.
|
||||
* @return this
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/10173")
|
||||
@RequiresApi(30)
|
||||
@Deprecated
|
||||
public BinderChannelBuilder bindAsUser(UserHandle targetUserHandle) {
|
||||
transportFactoryBuilder.setTargetUserHandle(targetUserHandle);
|
||||
transportFactoryBuilder.setDefaultTargetUserHandle(targetUserHandle);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -271,6 +279,35 @@ public final class BinderChannelBuilder extends ForwardingChannelBuilder<BinderC
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks servers against this Channel's {@link SecurityPolicy} *before* binding.
|
||||
*
|
||||
* <p>Android users can be tricked into installing a malicious app with the same package name as a
|
||||
* legitimate server. That's why we don't send calls to a server until it has been authorized by
|
||||
* an appropriate {@link SecurityPolicy}. But merely binding to a malicious server can enable
|
||||
* "keep-alive" and "background activity launch" abuse, even if it's ultimately unauthorized.
|
||||
* Pre-authorization mitigates these threats by performing a preliminary {@link SecurityPolicy}
|
||||
* check against a server app's PackageManager-registered identity without actually creating an
|
||||
* instance of it. This is especially important for security when the server's direct address
|
||||
* isn't known in advance but rather resolved via target URI or discovered by other means.
|
||||
*
|
||||
* <p>Note that, unlike ordinary authorization, pre-authorization is performed against the server
|
||||
* app's UID, not the UID of the process hosting the bound Service. These can be different, most
|
||||
* commonly due to services that set `android:isolatedProcess=true`.
|
||||
*
|
||||
* <p>Pre-authorization is strongly recommended but it remains optional for now because of this
|
||||
* behavior change and the small performance cost.
|
||||
*
|
||||
* <p>The default value of this property is false but it will become true in a future release.
|
||||
* Clients that require a particular behavior should configure it explicitly using this method
|
||||
* rather than relying on the default.
|
||||
*/
|
||||
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/12191")
|
||||
public BinderChannelBuilder preAuthorizeServers(boolean preAuthorize) {
|
||||
transportFactoryBuilder.setPreAuthorizeServers(preAuthorize);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BinderChannelBuilder idleTimeout(long value, TimeUnit unit) {
|
||||
checkState(
|
||||
|
@ -284,6 +321,8 @@ public final class BinderChannelBuilder extends ForwardingChannelBuilder<BinderC
|
|||
public ManagedChannel build() {
|
||||
transportFactoryBuilder.setOffloadExecutorPool(
|
||||
managedChannelImplBuilder.getOffloadExecutorPool());
|
||||
setNameResolverArg(
|
||||
ApiConstants.SOURCE_ANDROID_CONTEXT, transportFactoryBuilder.getSourceContext());
|
||||
return super.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,7 +184,6 @@ public final class SecurityPolicies {
|
|||
* Creates {@link SecurityPolicy} which checks if the app is a device owner app. See {@link
|
||||
* DevicePolicyManager}.
|
||||
*/
|
||||
@RequiresApi(18)
|
||||
public static io.grpc.binder.SecurityPolicy isDeviceOwner(Context applicationContext) {
|
||||
DevicePolicyManager devicePolicyManager =
|
||||
(DevicePolicyManager) applicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
|
@ -199,7 +198,6 @@ public final class SecurityPolicies {
|
|||
* Creates {@link SecurityPolicy} which checks if the app is a profile owner app. See {@link
|
||||
* DevicePolicyManager}.
|
||||
*/
|
||||
@RequiresApi(21)
|
||||
public static SecurityPolicy isProfileOwner(Context applicationContext) {
|
||||
DevicePolicyManager devicePolicyManager =
|
||||
(DevicePolicyManager) applicationContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
package io.grpc.binder;
|
||||
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import io.grpc.Status;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
/**
|
||||
* Decides whether a given Android UID is authorized to access some resource.
|
||||
|
@ -53,4 +53,25 @@ public abstract class SecurityPolicy {
|
|||
* @return A gRPC {@link Status} object, with OK indicating authorized.
|
||||
*/
|
||||
public abstract Status checkAuthorization(int uid);
|
||||
|
||||
/**
|
||||
* Decides whether the given Android UID is authorized, without providing its raw integer value.
|
||||
*
|
||||
* <p>Calling this is equivalent to calling {@link SecurityPolicy#checkAuthorization(int)}, except
|
||||
* the caller provides a {@link PeerUid} wrapper instead of the raw integer uid (known only to the
|
||||
* transport). This allows a server to check additional application-layer security policy for
|
||||
* itself *after* the call itself is authorized by the transport layer. Cross cutting application-
|
||||
* layer checks could be done from a {@link io.grpc.ServerInterceptor}. Checks based on the
|
||||
* substance of a request message could be done by the individual RPC method implementations
|
||||
* themselves.
|
||||
*
|
||||
* <p>See #checkAuthorizationAsync(int) for details on the semantics. See {@link
|
||||
* PeerUids#newPeerIdentifyingServerInterceptor()} for how to get a {@link PeerUid}.
|
||||
*
|
||||
* @param uid The Android UID to authenticate.
|
||||
* @return A gRPC {@link Status} object, with OK indicating authorized.
|
||||
*/
|
||||
public final Status checkAuthorization(PeerUid uid) {
|
||||
return checkAuthorization(uid.getUid());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,10 @@ package io.grpc.binder;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.errorprone.annotations.CheckReturnValue;
|
||||
import io.grpc.Status;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.CheckReturnValue;
|
||||
|
||||
/**
|
||||
* A security policy for a gRPC server.
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue