Compare commits

..

19 Commits

Author SHA1 Message Date
Eric Anderson 9eda2b9092 Bump version to 1.68.3 2025-01-16 07:46:06 -08:00
Eric Anderson 9035e4efa3 Update README etc to reference 1.68.3 2025-01-16 07:37:44 -08:00
ZachChuba eb14478d0d fix security issue with okhttp (#11749)
* Validate that hostname is ascii in OkHostnameVerifier.java
2025-01-15 14:55:19 -08:00
vinodhabib bccbb8bfe4 xds: fixed unsupported unsigned 32 bits issue for circuit breaker (#11735)
Added change for circuit breaking by converting signed 32-bit Int to Unsigned 64-bit Long For MaxRequest negative value ( -1)

Fixes #11695
2025-01-15 14:54:42 -08:00
Eric Anderson 14db9e19dd xds: Remember nonces for unknown types
If the control plane sends a resource type the client doesn't understand
at-the-moment, the control plane will still expect the client to include
the nonce if the client subscribes to the type in the future.

This most easily happens when unsubscribing the last resource of a type.
Which meant 1cf1927d1 was insufficient.
2025-01-07 14:25:20 -08:00
Eric Anderson 7fe25f7355 xds: Preserve nonce when unsubscribing type
This fixes a regression introduced in 19c9b998.

b/374697875
2025-01-07 10:39:49 -08:00
Eric Anderson 32877ea94f
xds: Unexpected types in server_features should be ignored
It was clearly defined in gRFC A30. The relevant text was copied as a
comment in the code.

As discovered due to grpc/grpc-go#7932
2024-12-16 20:54:00 -08:00
Eric Anderson 7433b11395 Bump version to 1.68.3-SNAPSHOT 2024-11-27 16:13:48 -08:00
Eric Anderson fa5cfcd63c Bump version to 1.68.2 2024-11-27 16:08:03 -08:00
Eric Anderson 3782ba89a0 Update README etc to reference 1.68.2 2024-11-27 15:56:46 -08:00
Kannan J 1dac376256 okhttp: Use failing "source" for read bytes when sending GOAWAY due to insufficient thread pool size
Create `ClientFrameHandler` with failing source to be used in case of failed 2nd thread scheduling. Fixes NPE from https://github.com/grpc/grpc-java/pull/11503.
2024-11-27 15:53:47 -08:00
Yash Tibrewal e225c23552
[CSM] Use xds-enabled server and xds credentials in examples (#11706)
Backport #11706 to v1.68.x
2024-11-27 14:56:06 -08:00
Vindhya Ningegowda 197a15c9c9
gae-interop-testing: Upgrade to Java 17 (#11710)
Java 11 is out-of-support on GAE. Unfortunately the docs use the term
"deprecated" as "deleted," not "discouraged." So they talk about it
being deprecated _after_ it is no longer supported.

https://cloud.google.com/appengine/docs/standard/lifecycle/support-schedule#java
https://cloud.google.com/appengine/docs/flexible/lifecycle/support-schedule#java

Backport of #11699
2024-11-26 17:26:52 -08:00
Kannan J 2636d5dda0
api: When forwarding from Listener onAddresses to Listener2 continue to use onResult (#11666) (#11688)
When forwarding from Listener onAddresses to Listener2 continue to use onResult and not onResult2 because the latter requires to be called from within synchronization context and it breaks existing code that didn't need to do so when using the old Listener interface.
2024-11-14 22:04:10 +05:30
Eric Anderson 468b29cb35 Bump version to 1.68.2-SNAPSHOT 2024-10-28 16:30:39 -07:00
Eric Anderson 16f93c8127 Bump version to 1.68.1 2024-10-28 16:22:10 -07:00
Eric Anderson 2b533529df Update README etc to reference 1.68.1 2024-10-28 16:11:16 -07:00
Eric Anderson 135f433bcd
Revert "stub: Ignore unary response on server if status is not OK" (#11636) (#11640)
This reverts commit 99f86835ed.

The change doesn't handle `null` messages, which don't happen with
protobuf, but can happen with other marshallers, especially in tests.
See cl/689445172

This will reopen #5969.
2024-10-28 09:59:45 +05:30
Eric Anderson 2d0c158987
Bump to 1.68.1-SNAPSHOT (#11637)
1.68.0 has already been used (by a mistaken 1.67.x release)
2024-10-25 12:20:26 +05:30
732 changed files with 11528 additions and 34658 deletions

View File

@ -1,41 +0,0 @@
name: GitHub Actions Branch Testing
on:
push:
branches:
- master
- 'v1.*'
schedule:
- cron: '54 19 * * SUN' # weekly at a "random" time
permissions:
contents: read
jobs:
arm64:
runs-on: ubuntu-24.04-arm
strategy:
matrix:
jre: [17]
fail-fast: false # Should swap to true if we grow a large matrix
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: ${{ matrix.jre }}
distribution: 'temurin'
- name: Gradle cache
uses: actions/cache@v4
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build
run: ./gradlew -Dorg.gradle.parallel=true -Dorg.gradle.jvmargs='-Xmx1g' -PskipAndroid=true -PskipCodegen=true -PerrorProne=false test

View File

@ -77,11 +77,8 @@ jobs:
bazel:
runs-on: ubuntu-latest
strategy:
matrix:
bzlmod: [true, false]
env:
USE_BAZEL_VERSION: 7.0.0
USE_BAZEL_VERSION: 6.0.0
steps:
- uses: actions/checkout@v4
@ -100,11 +97,19 @@ jobs:
key: ${{ runner.os }}-bazel-${{ env.USE_BAZEL_VERSION }}-${{ hashFiles('WORKSPACE', 'repositories.bzl') }}
- name: Run bazel build
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }}
- name: Run bazel test
run: bazelisk test //... --enable_bzlmod=${{ matrix.bzlmod }}
run: bazelisk build //... --enable_bzlmod=false
- name: Run example bazel build
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }}
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
working-directory: ./examples

View File

@ -33,6 +33,7 @@ java_library(
"//api",
"//protobuf",
"//stub",
"//stub:javax_annotation",
"@com_google_protobuf//:protobuf_java",
artifact("com.google.code.findbugs:jsr305"),
artifact("com.google.guava:guava"),
@ -46,6 +47,7 @@ java_library(
"//api",
"//protobuf-lite",
"//stub",
"//stub:javax_annotation",
artifact("com.google.code.findbugs:jsr305"),
artifact("com.google.guava:guava"),
],
@ -65,5 +67,6 @@ java_library(
visibility = ["//:__subpackages__"],
exports = [
artifact("com.google.auto.value:auto-value-annotations"),
artifact("org.apache.tomcat:annotations-api"), # @Generated for Java 9+
],
)

View File

@ -44,11 +44,11 @@ This section is only necessary if you are making changes to the code
generation. Most users only need to use `skipCodegen=true` as discussed above.
### Build Protobuf
The codegen plugin is C++ code and requires protobuf 22.5 or later.
The codegen plugin is C++ code and requires protobuf 21.7 or later.
For Linux, Mac and MinGW:
```
$ PROTOBUF_VERSION=22.5
$ PROTOBUF_VERSION=21.7
$ curl -LO https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-all-$PROTOBUF_VERSION.tar.gz
$ tar xzf protobuf-all-$PROTOBUF_VERSION.tar.gz
$ cd protobuf-$PROTOBUF_VERSION

View File

@ -11,6 +11,8 @@ 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
@ -24,9 +26,7 @@ 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)

View File

@ -2,61 +2,79 @@ module(
name = "grpc-java",
compatibility_level = 0,
repo_name = "io_grpc_grpc_java",
version = "1.76.0-SNAPSHOT", # CURRENT_GRPC_VERSION
version = "1.68.3", # CURRENT_GRPC_VERSION
)
# GRPC_DEPS_START
IO_GRPC_GRPC_JAVA_ARTIFACTS = [
"com.google.android:annotations:4.1.1.4",
"com.google.api.grpc:proto-google-common-protos:2.59.2",
"com.google.auth:google-auth-library-credentials:1.24.1",
"com.google.auth:google-auth-library-oauth2-http:1.24.1",
"com.google.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.auto.value:auto-value-annotations:1.11.0",
"com.google.auto.value:auto-value:1.11.0",
"com.google.code.findbugs:jsr305:3.0.2",
"com.google.code.gson:gson:2.11.0",
"com.google.errorprone:error_prone_annotations:2.30.0",
"com.google.errorprone:error_prone_annotations:2.28.0",
"com.google.guava:failureaccess:1.0.1",
"com.google.guava:guava:33.3.1-android",
"com.google.re2j:re2j:1.8",
"com.google.s2a.proto.v2:s2a-proto:0.1.2",
"com.google.guava:guava:33.2.1-android",
"com.google.re2j:re2j:1.7",
"com.google.truth:truth:1.4.2",
"com.squareup.okhttp:okhttp:2.7.5",
"com.squareup.okio:okio:2.10.0", # 3.0+ needs swapping to -jvm; need work to avoid flag-day
"io.netty:netty-buffer:4.1.124.Final",
"io.netty:netty-codec-http2:4.1.124.Final",
"io.netty:netty-codec-http:4.1.124.Final",
"io.netty:netty-codec-socks:4.1.124.Final",
"io.netty:netty-codec:4.1.124.Final",
"io.netty:netty-common:4.1.124.Final",
"io.netty:netty-handler-proxy:4.1.124.Final",
"io.netty:netty-handler:4.1.124.Final",
"io.netty:netty-resolver:4.1.124.Final",
"io.netty:netty-tcnative-boringssl-static:2.0.70.Final",
"io.netty:netty-tcnative-classes:2.0.70.Final",
"io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.124.Final",
"io.netty:netty-transport-native-unix-common:4.1.124.Final",
"io.netty:netty-transport:4.1.124.Final",
"io.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.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")
# 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 = "protobuf", repo_name = "com_google_protobuf", version = "23.1")
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(
@ -183,3 +201,7 @@ 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)

View File

@ -44,8 +44,8 @@ For a guided tour, take a look at the [quick start
guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC
basics](https://grpc.io/docs/languages/java/basics).
The [examples](https://github.com/grpc/grpc-java/tree/v1.75.0/examples) and the
[Android example](https://github.com/grpc/grpc-java/tree/v1.75.0/examples/android)
The [examples](https://github.com/grpc/grpc-java/tree/v1.68.3/examples) and the
[Android example](https://github.com/grpc/grpc-java/tree/v1.68.3/examples/android)
are standalone projects that showcase the usage of gRPC.
Download
@ -56,18 +56,18 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.75.0</version>
<version>1.68.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.75.0</version>
<version>1.68.3</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.75.0</version>
<version>1.68.3</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.75.0'
implementation 'io.grpc:grpc-protobuf:1.75.0'
implementation 'io.grpc:grpc-stub:1.75.0'
runtimeOnly 'io.grpc:grpc-netty-shaded:1.68.3'
implementation 'io.grpc:grpc-protobuf:1.68.3'
implementation 'io.grpc:grpc-stub:1.68.3'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
```
For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and
`grpc-protobuf-lite` instead of `grpc-protobuf`:
```gradle
implementation 'io.grpc:grpc-okhttp:1.75.0'
implementation 'io.grpc:grpc-protobuf-lite:1.75.0'
implementation 'io.grpc:grpc-stub:1.75.0'
implementation 'io.grpc:grpc-okhttp:1.68.3'
implementation 'io.grpc:grpc-protobuf-lite:1.68.3'
implementation 'io.grpc:grpc-stub:1.68.3'
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.75.0
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.68.3
Development snapshots are available in [Sonatypes's snapshot
repository](https://central.sonatype.com/repository/maven-snapshots/).
repository](https://oss.sonatype.org/content/repositories/snapshots/).
Generated Code
--------------
@ -131,7 +131,7 @@ For protobuf-based codegen integrated with the Maven build system, you can use
<configuration>
<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.75.0:exe:${os.detected.classifier}</pluginArtifact>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.68.3:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
@ -152,7 +152,7 @@ For non-Android protobuf-based codegen integrated with the Gradle build system,
you can use [protobuf-gradle-plugin][]:
```gradle
plugins {
id 'com.google.protobuf' version '0.9.5'
id 'com.google.protobuf' version '0.9.4'
}
protobuf {
@ -161,7 +161,7 @@ protobuf {
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
artifact = 'io.grpc:protoc-gen-grpc-java:1.68.3'
}
}
generateProtoTasks {
@ -185,7 +185,7 @@ use protobuf-gradle-plugin but specify the 'lite' options:
```gradle
plugins {
id 'com.google.protobuf' version '0.9.5'
id 'com.google.protobuf' version '0.9.4'
}
protobuf {
@ -194,7 +194,7 @@ protobuf {
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
artifact = 'io.grpc:protoc-gen-grpc-java:1.68.3'
}
}
generateProtoTasks {

View File

@ -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/publish/publish-portal-ossrh-staging-api/#deploying).
Central on the [OSSRH site](https://central.sonatype.org/pages/releasing-the-deployment.html).
10. We have containers for each release to detect compatibility regressions with
old releases. Generate one for the new release by following the [GCR image
generation instructions][gcr-image]. Summary:
```bash
# If you haven't previously configured docker:
gcloud auth configure-docker us-docker.pkg.dev
gcloud auth configure-docker
# In main grpc repo, add the new version to matrix
${EDITOR:-nano -w} tools/interop_matrix/client_matrix.py
tools/interop_matrix/create_matrix_images.py --git_checkout --release=v$MAJOR.$MINOR.$PATCH \
--upload_images --language java
docker pull us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH
docker_image=us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH \
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 \
tools/interop_matrix/testcases/java__master
# Commit the changes

View File

@ -399,9 +399,7 @@ 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-1.70.x | 4.1.110.Final | 2.0.65.Final
1.71.x-1.74.x | 4.1.110.Final | 2.0.70.Final
1.75.x- | 4.1.124.Final | 2.0.72.Final
1.67.x | 4.1.110.Final | 2.0.65.Final
_(grpc-netty-shaded avoids issues with keeping these versions in sync.)_

View File

@ -22,19 +22,20 @@ 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(

View File

@ -18,7 +18,6 @@ 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"),

View File

@ -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,11 +44,7 @@ dependencies {
classifier = "linux-x86_64"
}
}
signature (libraries.signature.java) {
artifact {
extension = "signature"
}
}
signature libraries.signature.java
}
configureProtoCompilation()

View File

@ -4,6 +4,9 @@ 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 {
@ -57,21 +60,6 @@ public final class HandshakerServiceGrpc {
return HandshakerServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static HandshakerServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<HandshakerServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<HandshakerServiceBlockingV2Stub>() {
@java.lang.Override
public HandshakerServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new HandshakerServiceBlockingV2Stub(channel, callOptions);
}
};
return HandshakerServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -169,40 +157,6 @@ public final class HandshakerServiceGrpc {
/**
* A stub to allow clients to do synchronous rpc calls to service HandshakerService.
*/
public static final class HandshakerServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<HandshakerServiceBlockingV2Stub> {
private HandshakerServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected HandshakerServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new HandshakerServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Handshaker service accepts a stream of handshaker request, returning a
* stream of handshaker response. Client is expected to send exactly one
* message with either client_start or server_start followed by one or more
* messages with next. Each time client sends a request, the handshaker
* service expects to respond. Client does not have to wait for service's
* response before sending next request.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.alts.internal.HandshakerReq, io.grpc.alts.internal.HandshakerResp>
doHandshake() {
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
getChannel(), getDoHandshakeMethod(), getCallOptions());
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service HandshakerService.
*/
public static final class HandshakerServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<HandshakerServiceBlockingStub> {
private HandshakerServiceBlockingStub(

View File

@ -14,10 +14,9 @@
* limitations under the License.
*/
package io.grpc.alts;
import io.grpc.Attributes;
import io.grpc.ClientCall;
import io.grpc.ExperimentalApi;
import io.grpc.ServerCall;
import io.grpc.alts.internal.AltsInternalContext;
@ -30,36 +29,14 @@ public final class AltsContextUtil {
private AltsContextUtil() {}
/**
* Creates an {@link AltsContext} from ALTS context information in the {@link ServerCall}.
* Creates a {@link AltsContext} from ALTS context information in the {@link ServerCall}.
*
* @param call the {@link ServerCall} containing the ALTS information
* @return the created {@link AltsContext}
* @throws IllegalArgumentException if the {@link ServerCall} has no ALTS information.
*/
public static AltsContext createFrom(ServerCall<?, ?> call) {
return createFrom(call.getAttributes());
}
/**
* Creates an {@link AltsContext} from ALTS context information in the {@link ClientCall}.
*
* @param call the {@link ClientCall} containing the ALTS information
* @return the created {@link AltsContext}
* @throws IllegalArgumentException if the {@link ClientCall} has no ALTS information.
*/
public static AltsContext createFrom(ClientCall<?, ?> call) {
return createFrom(call.getAttributes());
}
/**
* Creates an {@link AltsContext} from ALTS context information in the {@link Attributes}.
*
* @param attributes the {@link Attributes} containing the ALTS information
* @return the created {@link AltsContext}
* @throws IllegalArgumentException if the {@link Attributes} has no ALTS information.
*/
public static AltsContext createFrom(Attributes attributes) {
Object authContext = attributes.get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
public static AltsContext createFrom(ServerCall<?,?> call) {
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
if (!(authContext instanceof AltsInternalContext)) {
throw new IllegalArgumentException("No ALTS context information found");
}
@ -72,28 +49,8 @@ public final class AltsContextUtil {
* @param call the {@link ServerCall} to check
* @return true, if the {@link ServerCall} contains ALTS information and false otherwise.
*/
public static boolean check(ServerCall<?, ?> call) {
return check(call.getAttributes());
}
/**
* Checks if the {@link ClientCall} contains ALTS information.
*
* @param call the {@link ClientCall} to check
* @return true, if the {@link ClientCall} contains ALTS information and false otherwise.
*/
public static boolean check(ClientCall<?, ?> call) {
return check(call.getAttributes());
}
/**
* Checks if the {@link Attributes} contains ALTS information.
*
* @param attributes the {@link Attributes} to check
* @return true, if the {@link Attributes} contains ALTS information and false otherwise.
*/
public static boolean check(Attributes attributes) {
Object authContext = attributes.get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
public static boolean check(ServerCall<?,?> call) {
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
return authContext instanceof AltsInternalContext;
}
}

View File

@ -1,46 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.alts;
import io.grpc.CallCredentials;
import java.util.concurrent.Executor;
/**
* {@code CallCredentials} that will pick the right credentials based on whether the established
* connection is ALTS or TLS.
*/
final class DualCallCredentials extends CallCredentials {
private final CallCredentials tlsCallCredentials;
private final CallCredentials altsCallCredentials;
public DualCallCredentials(CallCredentials tlsCallCreds, CallCredentials altsCallCreds) {
tlsCallCredentials = tlsCallCreds;
altsCallCredentials = altsCallCreds;
}
@Override
public void applyRequestMetadata(
CallCredentials.RequestInfo requestInfo,
Executor appExecutor,
CallCredentials.MetadataApplier applier) {
if (AltsContextUtil.check(requestInfo.getTransportAttrs())) {
altsCallCredentials.applyRequestMetadata(requestInfo, appExecutor, applier);
} else {
tlsCallCredentials.applyRequestMetadata(requestInfo, appExecutor, applier);
}
}
}

View File

@ -63,7 +63,6 @@ public final class GoogleDefaultChannelCredentials {
*/
public static final class Builder {
private CallCredentials callCredentials;
private CallCredentials altsCallCredentials;
private Builder() {}
@ -73,32 +72,23 @@ public final class GoogleDefaultChannelCredentials {
return this;
}
/** Constructs GoogleDefaultChannelCredentials with an ALTS-specific call credential. */
public Builder altsCallCredentials(CallCredentials callCreds) {
altsCallCredentials = callCreds;
return this;
}
/** Builds a GoogleDefaultChannelCredentials instance. */
public ChannelCredentials build() {
ChannelCredentials nettyCredentials =
InternalNettyChannelCredentials.create(createClientFactory());
CallCredentials tlsCallCreds = callCredentials;
if (tlsCallCreds == null) {
try {
tlsCallCreds = MoreCallCredentials.from(GoogleCredentials.getApplicationDefault());
} catch (IOException e) {
tlsCallCreds =
new FailingCallCredentials(
Status.UNAUTHENTICATED
.withDescription("Failed to get Google default credentials")
.withCause(e));
}
if (callCredentials != null) {
return CompositeChannelCredentials.create(nettyCredentials, callCredentials);
}
CallCredentials callCreds;
try {
callCreds = MoreCallCredentials.from(GoogleCredentials.getApplicationDefault());
} catch (IOException e) {
callCreds =
new FailingCallCredentials(
Status.UNAUTHENTICATED
.withDescription("Failed to get Google default credentials")
.withCause(e));
}
CallCredentials callCreds =
altsCallCredentials == null
? tlsCallCreds
: new DualCallCredentials(tlsCallCreds, altsCallCredentials);
return CompositeChannelCredentials.create(nettyCredentials, callCreds);
}

View File

@ -21,7 +21,6 @@ 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;
@ -46,9 +45,6 @@ final class HandshakerServiceChannel {
return new ChannelResource(handshakerAddress);
}
private static final boolean EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS =
GrpcUtil.getFlag("GRPC_EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS", false);
private static class ChannelResource implements Resource<Channel> {
private final String target;
@ -61,16 +57,12 @@ final class HandshakerServiceChannel {
/* Use its own event loop thread pool to avoid blocking. */
EventLoopGroup eventGroup =
new NioEventLoopGroup(1, new DefaultThreadFactory("handshaker pool", true));
NettyChannelBuilder channelBuilder =
NettyChannelBuilder.forTarget(target)
ManagedChannel channel = NettyChannelBuilder.forTarget(target)
.channelType(NioSocketChannel.class, InetSocketAddress.class)
.directExecutor()
.eventLoopGroup(eventGroup)
.usePlaintext();
if (EXPERIMENTAL_ALTS_HANDSHAKER_KEEPALIVE_PARAMS) {
channelBuilder.keepAliveTime(10, TimeUnit.MINUTES).keepAliveTimeout(10, TimeUnit.SECONDS);
}
ManagedChannel channel = channelBuilder.build();
.usePlaintext()
.build();
return new EventLoopHoldingChannel(channel, eventGroup);
}

View File

@ -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 {

View File

@ -24,7 +24,6 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import io.grpc.Attributes;
import io.grpc.ClientCall;
import io.grpc.ServerCall;
import io.grpc.alts.AltsContext.SecurityLevel;
import io.grpc.alts.internal.AltsInternalContext;
@ -38,28 +37,27 @@ import org.junit.runners.JUnit4;
/** Unit tests for {@link AltsContextUtil}. */
@RunWith(JUnit4.class)
public class AltsContextUtilTest {
private final ServerCall<?,?> call = mock(ServerCall.class);
@Test
public void check_noAttributeValue() {
assertFalse(AltsContextUtil.check(Attributes.newBuilder().build()));
when(call.getAttributes()).thenReturn(Attributes.newBuilder().build());
assertFalse(AltsContextUtil.check(call));
}
@Test
public void check_unexpectedAttributeValueType() {
assertFalse(AltsContextUtil.check(Attributes.newBuilder()
public void contains_unexpectedAttributeValueType() {
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new Object())
.build()));
.build());
assertFalse(AltsContextUtil.check(call));
}
@Test
public void check_altsInternalContext() {
assertTrue(AltsContextUtil.check(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
.build()));
}
@Test
public void checkServer_altsInternalContext() {
ServerCall<?,?> call = mock(ServerCall.class);
public void contains_altsInternalContext() {
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
.build());
@ -68,67 +66,26 @@ public class AltsContextUtilTest {
}
@Test
public void checkClient_altsInternalContext() {
ClientCall<?,?> call = mock(ClientCall.class);
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
.build());
assertTrue(AltsContextUtil.check(call));
}
@Test
public void createFrom_altsInternalContext() {
public void from_altsInternalContext() {
HandshakerResult handshakerResult =
HandshakerResult.newBuilder()
.setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer"))
.setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer"))
.build();
AltsContext context = AltsContextUtil.createFrom(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult))
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult))
.build());
AltsContext context = AltsContextUtil.createFrom(call);
assertEquals("remote@peer", context.getPeerServiceAccount());
assertEquals("local@peer", context.getLocalServiceAccount());
assertEquals(SecurityLevel.INTEGRITY_AND_PRIVACY, context.getSecurityLevel());
}
@Test(expected = IllegalArgumentException.class)
public void createFrom_noAttributeValue() {
AltsContextUtil.createFrom(Attributes.newBuilder().build());
}
public void from_noAttributeValue() {
when(call.getAttributes()).thenReturn(Attributes.newBuilder().build());
@Test
public void createFromServer_altsInternalContext() {
HandshakerResult handshakerResult =
HandshakerResult.newBuilder()
.setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer"))
.setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer"))
.build();
ServerCall<?,?> call = mock(ServerCall.class);
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult))
.build());
AltsContext context = AltsContextUtil.createFrom(call);
assertEquals("remote@peer", context.getPeerServiceAccount());
}
@Test
public void createFromClient_altsInternalContext() {
HandshakerResult handshakerResult =
HandshakerResult.newBuilder()
.setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer"))
.setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer"))
.build();
ClientCall<?,?> call = mock(ClientCall.class);
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult))
.build());
AltsContext context = AltsContextUtil.createFrom(call);
assertEquals("remote@peer", context.getPeerServiceAccount());
AltsContextUtil.createFrom(call);
}
}

View File

@ -1,109 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.alts;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import io.grpc.Attributes;
import io.grpc.CallCredentials;
import io.grpc.CallCredentials.RequestInfo;
import io.grpc.MethodDescriptor;
import io.grpc.SecurityLevel;
import io.grpc.alts.internal.AltsInternalContext;
import io.grpc.alts.internal.AltsProtocolNegotiator;
import io.grpc.testing.TestMethodDescriptors;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
/** Unit tests for {@link DualCallCredentials}. */
@RunWith(JUnit4.class)
public class DualCallCredentialsTest {
@Rule public final MockitoRule mocks = MockitoJUnit.rule();
@Mock CallCredentials tlsCallCredentials;
@Mock CallCredentials altsCallCredentials;
private static final String AUTHORITY = "testauthority";
private static final SecurityLevel SECURITY_LEVEL = SecurityLevel.PRIVACY_AND_INTEGRITY;
@Test
public void invokeTlsCallCredentials() {
DualCallCredentials callCredentials =
new DualCallCredentials(tlsCallCredentials, altsCallCredentials);
RequestInfo requestInfo = new RequestInfoImpl(false);
callCredentials.applyRequestMetadata(requestInfo, null, null);
verify(altsCallCredentials, never()).applyRequestMetadata(any(), any(), any());
verify(tlsCallCredentials, times(1)).applyRequestMetadata(requestInfo, null, null);
}
@Test
public void invokeAltsCallCredentials() {
DualCallCredentials callCredentials =
new DualCallCredentials(tlsCallCredentials, altsCallCredentials);
RequestInfo requestInfo = new RequestInfoImpl(true);
callCredentials.applyRequestMetadata(requestInfo, null, null);
verify(altsCallCredentials, times(1)).applyRequestMetadata(requestInfo, null, null);
verify(tlsCallCredentials, never()).applyRequestMetadata(any(), any(), any());
}
private static final class RequestInfoImpl extends CallCredentials.RequestInfo {
private Attributes attrs;
RequestInfoImpl(boolean hasAltsContext) {
attrs =
hasAltsContext
? Attributes.newBuilder()
.set(
AltsProtocolNegotiator.AUTH_CONTEXT_KEY,
AltsInternalContext.getDefaultInstance())
.build()
: Attributes.EMPTY;
}
@Override
public MethodDescriptor<?, ?> getMethodDescriptor() {
return TestMethodDescriptors.voidMethod();
}
@Override
public SecurityLevel getSecurityLevel() {
return SECURITY_LEVEL;
}
@Override
public String getAuthority() {
return AUTHORITY;
}
@Override
public Attributes getTransportAttrs() {
return attrs;
}
}
}

View File

@ -7,10 +7,11 @@ description = 'gRPC: Android Integration Testing'
repositories {
google()
mavenCentral()
}
android {
namespace = 'io.grpc.android.integrationtest'
namespace 'io.grpc.android.integrationtest'
sourceSets {
main {
java {
@ -41,7 +42,7 @@ android {
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled = true
multiDexEnabled true
}
buildTypes {
debug { minifyEnabled false }
@ -73,6 +74,7 @@ dependencies {
project(':grpc-protobuf-lite'),
project(':grpc-stub'),
project(':grpc-testing'),
libraries.hdrhistogram,
libraries.junit,
libraries.truth,
libraries.androidx.test.rules,

View File

@ -7,6 +7,9 @@ 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 {
@ -89,21 +92,6 @@ public final class LoadBalancerStatsServiceGrpc {
return LoadBalancerStatsServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static LoadBalancerStatsServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub>() {
@java.lang.Override
public LoadBalancerStatsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
};
return LoadBalancerStatsServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -224,46 +212,6 @@ public final class LoadBalancerStatsServiceGrpc {
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingV2Stub> {
private LoadBalancerStatsServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected LoadBalancerStatsServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Gets the backend distribution for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientStatsMethod(), getCallOptions(), request);
}
/**
* <pre>
* Gets the accumulated stats for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service LoadBalancerStatsService.
* <pre>
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingStub> {
private LoadBalancerStatsServiceBlockingStub(

View File

@ -4,6 +4,9 @@ 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 {
@ -86,21 +89,6 @@ public final class MetricsServiceGrpc {
return MetricsServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static MetricsServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub>() {
@java.lang.Override
public MetricsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new MetricsServiceBlockingV2Stub(channel, callOptions);
}
};
return MetricsServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -211,46 +199,6 @@ public final class MetricsServiceGrpc {
/**
* A stub to allow clients to do synchronous rpc calls to service MetricsService.
*/
public static final class MetricsServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<MetricsServiceBlockingV2Stub> {
private MetricsServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected MetricsServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new MetricsServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Returns the values of all the gauges that are currently being maintained by
* the service
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Metrics.GaugeResponse>
getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request) {
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
getChannel(), getGetAllGaugesMethod(), getCallOptions(), request);
}
/**
* <pre>
* Returns the value of one gauge
* </pre>
*/
public io.grpc.testing.integration.Metrics.GaugeResponse getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetGaugeMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service MetricsService.
*/
public static final class MetricsServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<MetricsServiceBlockingStub> {
private MetricsServiceBlockingStub(

View File

@ -7,6 +7,9 @@ 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 {
@ -89,21 +92,6 @@ public final class ReconnectServiceGrpc {
return ReconnectServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static ReconnectServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub>() {
@java.lang.Override
public ReconnectServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
};
return ReconnectServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class ReconnectServiceGrpc {
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingV2Stub> {
private ReconnectServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected ReconnectServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStartMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStopMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service ReconnectService.
* <pre>
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingStub> {
private ReconnectServiceBlockingStub(

View File

@ -8,6 +8,9 @@ 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 {
@ -270,21 +273,6 @@ public final class TestServiceGrpc {
return TestServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static TestServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub>() {
@java.lang.Override
public TestServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new TestServiceBlockingV2Stub(channel, callOptions);
}
};
return TestServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -555,125 +543,6 @@ public final class TestServiceGrpc {
* performance with various types of payload.
* </pre>
*/
public static final class TestServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingV2Stub> {
private TestServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected TestServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new TestServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* One empty request followed by one empty response.
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getEmptyCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* One request followed by one response.
* </pre>
*/
public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnaryCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* One request followed by one response. Response has cache control
* headers set such that a caching HTTP proxy (such as GFE) can
* satisfy subsequent requests.
* </pre>
*/
public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getCacheableUnaryCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* One request followed by a sequence of responses (streamed download).
* The server returns the payload with client desired type and sizes.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) {
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* A sequence of requests followed by one response (streamed upload).
* The server returns the aggregated size of client payload as the result.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingInputCallRequest, io.grpc.testing.integration.Messages.StreamingInputCallResponse>
streamingInputCall() {
return io.grpc.stub.ClientCalls.blockingClientStreamingCall(
getChannel(), getStreamingInputCallMethod(), getCallOptions());
}
/**
* <pre>
* A sequence of requests with each request served by the server immediately.
* As one request could lead to multiple responses, this interface
* demonstrates the idea of full duplexing.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
fullDuplexCall() {
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
getChannel(), getFullDuplexCallMethod(), getCallOptions());
}
/**
* <pre>
* A sequence of requests followed by a sequence of responses.
* The server buffers all the client requests and then serves them in order. A
* stream of responses are returned to the client when the server starts with
* first request.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
halfDuplexCall() {
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
getChannel(), getHalfDuplexCallMethod(), getCallOptions());
}
/**
* <pre>
* The test server will not implement this method. It will be used
* to test the behavior when clients call unimplemented methods.
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnimplementedCallMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service TestService.
* <pre>
* A simple service to test the various types of RPCs and experiment with
* performance with various types of payload.
* </pre>
*/
public static final class TestServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingStub> {
private TestServiceBlockingStub(

View File

@ -8,6 +8,9 @@ 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 {
@ -60,21 +63,6 @@ public final class UnimplementedServiceGrpc {
return UnimplementedServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static UnimplementedServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub>() {
@java.lang.Override
public UnimplementedServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
};
return UnimplementedServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -178,37 +166,6 @@ public final class UnimplementedServiceGrpc {
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingV2Stub> {
private UnimplementedServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected UnimplementedServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* A call that no server should implement
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnimplementedCallMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service UnimplementedService.
* <pre>
* A simple service NOT implemented at servers so clients can test for
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingStub> {
private UnimplementedServiceBlockingStub(

View File

@ -7,6 +7,9 @@ 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 {
@ -59,21 +62,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
return XdsUpdateClientConfigureServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateClientConfigureServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateClientConfigureServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateClientConfigureServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -173,36 +161,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingV2Stub> {
private XdsUpdateClientConfigureServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateClientConfigureServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Update the tes client's configuration.
* </pre>
*/
public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getConfigureMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateClientConfigureService.
* <pre>
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingStub> {
private XdsUpdateClientConfigureServiceBlockingStub(

View File

@ -7,6 +7,9 @@ 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 {
@ -89,21 +92,6 @@ public final class XdsUpdateHealthServiceGrpc {
return XdsUpdateHealthServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateHealthServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateHealthServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateHealthServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class XdsUpdateHealthServiceGrpc {
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingV2Stub> {
private XdsUpdateHealthServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateHealthServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetServingMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetNotServingMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateHealthService.
* <pre>
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingStub> {
private XdsUpdateHealthServiceBlockingStub(

View File

@ -7,6 +7,9 @@ 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 {
@ -89,21 +92,6 @@ public final class LoadBalancerStatsServiceGrpc {
return LoadBalancerStatsServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static LoadBalancerStatsServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub>() {
@java.lang.Override
public LoadBalancerStatsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
};
return LoadBalancerStatsServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -224,46 +212,6 @@ public final class LoadBalancerStatsServiceGrpc {
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingV2Stub> {
private LoadBalancerStatsServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected LoadBalancerStatsServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Gets the backend distribution for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientStatsMethod(), getCallOptions(), request);
}
/**
* <pre>
* Gets the accumulated stats for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service LoadBalancerStatsService.
* <pre>
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingStub> {
private LoadBalancerStatsServiceBlockingStub(

View File

@ -4,6 +4,9 @@ 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 {
@ -86,21 +89,6 @@ public final class MetricsServiceGrpc {
return MetricsServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static MetricsServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<MetricsServiceBlockingV2Stub>() {
@java.lang.Override
public MetricsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new MetricsServiceBlockingV2Stub(channel, callOptions);
}
};
return MetricsServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -211,46 +199,6 @@ public final class MetricsServiceGrpc {
/**
* A stub to allow clients to do synchronous rpc calls to service MetricsService.
*/
public static final class MetricsServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<MetricsServiceBlockingV2Stub> {
private MetricsServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected MetricsServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new MetricsServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Returns the values of all the gauges that are currently being maintained by
* the service
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Metrics.GaugeResponse>
getAllGauges(io.grpc.testing.integration.Metrics.EmptyMessage request) {
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
getChannel(), getGetAllGaugesMethod(), getCallOptions(), request);
}
/**
* <pre>
* Returns the value of one gauge
* </pre>
*/
public io.grpc.testing.integration.Metrics.GaugeResponse getGauge(io.grpc.testing.integration.Metrics.GaugeRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetGaugeMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service MetricsService.
*/
public static final class MetricsServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<MetricsServiceBlockingStub> {
private MetricsServiceBlockingStub(

View File

@ -7,6 +7,9 @@ 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 {
@ -89,21 +92,6 @@ public final class ReconnectServiceGrpc {
return ReconnectServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static ReconnectServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub>() {
@java.lang.Override
public ReconnectServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
};
return ReconnectServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class ReconnectServiceGrpc {
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingV2Stub> {
private ReconnectServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected ReconnectServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStartMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStopMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service ReconnectService.
* <pre>
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingStub> {
private ReconnectServiceBlockingStub(

View File

@ -8,6 +8,9 @@ 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 {
@ -270,21 +273,6 @@ public final class TestServiceGrpc {
return TestServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static TestServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<TestServiceBlockingV2Stub>() {
@java.lang.Override
public TestServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new TestServiceBlockingV2Stub(channel, callOptions);
}
};
return TestServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -555,125 +543,6 @@ public final class TestServiceGrpc {
* performance with various types of payload.
* </pre>
*/
public static final class TestServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingV2Stub> {
private TestServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected TestServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new TestServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* One empty request followed by one empty response.
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty emptyCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getEmptyCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* One request followed by one response.
* </pre>
*/
public io.grpc.testing.integration.Messages.SimpleResponse unaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnaryCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* One request followed by one response. Response has cache control
* headers set such that a caching HTTP proxy (such as GFE) can
* satisfy subsequent requests.
* </pre>
*/
public io.grpc.testing.integration.Messages.SimpleResponse cacheableUnaryCall(io.grpc.testing.integration.Messages.SimpleRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getCacheableUnaryCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* One request followed by a sequence of responses (streamed download).
* The server returns the payload with client desired type and sizes.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<?, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
streamingOutputCall(io.grpc.testing.integration.Messages.StreamingOutputCallRequest request) {
return io.grpc.stub.ClientCalls.blockingV2ServerStreamingCall(
getChannel(), getStreamingOutputCallMethod(), getCallOptions(), request);
}
/**
* <pre>
* A sequence of requests followed by one response (streamed upload).
* The server returns the aggregated size of client payload as the result.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingInputCallRequest, io.grpc.testing.integration.Messages.StreamingInputCallResponse>
streamingInputCall() {
return io.grpc.stub.ClientCalls.blockingClientStreamingCall(
getChannel(), getStreamingInputCallMethod(), getCallOptions());
}
/**
* <pre>
* A sequence of requests with each request served by the server immediately.
* As one request could lead to multiple responses, this interface
* demonstrates the idea of full duplexing.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
fullDuplexCall() {
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
getChannel(), getFullDuplexCallMethod(), getCallOptions());
}
/**
* <pre>
* A sequence of requests followed by a sequence of responses.
* The server buffers all the client requests and then serves them in order. A
* stream of responses are returned to the client when the server starts with
* first request.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.testing.integration.Messages.StreamingOutputCallRequest, io.grpc.testing.integration.Messages.StreamingOutputCallResponse>
halfDuplexCall() {
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
getChannel(), getHalfDuplexCallMethod(), getCallOptions());
}
/**
* <pre>
* The test server will not implement this method. It will be used
* to test the behavior when clients call unimplemented methods.
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnimplementedCallMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service TestService.
* <pre>
* A simple service to test the various types of RPCs and experiment with
* performance with various types of payload.
* </pre>
*/
public static final class TestServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<TestServiceBlockingStub> {
private TestServiceBlockingStub(

View File

@ -8,6 +8,9 @@ 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 {
@ -60,21 +63,6 @@ public final class UnimplementedServiceGrpc {
return UnimplementedServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static UnimplementedServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub>() {
@java.lang.Override
public UnimplementedServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
};
return UnimplementedServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -178,37 +166,6 @@ public final class UnimplementedServiceGrpc {
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingV2Stub> {
private UnimplementedServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected UnimplementedServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* A call that no server should implement
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnimplementedCallMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service UnimplementedService.
* <pre>
* A simple service NOT implemented at servers so clients can test for
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingStub> {
private UnimplementedServiceBlockingStub(

View File

@ -7,6 +7,9 @@ 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 {
@ -59,21 +62,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
return XdsUpdateClientConfigureServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateClientConfigureServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateClientConfigureServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateClientConfigureServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -173,36 +161,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingV2Stub> {
private XdsUpdateClientConfigureServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateClientConfigureServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Update the tes client's configuration.
* </pre>
*/
public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getConfigureMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateClientConfigureService.
* <pre>
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingStub> {
private XdsUpdateClientConfigureServiceBlockingStub(

View File

@ -7,6 +7,9 @@ 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 {
@ -89,21 +92,6 @@ public final class XdsUpdateHealthServiceGrpc {
return XdsUpdateHealthServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateHealthServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateHealthServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateHealthServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class XdsUpdateHealthServiceGrpc {
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingV2Stub> {
private XdsUpdateHealthServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateHealthServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetServingMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetNotServingMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateHealthService.
* <pre>
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingStub> {
private XdsUpdateHealthServiceBlockingStub(

View File

@ -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 22
minSdkVersion 21
targetSdkVersion 33
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions { abortOnError = true }
lintOptions { abortOnError true }
publishing {
singleVariant('release') {
withSourcesJar()
@ -31,6 +31,7 @@ android {
repositories {
google()
mavenCentral()
}
dependencies {

View File

@ -28,7 +28,6 @@ import android.util.Log;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.errorprone.annotations.InlineMe;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import io.grpc.CallOptions;
import io.grpc.ClientCall;
import io.grpc.ConnectivityState;
@ -42,6 +41,7 @@ import io.grpc.MethodDescriptor;
import io.grpc.internal.GrpcUtil;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;
/**
* Builds a {@link ManagedChannel} that, when provided with a {@link Context}, will automatically
@ -217,6 +217,7 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
connectivityManager.registerDefaultNetworkCallback(defaultNetworkCallback);
unregisterRunnable =
new Runnable() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void run() {
connectivityManager.unregisterNetworkCallback(defaultNetworkCallback);
@ -230,6 +231,7 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
context.registerReceiver(networkReceiver, networkIntentFilter);
unregisterRunnable =
new Runnable() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void run() {
context.unregisterReceiver(networkReceiver);

View File

@ -6,6 +6,7 @@ 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"),

View File

@ -47,22 +47,9 @@ dependencies {
testImplementation project(':grpc-core')
testImplementation project(':grpc-testing')
testImplementation libraries.guava.testlib
testImplementation libraries.truth
signature (libraries.signature.java) {
artifact {
extension = "signature"
}
}
signature (libraries.signature.android) {
artifact {
extension = "signature"
}
}
}
animalsniffer {
annotation = 'io.grpc.IgnoreJRERequirement'
signature libraries.signature.java
signature libraries.signature.android
}
tasks.named("javadoc").configure {

View File

@ -16,10 +16,8 @@
package io.grpc;
import static java.util.Objects.requireNonNull;
import java.util.Arrays;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@ -35,7 +33,7 @@ import java.util.concurrent.TimeUnit;
* passed to the various components unambiguously.
*/
public final class Deadline implements Comparable<Deadline> {
private static final Ticker SYSTEM_TICKER = new SystemTicker();
private static final SystemTicker 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);
@ -93,7 +91,7 @@ public final class Deadline implements Comparable<Deadline> {
* @since 1.24.0
*/
public static Deadline after(long duration, TimeUnit units, Ticker ticker) {
requireNonNull(units, "units");
checkNotNull(units, "units");
return new Deadline(ticker, units.toNanos(duration), true);
}
@ -193,8 +191,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) {
requireNonNull(task, "task");
requireNonNull(scheduler, "scheduler");
checkNotNull(task, "task");
checkNotNull(scheduler, "scheduler");
return scheduler.schedule(task, deadlineNanos - ticker.nanoTime(), TimeUnit.NANOSECONDS);
}
@ -227,27 +225,37 @@ public final class Deadline implements Comparable<Deadline> {
@Override
public int compareTo(Deadline that) {
checkTicker(that);
return Long.compare(this.deadlineNanos, that.deadlineNanos);
long diff = this.deadlineNanos - that.deadlineNanos;
if (diff < 0) {
return -1;
} else if (diff > 0) {
return 1;
}
return 0;
}
@Override
public int hashCode() {
return Objects.hash(this.ticker, this.deadlineNanos);
return Arrays.asList(this.ticker, this.deadlineNanos).hashCode();
}
@Override
public boolean equals(final Object object) {
if (object == this) {
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(object instanceof Deadline)) {
if (!(o instanceof Deadline)) {
return false;
}
final Deadline that = (Deadline) object;
if (this.ticker == null ? that.ticker != null : this.ticker != that.ticker) {
final Deadline other = (Deadline) o;
if (this.ticker == null ? other.ticker != null : this.ticker != other.ticker) {
return false;
}
return this.deadlineNanos == that.deadlineNanos;
if (this.deadlineNanos != other.deadlineNanos) {
return false;
}
return true;
}
/**
@ -267,17 +275,24 @@ public final class Deadline implements Comparable<Deadline> {
* @since 1.24.0
*/
public abstract static class Ticker {
/** Returns the number of nanoseconds elapsed since this ticker's reference point in time. */
/** Returns the number of nanoseconds since this source's epoch. */
public abstract long nanoTime();
}
private static final class SystemTicker extends Ticker {
private static 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(

View File

@ -17,18 +17,16 @@
package io.grpc;
import static com.google.common.base.Preconditions.checkArgument;
import static io.grpc.TimeUtils.convertToNanos;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.errorprone.annotations.CheckReturnValue;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
@ -178,11 +176,6 @@ public final class CallOptions {
return withDeadline(Deadline.after(duration, unit));
}
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
public CallOptions withDeadlineAfter(Duration duration) {
return withDeadlineAfter(convertToNanos(duration), TimeUnit.NANOSECONDS);
}
/**
* Returns the deadline or {@code null} if the deadline is not set.
*/

View File

@ -67,7 +67,7 @@ import javax.annotation.Nullable;
* manner, and notifies gRPC library to receive additional response after one is consumed by
* a fictional <code>processResponse()</code>.
*
* <pre>
* <p><pre>
* call = channel.newCall(bidiStreamingMethod, callOptions);
* listener = new ClientCall.Listener&lt;FooResponse&gt;() {
* &#64;Override

View File

@ -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 List<Configurator> configurators = Collections.emptyList();
private boolean configFrozen;
@GuardedBy("this")
private int configuratorsCallCountBeforeSet = 0;
private List<Configurator> configurators = Collections.emptyList();
ConfiguratorRegistry() {}
@ -56,10 +56,11 @@ final class ConfiguratorRegistry {
* @throws IllegalStateException if this method is called more than once
*/
public synchronized void setConfigurators(List<? extends Configurator> configurators) {
if (wasConfiguratorsSet) {
if (configFrozen) {
throw new IllegalStateException("Configurators are already set");
}
this.configurators = Collections.unmodifiableList(new ArrayList<>(configurators));
configFrozen = true;
wasConfiguratorsSet = true;
}
@ -67,20 +68,10 @@ final class ConfiguratorRegistry {
* Returns a list of the configurators in this registry.
*/
public synchronized List<Configurator> getConfigurators() {
if (!wasConfiguratorsSet) {
configuratorsCallCountBeforeSet++;
}
configFrozen = true;
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;
}

View File

@ -263,12 +263,6 @@ 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.

View File

@ -1,30 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* Disables Animal Sniffer's signature checking. This is our own package-private version to avoid
* dependening on animalsniffer-annotations.
*
* <p>FIELD is purposefully not supported, as Android wouldn't be able to ignore a field. Instead,
* the entire class would need to be avoided on Android.
*/
@Target({ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE})
@interface IgnoreJRERequirement {}

View File

@ -35,7 +35,7 @@ public abstract class InternalConfigSelector {
= Attributes.Key.create("internal:io.grpc.config-selector");
// Use PickSubchannelArgs for SelectConfigArgs for now. May change over time.
/** Selects the config for an RPC. */
/** Selects the config for an PRC. */
public abstract Result selectConfig(LoadBalancer.PickSubchannelArgs args);
public static final class Result {

View File

@ -48,8 +48,4 @@ public final class InternalConfiguratorRegistry {
public static boolean wasSetConfiguratorsCalled() {
return ConfiguratorRegistry.getDefaultRegistry().wasSetConfiguratorsCalled();
}
public static int getConfiguratorsCallCountBeforeSet() {
return ConfiguratorRegistry.getDefaultRegistry().getConfiguratorsCallCountBeforeSet();
}
}

View File

@ -38,11 +38,12 @@ public final class InternalStatus {
public static final Metadata.Key<Status> CODE_KEY = Status.CODE_KEY;
/**
* Create a new {@link StatusRuntimeException} skipping the filling of the stack trace.
* Create a new {@link StatusRuntimeException} with the internal option of skipping the filling
* of the stack trace.
*/
@Internal
public static StatusRuntimeException asRuntimeExceptionWithoutStacktrace(Status status,
@Nullable Metadata trailers) {
return new InternalStatusRuntimeException(status, trailers);
public static final StatusRuntimeException asRuntimeException(Status status,
@Nullable Metadata trailers, boolean fillInStackTrace) {
return new StatusRuntimeException(status, trailers, fillInStackTrace);
}
}

View File

@ -1,39 +0,0 @@
/*
* 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;
}
}

View File

@ -1,26 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import java.time.Duration;
@Internal
public final class InternalTimeUtils {
public static long convert(Duration duration) {
return TimeUtils.convertToNanos(duration);
}
}

View File

@ -212,7 +212,7 @@ public abstract class LoadBalancer {
*
* @since 1.21.0
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1771")
public static final class ResolvedAddresses {
private final List<EquivalentAddressGroup> addresses;
@NameResolver.ResolutionResultAttr
@ -452,6 +452,18 @@ 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() {}
}
/**
@ -540,7 +552,6 @@ 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,
@ -549,17 +560,6 @@ 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,19 +639,6 @@ 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)}.
*
@ -695,13 +682,6 @@ 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.
@ -756,7 +736,6 @@ public abstract class LoadBalancer {
.add("streamTracerFactory", streamTracerFactory)
.add("status", status)
.add("drop", drop)
.add("authority-override", authorityOverride)
.toString();
}
@ -1021,8 +1000,8 @@ public abstract class LoadBalancer {
}
/**
* Create an out-of-band channel for the LoadBalancers own RPC needs, e.g., talking to an
* external load-balancer service.
* Out-of-band channel for LoadBalancers 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}.
@ -1032,12 +1011,7 @@ public abstract class LoadBalancer {
public abstract ManagedChannel createOobChannel(EquivalentAddressGroup eag, String authority);
/**
* 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}.
* Accept a list of EAG for multiple authorities: https://github.com/grpc/grpc-java/issues/4618
* */
public ManagedChannel createOobChannel(List<EquivalentAddressGroup> eag,
String authority) {
@ -1189,10 +1163,6 @@ 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.

View File

@ -633,23 +633,6 @@ 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.

View File

@ -18,7 +18,6 @@ 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;
@ -31,6 +30,7 @@ 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;
/**

View File

@ -22,8 +22,6 @@ 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;
@ -34,6 +32,8 @@ 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 = Sets.newHashSetWithExpectedSize(size);
Set<String> ks = new HashSet<>(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 = Maps.newHashMapWithExpectedSize(keys.size());
Map<ByteBuffer, Key<?>> asciiKeys = new HashMap<>(keys.size());
for (Key<?> key : keys) {
asciiKeys.put(ByteBuffer.wrap(key.asciiName()), key);
}

View File

@ -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;

View File

@ -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.

View File

@ -28,13 +28,11 @@ 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;
/**
@ -239,9 +237,6 @@ 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
*/
@ -251,10 +246,6 @@ 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
*/
@ -262,14 +253,9 @@ public abstract class NameResolver {
public abstract void onError(Status error);
/**
* 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.
* Handles updates on resolved addresses and attributes.
*
* @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.
* @param resolutionResult the resolved server addresses, attributes, and Service Config.
* @since 1.66
*/
public Status onResult2(ResolutionResult resolutionResult) {
@ -287,20 +273,10 @@ 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>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()}.
* <p>Note this class doesn't override neither {@code equals()} nor {@code hashCode()}.
*
* @since 1.21.0
*/
@ -314,23 +290,24 @@ 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(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);
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;
}
/**
@ -339,7 +316,6 @@ 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;
}
@ -392,30 +368,6 @@ 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.
*
@ -453,26 +405,6 @@ 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() {
@ -481,13 +413,10 @@ 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();
}
@ -506,9 +435,6 @@ 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;
}
@ -535,9 +461,6 @@ 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() {
}
@ -624,75 +547,16 @@ 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(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);
return
new Args(
defaultPort, proxyDetector, syncContext, serviceConfigParser,
scheduledExecutorService, channelLogger, executor, overrideAuthority);
}
}
}
@ -990,10 +854,4 @@ 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;
}
}

View File

@ -20,7 +20,6 @@ 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;
@ -32,6 +31,7 @@ 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,11 +166,6 @@ 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);
}

View File

@ -18,7 +18,6 @@ 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;
@ -26,6 +25,7 @@ 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;
/**

View File

@ -23,7 +23,6 @@ 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;
@ -31,6 +30,7 @@ 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;

View File

@ -44,7 +44,12 @@ public class StatusException extends Exception {
* @since 1.0.0
*/
public StatusException(Status status, @Nullable Metadata trailers) {
super(Status.formatThrowableMessage(status), status.getCause());
this(status, trailers, /*fillInStackTrace=*/ true);
}
StatusException(Status status, @Nullable Metadata trailers, boolean fillInStackTrace) {
super(Status.formatThrowableMessage(status), status.getCause(),
/* enableSuppression */ true, /* writableStackTrace */fillInStackTrace);
this.status = status;
this.trailers = trailers;
}

View File

@ -66,14 +66,6 @@ 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)) {

View File

@ -45,7 +45,12 @@ public class StatusRuntimeException extends RuntimeException {
* @since 1.0.0
*/
public StatusRuntimeException(Status status, @Nullable Metadata trailers) {
super(Status.formatThrowableMessage(status), status.getCause());
this(status, trailers, /*fillInStackTrace=*/ true);
}
StatusRuntimeException(Status status, @Nullable Metadata trailers, boolean fillInStackTrace) {
super(Status.formatThrowableMessage(status), status.getCause(),
/* enable suppressions */ true, /* writableStackTrace */ fillInStackTrace);
this.status = status;
this.trailers = trailers;
}

View File

@ -18,10 +18,8 @@ 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;
@ -164,12 +162,6 @@ 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.
@ -201,14 +193,6 @@ 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;
@ -262,4 +246,4 @@ public final class SynchronizationContext implements Executor {
return !(runnable.hasStarted || runnable.isCancelled);
}
}
}
}

View File

@ -1,32 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import java.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;
}
}
}

View File

@ -32,7 +32,6 @@ 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;
@ -151,15 +150,6 @@ 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

View File

@ -85,12 +85,14 @@ public class ConfiguratorRegistryTest {
@Override
public void run() {
assertThat(ConfiguratorRegistry.getDefaultRegistry().getConfigurators()).isEmpty();
NoopConfigurator noopConfigurator = new NoopConfigurator();
ConfiguratorRegistry.getDefaultRegistry()
.setConfigurators(Arrays.asList(noopConfigurator));
assertThat(ConfiguratorRegistry.getDefaultRegistry().getConfigurators())
.containsExactly(noopConfigurator);
assertThat(InternalConfiguratorRegistry.getConfiguratorsCallCountBeforeSet()).isEqualTo(1);
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");
}
}
}

View File

@ -16,7 +16,6 @@
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;
@ -25,7 +24,6 @@ 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;
@ -39,7 +37,9 @@ 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,6 +49,9 @@ 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
@ -62,7 +65,7 @@ public class MetadataTest {
}
};
private static class FishStreamMarshaller implements Metadata.BinaryStreamMarshaller<Fish> {
private static class FishStreamMarsaller implements Metadata.BinaryStreamMarshaller<Fish> {
@Override
public InputStream toStream(Fish fish) {
return new ByteArrayInputStream(FISH_MARSHALLER.toBytes(fish));
@ -79,7 +82,7 @@ public class MetadataTest {
}
private static final Metadata.BinaryStreamMarshaller<Fish> FISH_STREAM_MARSHALLER =
new FishStreamMarshaller();
new FishStreamMarsaller();
/** A pattern commonly used to avoid unnecessary serialization of immutable objects. */
private static final class FakeFishStream extends InputStream {
@ -118,9 +121,10 @@ public class MetadataTest {
@Test
public void noPseudoHeaders() {
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
() -> Metadata.Key.of(":test-bin", FISH_MARSHALLER));
assertThat(e).hasMessageThat().isEqualTo("Invalid character ':' in key name ':test-bin'");
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Invalid character");
Metadata.Key.of(":test-bin", FISH_MARSHALLER);
}
@Test
@ -182,7 +186,8 @@ public class MetadataTest {
Iterator<Fish> i = metadata.getAll(KEY).iterator();
assertEquals(lance, i.next());
assertThrows(UnsupportedOperationException.class, i::remove);
thrown.expect(UnsupportedOperationException.class);
i.remove();
}
@Test
@ -266,15 +271,17 @@ public class MetadataTest {
@Test
public void shortBinaryKeyName() {
assertThrows(IllegalArgumentException.class, () -> Metadata.Key.of("-bin", FISH_MARSHALLER));
thrown.expect(IllegalArgumentException.class);
Metadata.Key.of("-bin", FISH_MARSHALLER);
}
@Test
public void invalidSuffixBinaryKeyName() {
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");
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Binary header is named");
Metadata.Key.of("nonbinary", FISH_MARSHALLER);
}
@Test
@ -408,7 +415,7 @@ public class MetadataTest {
h.put(KEY_STREAMED, salmon);
// Get using a different marshaller instance.
Fish fish = h.get(copyKey(KEY_STREAMED, new FishStreamMarshaller()));
Fish fish = h.get(copyKey(KEY_STREAMED, new FishStreamMarsaller()));
assertEquals(salmon, fish);
}

View File

@ -26,7 +26,9 @@ 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;
@ -35,6 +37,10 @@ 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()

View File

@ -47,13 +47,9 @@ 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_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 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 ConfigOrError CONFIG = ConfigOrError.fromConfig("foo");
@Rule
@ -68,8 +64,6 @@ 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
@ -83,9 +77,6 @@ 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);
@ -96,9 +87,6 @@ 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);
@ -114,8 +102,6 @@ public class NameResolverTest {
.setChannelLogger(channelLogger)
.setOffloadExecutor(executor)
.setOverrideAuthority(overrideAuthority)
.setMetricRecorder(metricRecorder)
.setArg(FOO_ARG_KEY, customArgValue)
.build();
}

View File

@ -19,7 +19,6 @@ 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;
@ -41,6 +40,7 @@ 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,6 +55,10 @@ 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;
@ -107,21 +111,21 @@ public class ServerInterceptorsTest {
public void npeForNullServiceDefinition() {
ServerServiceDefinition serviceDef = null;
List<ServerInterceptor> interceptors = Arrays.asList();
assertThrows(NullPointerException.class,
() -> ServerInterceptors.intercept(serviceDef, interceptors));
thrown.expect(NullPointerException.class);
ServerInterceptors.intercept(serviceDef, interceptors);
}
@Test
public void npeForNullInterceptorList() {
assertThrows(NullPointerException.class,
() -> ServerInterceptors.intercept(serviceDefinition, (List<ServerInterceptor>) null));
thrown.expect(NullPointerException.class);
ServerInterceptors.intercept(serviceDefinition, (List<ServerInterceptor>) null);
}
@Test
public void npeForNullInterceptor() {
List<ServerInterceptor> interceptors = Arrays.asList((ServerInterceptor) null);
assertThrows(NullPointerException.class,
() -> ServerInterceptors.intercept(serviceDefinition, interceptors));
thrown.expect(NullPointerException.class);
ServerInterceptors.intercept(serviceDefinition, interceptors);
}
@Test

View File

@ -18,13 +18,14 @@ 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;
@ -51,6 +52,9 @@ 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() {
@ -87,7 +91,9 @@ public class ServerServiceDefinitionTest {
ServiceDescriptor sd = new ServiceDescriptor(serviceName, method1);
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd)
.addMethod(method1, methodHandler1);
assertThrows(IllegalStateException.class, () -> ssd.addMethod(diffMethod1, methodHandler2));
thrown.expect(IllegalStateException.class);
ssd.addMethod(diffMethod1, methodHandler2)
.build();
}
@Test
@ -95,7 +101,8 @@ public class ServerServiceDefinitionTest {
ServiceDescriptor sd = new ServiceDescriptor(serviceName);
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd)
.addMethod(methodDef1);
assertThrows(IllegalStateException.class, ssd::build);
thrown.expect(IllegalStateException.class);
ssd.build();
}
@Test
@ -103,14 +110,16 @@ public class ServerServiceDefinitionTest {
ServiceDescriptor sd = new ServiceDescriptor(serviceName, method1);
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd)
.addMethod(diffMethod1, methodHandler1);
assertThrows(IllegalStateException.class, ssd::build);
thrown.expect(IllegalStateException.class);
ssd.build();
}
@Test
public void buildMisaligned_missingMethod() {
ServiceDescriptor sd = new ServiceDescriptor(serviceName, method1);
ServerServiceDefinition.Builder ssd = ServerServiceDefinition.builder(sd);
assertThrows(IllegalStateException.class, ssd::build);
thrown.expect(IllegalStateException.class);
ssd.build();
}
@Test

View File

@ -16,18 +16,17 @@
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;
@ -37,27 +36,32 @@ 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() {
List<MethodDescriptor<?, ?>> methods = Collections.emptyList();
NullPointerException e = assertThrows(NullPointerException.class,
() -> new ServiceDescriptor(null, methods));
assertThat(e).hasMessageThat().isEqualTo("name");
thrown.expect(NullPointerException.class);
thrown.expectMessage("name");
new ServiceDescriptor(null, Collections.<MethodDescriptor<?, ?>>emptyList());
}
@Test
public void failsOnNullMethods() {
NullPointerException e = assertThrows(NullPointerException.class,
() -> new ServiceDescriptor("name", (Collection<MethodDescriptor<?, ?>>) null));
assertThat(e).hasMessageThat().isEqualTo("methods");
thrown.expect(NullPointerException.class);
thrown.expectMessage("methods");
new ServiceDescriptor("name", (Collection<MethodDescriptor<?, ?>>) null);
}
@Test
public void failsOnNullMethod() {
List<MethodDescriptor<?, ?>> methods = Collections.singletonList(null);
NullPointerException e = assertThrows(NullPointerException.class,
() -> new ServiceDescriptor("name", methods));
assertThat(e).hasMessageThat().isEqualTo("method");
thrown.expect(NullPointerException.class);
thrown.expectMessage("method");
new ServiceDescriptor("name", Collections.<MethodDescriptor<?, ?>>singletonList(null));
}
@Test
@ -65,17 +69,15 @@ 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());
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
() -> new ServiceDescriptor("fooService", descriptors));
StringSubject error = assertThat(e).hasMessageThat();
error.contains("service names");
error.contains("fooService");
error.contains("wrongService");
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("service names");
new ServiceDescriptor("name", descriptors);
}
@Test
@ -94,9 +96,10 @@ public class ServiceDescriptorTest {
.setResponseMarshaller(TestMethodDescriptors.voidMarshaller())
.build());
IllegalArgumentException e = assertThrows(IllegalArgumentException.class,
() -> new ServiceDescriptor("name", descriptors));
assertThat(e).hasMessageThat().isEqualTo("duplicate name name/method");
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("duplicate");
new ServiceDescriptor("name", descriptors);
}
@Test

View File

@ -28,6 +28,14 @@ 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 =

View File

@ -31,7 +31,7 @@ public class StatusRuntimeExceptionTest {
@Test
public void internalCtorRemovesStack() {
StackTraceElement[] trace =
new InternalStatusRuntimeException(Status.CANCELLED, null) {}.getStackTrace();
new StatusRuntimeException(Status.CANCELLED, null, false) {}.getStackTrace();
assertThat(trace).isEmpty();
}

View File

@ -27,7 +27,6 @@ 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;
@ -73,7 +72,7 @@ public class SynchronizationContextTest {
@Mock
private Runnable task3;
@After public void tearDown() {
assertThat(uncaughtErrors).isEmpty();
}
@ -247,43 +246,6 @@ 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();
@ -395,13 +357,5 @@ 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);
}
}
}

View File

@ -1,60 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import 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));
}
}

View File

@ -1,118 +0,0 @@
/*
* 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;
}
}
}

View File

@ -1,66 +0,0 @@
/*
* 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 + "}";
}
}
}

View File

@ -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", actualNanos / NANOSECONDS_IN_A_SECOND),
fact("but was", expectedNanos / NANOSECONDS_IN_A_SECOND),
fact("outside tolerance in seconds", deltaNanos / NANOSECONDS_IN_A_SECOND));
}
}

View File

@ -22,14 +22,6 @@ dependencies {
project(':grpc-core'),
project(":grpc-context"), // Override google-auth dependency with our newer version
libraries.google.auth.oauth2Http
signature (libraries.signature.java) {
artifact {
extension = "signature"
}
}
signature (libraries.signature.android) {
artifact {
extension = "signature"
}
}
signature libraries.signature.java
signature libraries.signature.android
}

View File

@ -50,12 +50,10 @@ 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.PrivateKey;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@ -344,10 +342,7 @@ public class GoogleAuthLibraryCallCredentialsTest {
@Test
public void serviceAccountToJwt() throws Exception {
PrivateKey privateKey;
try (InputStream server1Key = TlsTesting.loadCert("server1.key")) {
privateKey = CertificateUtils.getPrivateKey(server1Key);
}
KeyPair pair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
HttpTransportFactory factory = Mockito.mock(HttpTransportFactory.class);
Mockito.when(factory.create()).thenThrow(new AssertionError());
@ -355,7 +350,7 @@ public class GoogleAuthLibraryCallCredentialsTest {
ServiceAccountCredentials credentials =
ServiceAccountCredentials.newBuilder()
.setClientEmail("test-email@example.com")
.setPrivateKey(privateKey)
.setPrivateKey(pair.getPrivate())
.setPrivateKeyId("test-private-key-id")
.setHttpTransportFactory(factory)
.build();
@ -395,16 +390,13 @@ public class GoogleAuthLibraryCallCredentialsTest {
@Test
public void jwtAccessCredentialsInRequestMetadata() throws Exception {
PrivateKey privateKey;
try (InputStream server1Key = TlsTesting.loadCert("server1.key")) {
privateKey = CertificateUtils.getPrivateKey(server1Key);
}
KeyPair pair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
ServiceAccountCredentials credentials =
ServiceAccountCredentials.newBuilder()
.setClientId("test-client")
.setClientEmail("test-email@example.com")
.setPrivateKey(privateKey)
.setPrivateKey(pair.getPrivate())
.setPrivateKeyId("test-private-key-id")
.setQuotaProjectId("test-quota-project-id")
.build();

View File

@ -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,11 +26,7 @@ dependencies {
shadow configurations.implementation.getDependencies().minus([xdsDependency])
shadow project(path: ':grpc-xds', configuration: 'shadow')
signature (libraries.signature.java) {
artifact {
extension = "signature"
}
}
signature libraries.signature.java
}
tasks.named("jar").configure {

View File

@ -43,11 +43,7 @@ dependencies {
testImplementation libraries.junit,
libraries.mockito.core
signature (libraries.signature.java) {
artifact {
extension = "signature"
}
}
signature libraries.signature.java
}
import net.ltgt.gradle.errorprone.CheckSeverity

View File

@ -4,6 +4,9 @@ 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 {
@ -181,21 +184,6 @@ 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
*/
@ -379,87 +367,6 @@ 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(

View File

@ -4,6 +4,9 @@ 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 {
@ -57,21 +60,6 @@ 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
*/
@ -159,33 +147,6 @@ 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(

View File

@ -4,6 +4,9 @@ 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 {
@ -150,21 +153,6 @@ 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
*/
@ -335,77 +323,6 @@ 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(

View File

@ -6,32 +6,33 @@ plugins {
description = 'gRPC BinderChannel'
android {
namespace = 'io.grpc.binder'
namespace 'io.grpc.binder'
compileSdkVersion 34
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
defaultConfig {
minSdkVersion 22
minSdkVersion 21
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 {
@ -72,7 +73,6 @@ dependencies {
androidTestImplementation testFixtures(project(':grpc-core'))
testFixturesImplementation libraries.guava.testlib
testFixturesImplementation testFixtures(project(':grpc-core'))
}
import net.ltgt.gradle.errorprone.CheckSeverity

View File

@ -11,13 +11,11 @@
<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>

View File

@ -23,7 +23,6 @@ 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;
@ -40,6 +39,7 @@ 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,6 +49,7 @@ 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;
@ -76,6 +77,7 @@ 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);
@ -97,6 +99,7 @@ public final class BinderChannelSmokeTest {
.setType(MethodDescriptor.MethodType.BIDI_STREAMING)
.build();
FakeNameResolverProvider fakeNameResolverProvider;
ManagedChannel channel;
AtomicReference<Metadata> headersCapture = new AtomicReference<>();
AtomicReference<PeerUid> clientUidCapture = new AtomicReference<>();
@ -135,6 +138,8 @@ 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()
@ -161,6 +166,7 @@ public final class BinderChannelSmokeTest {
@After
public void tearDown() throws Exception {
channel.shutdownNow();
NameResolverRegistry.getDefaultRegistry().deregister(fakeNameResolverProvider);
HostServices.awaitServiceShutdown();
}
@ -229,11 +235,7 @@ public final class BinderChannelSmokeTest {
@Test
public void testConnectViaTargetUri() throws Exception {
// Compare with the <intent-filter> mapping in AndroidManifest.xml.
channel =
BinderChannelBuilder.forTarget(
"intent://authority/path#Intent;action=action1;scheme=scheme;end;", appContext)
.build();
channel = BinderChannelBuilder.forTarget(SERVER_TARGET_URI, appContext).build();
assertThat(doCall("Hello").get()).isEqualTo("Hello");
}
@ -243,10 +245,7 @@ public final class BinderChannelSmokeTest {
channel =
BinderChannelBuilder.forAddress(
AndroidComponentAddress.forBindIntent(
new Intent()
.setAction("action1")
.setData(Uri.parse("scheme://authority/path"))
.setPackage(appContext.getPackageName())),
new Intent().setAction("action1").setPackage(appContext.getPackageName())),
appContext)
.build();
assertThat(doCall("Hello").get()).isEqualTo("Hello");

View File

@ -29,7 +29,6 @@ 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;
@ -39,6 +38,7 @@ 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.

View File

@ -17,7 +17,6 @@
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;
@ -25,9 +24,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;
@ -38,13 +37,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;
@ -63,7 +62,9 @@ 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;
@ -100,7 +101,7 @@ public final class BinderClientTransportTest {
.build();
AndroidComponentAddress serverAddress;
BinderClientTransport transport;
BinderTransport.BinderClientTransport transport;
BlockingSecurityPolicy blockingSecurityPolicy = new BlockingSecurityPolicy();
private final ObjectPool<ScheduledExecutorService> executorServicePool =
@ -153,32 +154,23 @@ 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;
}
@CanIgnoreReturnValue
public BinderClientTransportBuilder setPreAuthorizeServer(boolean preAuthorizeServer) {
factoryBuilder.setPreAuthorizeServers(preAuthorizeServer);
return this;
}
public BinderClientTransport build() {
public BinderTransport.BinderClientTransport build() {
return factoryBuilder
.buildClientTransportFactory()
.newClientTransport(serverAddress, new ClientTransportOptions(), null);
@ -197,7 +189,7 @@ public final class BinderClientTransportTest {
private static void shutdownAndTerminate(ExecutorService executorService)
throws InterruptedException {
executorService.shutdownNow();
if (!executorService.awaitTermination(TIMEOUT_SECONDS, SECONDS)) {
if (!executorService.awaitTermination(TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
throw new AssertionError("executor failed to terminate promptly");
}
}
@ -378,131 +370,47 @@ public final class BinderClientTransportTest {
}
@Test
public void testBlackHoleSecurityPolicyAuthTimeout() throws Exception {
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
public void testBlackHoleSecurityPolicyConnectTimeout() throws Exception {
transport =
new BinderClientTransportBuilder()
.setSecurityPolicy(securityPolicy)
.setPreAuthorizeServer(false)
.setSecurityPolicy(blockingSecurityPolicy)
.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();
// If the transport gave up waiting on auth, it should cancel its request.
assertThat(authRequest.isCancelled()).isTrue();
blockingSecurityPolicy.provideNextCheckAuthorizationResult(Status.OK);
}
@Test
public void testBlackHoleSecurityPolicyPreAuthTimeout() throws Exception {
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
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);
transportListener.awaitTermination();
}
@Test
public void testAsyncSecurityPolicyPreAuthFailure() throws Exception {
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
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.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 {
public void testAsyncSecurityPolicyFailure() throws Exception {
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
transport = new BinderClientTransportBuilder().setSecurityPolicy(securityPolicy).build();
RuntimeException exception = new NullPointerException();
securityPolicy.setAuthorizationException(exception);
transport.start(transportListener).run();
AuthRequest authRequest = securityPolicy.takeNextAuthRequest(TIMEOUT_SECONDS, SECONDS);
transport.shutdownNow(Status.UNAVAILABLE); // 'authRequest' remains unanswered!
transportListener.awaitShutdown();
Status transportStatus = transportListener.awaitShutdown();
assertThat(transportStatus.getCode()).isEqualTo(Code.INTERNAL);
assertThat(transportStatus.getCause()).isEqualTo(exception);
transportListener.awaitTermination();
}
@Test
public void testAsyncSecurityPolicySuccess() throws Exception {
SettableAsyncSecurityPolicy securityPolicy = new SettableAsyncSecurityPolicy();
transport = new BinderClientTransportBuilder().setSecurityPolicy(securityPolicy).build();
securityPolicy.setAuthorizationResult(Status.PERMISSION_DENIED);
transport.start(transportListener).run();
Status transportStatus = transportListener.awaitShutdown();
assertThat(transportStatus.getCode()).isEqualTo(Code.PERMISSION_DENIED);
transportListener.awaitTermination();
assertThat(authRequest.isCancelled()).isTrue();
}
private static void startAndAwaitReady(
BinderClientTransport transport, TestTransportListener transportListener) throws Exception {
BinderTransport.BinderClientTransport transport, TestTransportListener transportListener)
throws Exception {
transport.start(transportListener).run();
transportListener.awaitReady();
}
@ -521,7 +429,7 @@ public final class BinderClientTransportTest {
}
public Status awaitShutdown() throws Exception {
return shutdownStatus.get(TIMEOUT_SECONDS, SECONDS);
return shutdownStatus.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
}
@Override
@ -532,7 +440,7 @@ public final class BinderClientTransportTest {
}
public void awaitTermination() throws Exception {
isTerminated.get(TIMEOUT_SECONDS, SECONDS);
isTerminated.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
}
@Override
@ -543,7 +451,7 @@ public final class BinderClientTransportTest {
}
public void awaitReady() throws Exception {
isReady.get(TIMEOUT_SECONDS, SECONDS);
isReady.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
}
@Override
@ -659,4 +567,25 @@ 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);
}
}
}

View File

@ -106,7 +106,8 @@ public final class BinderTransportTest extends AbstractTransportTest {
options.setEagAttributes(eagAttrs());
options.setChannelLogger(transportLogger());
return new BinderClientTransport(builder.buildClientTransportFactory(), addr, options);
return new BinderTransport.BinderClientTransport(
builder.buildClientTransportFactory(), addr, options);
}
@Test

View File

@ -18,14 +18,10 @@ 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;
@ -45,25 +41,18 @@ import javax.annotation.Nullable;
* fields, namely, an action of {@link ApiConstants#ACTION_BIND}, an empty category set and null
* type and data URI.
*
* <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.
* <p>The semantics of {@link #equals(Object)} are the same as {@link Intent#filterEquals(Intent)}.
*/
public final class AndroidComponentAddress extends SocketAddress {
private static final long serialVersionUID = 0L;
private final Intent bindIntent; // "Explicit", having either a component or package restriction.
@Nullable
private final UserHandle targetUser; // null means the same user that hosts this process.
private AndroidComponentAddress(Intent bindIntent, @Nullable UserHandle targetUser) {
protected AndroidComponentAddress(Intent bindIntent) {
checkArgument(
bindIntent.getComponent() != null || bindIntent.getPackage() != null,
"'bindIntent' must be explicit. Specify either a package or ComponentName.");
this.bindIntent = bindIntent;
this.targetUser = targetUser;
}
/**
@ -110,7 +99,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(), null);
return new AndroidComponentAddress(intent.cloneFilter());
}
/**
@ -119,7 +108,7 @@ public final class AndroidComponentAddress extends SocketAddress {
*/
public static AndroidComponentAddress forComponent(ComponentName component) {
return new AndroidComponentAddress(
new Intent(ApiConstants.ACTION_BIND).setComponent(component), null);
new Intent(ApiConstants.ACTION_BIND).setComponent(component));
}
/**
@ -152,9 +141,6 @@ 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.
@ -191,92 +177,13 @@ public final class AndroidComponentAddress extends SocketAddress {
public boolean equals(Object obj) {
if (obj instanceof AndroidComponentAddress) {
AndroidComponentAddress that = (AndroidComponentAddress) obj;
return bindIntent.filterEquals(that.bindIntent)
&& Objects.equal(this.targetUser, that.targetUser);
return bindIntent.filterEquals(that.bindIntent);
}
return false;
}
@Override
public String toString() {
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 &#064;SystemApi's and hold certain &#064;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 &#064;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);
}
return "AndroidComponentAddress[" + bindIntent + "]";
}
}

View File

@ -17,11 +17,7 @@
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")
@ -33,43 +29,4 @@ 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");
}

View File

@ -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,25 +67,4 @@ 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());
}
}

View File

@ -236,28 +236,20 @@ public final class BinderChannelBuilder extends ForwardingChannelBuilder<BinderC
}
/**
* Specifies the {@link UserHandle} to be searched for the remote Android Service by default.
* Provides the target {@UserHandle} of the remote Android service.
*
* <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>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>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.setDefaultTargetUserHandle(targetUserHandle);
transportFactoryBuilder.setTargetUserHandle(targetUserHandle);
return this;
}
@ -279,35 +271,6 @@ 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(
@ -321,8 +284,6 @@ public final class BinderChannelBuilder extends ForwardingChannelBuilder<BinderC
public ManagedChannel build() {
transportFactoryBuilder.setOffloadExecutorPool(
managedChannelImplBuilder.getOffloadExecutorPool());
setNameResolverArg(
ApiConstants.SOURCE_ANDROID_CONTEXT, transportFactoryBuilder.getSourceContext());
return super.build();
}
}

View File

@ -184,6 +184,7 @@ 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);
@ -198,6 +199,7 @@ 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);

View File

@ -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,25 +53,4 @@ 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());
}
}

View File

@ -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