Compare commits

..

21 Commits

Author SHA1 Message Date
larry-safran 56d1c63802 Bump version to 1.54.1 2023-04-14 15:42:30 -07:00
larry-safran 4a5605cea3 Update README etc to reference 1.54.1 2023-04-14 14:57:17 -07:00
Eric Anderson 4b01c907bc core: Fix NPE race during hedging
The problem was one hedge was committed before another had drained
start(). This was not testable because HedgingRunnable checks whether
scheduledHedgingRef is cancelled, which is racy, but there's no way to
deterministically trigger either race.

The same problem couldn't be triggered with retries because only one
attempt will be draining at a time. Retries with cancellation also
couldn't trigger it, for the surprising reason that the noop stream used
in cancel() wasn't considered drained.

This commit marks the noop stream as drained with cancel(), which allows
memory to be garbage collected sooner and exposes the race for tests.
That then showed the stream as hanging, because inFlightSubStreams
wasn't being decremented.

Fixes #9185
2023-04-13 10:10:36 -07:00
DNVindhya 92b4faed40
Pass interop parameters to each langs run.sh as-is. run.sh should just pass through to the interop client/server binaries (#10042)
Co-authored-by: Stanley Cheung <stanleycheung@google.com>
2023-04-12 11:56:24 -07:00
DNVindhya 1bf518af12 gcp-o11y: Remove monitored resource detection for logging (#10020)
* removed populating monitored resource to k8s_conatiner by default for logging; Delegating the resource detection to cloud logging library instead (enabled by default)

* remove kubernetes resource detection logic from observability
2023-04-07 07:24:33 -07:00
Vindhya Ningegowda 5369df13a5 Removes the ExperimentalApi annotation from GcpObservability. 2023-04-07 07:24:11 -07:00
DNVindhya 6d21d71a25 use glob for example file names which is used in updating release versions (#9998) 2023-04-04 07:46:06 -07:00
Eric Anderson e955afe50a examples: Fix grpc version in gcp-observability
gcp-observability was missing from RELEASING.md, so it wasn't updated
when we changed the patch release.
2023-04-04 07:45:47 -07:00
yifeizhuang 5c09616aae
xds: fix flaky wrr test (#10005) 2023-04-03 11:27:32 -07:00
Terry Wilson 7d5d25d34e Bump version to 1.54.1-SNAPSHOT 2023-03-23 11:11:14 -07:00
Terry Wilson e988f84d14 Bump version to 1.54.0 2023-03-23 10:53:48 -07:00
Terry Wilson abdb6980ec Update README etc to reference 1.54.0 2023-03-23 10:16:45 -07:00
Stanley Cheung 61ec299352 Remove sleep from Observability Interop Test binary now that its done in close() (#9977)
After #9972, the `sleep()` is done inside Observability `close()`, we can remove this `sleep()` in the Observability Interop test binary.
2023-03-23 09:15:10 -07:00
DNVindhya 9f26b7dd08 gcp-o11y: add default custom tag for metrics exporter
This PR adds a default custom tag for metrics, irrespective of custom
tags being present in the observability configuration. 

OpenCensus by default adds a custom tag
[opencenus_task](https://docs.google.com/document/d/1sWC-XD277cM0PXxAhzJKY2X0Uj2W7bVoSv-jvnA0N8Q/edit?resourcekey=0-l-wqh1fctxZXHCUrvZv2BQ#heading=h.xy85j580eik0)
for metrics which gets overriden if custom tags are set.

The unique custom tag is required to ensure the uniqueness of the
Timeseries. The format of the default custom tag is:
`java-{PID}@{HOSTNAME}`, if `{PID}` is not available a random number
will be used.
2023-03-23 08:15:27 -07:00
DNVindhya fefa2d9b16
examples: add gcp-observability examples (v1.54.x backport) (#9987)
* examples: add gcp-observability examples (#9967)
2023-03-22 23:18:49 -07:00
DNVindhya 882a27bcb6 gcp-o11y: add sleep in Observability close()
This commit adds sleep in `close()` for metrics and/or traces to be
flushed before closing observability.

Currently sleep is set to 2 * [Metrics export interval (30 secs)].
2023-03-22 15:08:02 -07:00
Vindhya Ningegowda 2e41c9a5cb disable recording real-time metrics using in gcp-o11y 2023-03-22 15:05:58 -07:00
Stanley Cheung 132bf3e573 interop-testing: Do not System.exit(0) from interop client
After #9937 was merged, the Java observability tests start to fail.

This System.exit(0) call in the existing Interop client main() method
prevented execution to continue in the new combined Observability
Interop test binary here. (The new binary is calling the old binary's
main() method.)
2023-03-21 16:16:41 -07:00
DNVindhya 85ce900dfc gcp-observability, census: add trace information to logs (#9963)
This commit adds trace information (TraceId, SpanId and TraceSampled)
fields to LogEntry, when both logging and tracing are enabled in
gcp-observability. 

For server-side logs, span information was readily available using
Span.getContext() propagated via `io.grpc.Context`. Similar approach is
not feasible for client-side architecture.

Client SpanContext which has all the information required to be added
to logs is propagated to the logging interceptor via `io.grpc.CallOptions`.
2023-03-21 15:01:21 -07:00
DNVindhya bb39ca3ec9 gcp-observability: Update logging fields for GA and use custom BatchingSettings (#9959)
This commit updates the following in gcp observability logging schema
* `payload.status_code` will be of type `google.rpc.Code` instead of `uint32`.
*  names in enum `Address.TYPE`

Use custom batching settings for [LoggingOptions](https://javadoc.io/doc/com.google.cloud/google-cloud-logging/latest/com/google/cloud/logging/LoggingOptions.html)

Note: Upgraded `com.google.cloud:google-cloud-logging` from `3.6.1` to `3.14.5`.
2023-03-21 08:40:02 -07:00
DNVindhya 051e3971de census: Trace annotation for reporting inbound message sizes (#9944)
This commit uses [OpenCensus Annotation][] to report message size
[bytes] for inbound/received messages in traces.

`addMessageEvent` API which is currently used expects both uncompressed
and compressed message (optional) sizes to be reported at the same.
Since decompression for messages happens at a later point in time,
reporting compressed message as is and reporting uncompressed size as
`-1` renders the size as _0 bytes received_ in cloud tracing front end.

As a workaround, we add _two annotations for each received message_:
* For compressed message size
* For uncompressed message size (when it is available)

This commit also removes `addMessageEvents` a flag introduced in
PR #9485 to temporarily suppress message events for gcp-observability.

[OpenCensus Annotation]: https://www.javadoc.io/static/io.opencensus/opencensus-api/0.31.0/io/opencensus/trace/Annotation.html
2023-03-13 15:45:17 -07:00
1462 changed files with 38155 additions and 97160 deletions

View File

@ -1 +0,0 @@
build --cxxopt=-std=c++14 --host_cxxopt=-std=c++14

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

@ -9,5 +9,5 @@ jobs:
name: "Gradle wrapper validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v4
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1

View File

@ -13,7 +13,7 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
- uses: dessant/lock-threads@v4
with:
github-token: ${{ github.token }}
issue-inactive-days: 90

View File

@ -17,18 +17,18 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
jre: [8, 11, 17]
jre: [8, 11]
fail-fast: false # Should swap to true if we grow a large matrix
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
with:
java-version: ${{ matrix.jre }}
distribution: 'temurin'
- name: Gradle cache
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
@ -37,7 +37,7 @@ jobs:
restore-keys: |
${{ runner.os }}-gradle-
- name: Maven cache
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: |
~/.m2/repository
@ -46,7 +46,7 @@ jobs:
restore-keys: |
${{ runner.os }}-maven-
- name: Protobuf cache
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: /tmp/protobuf-cache
key: ${{ runner.os }}-maven-${{ hashFiles('buildscripts/make_dependencies.sh') }}
@ -55,56 +55,16 @@ jobs:
run: buildscripts/kokoro/unix.sh
- name: Post Failure Upload Test Reports to Artifacts
if: ${{ failure() }}
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v3
with:
name: Test Reports (JRE ${{ matrix.jre }})
path: |
./*/build/reports/tests/**
./*/*/build/reports/tests/**
path: ./*/build/reports/tests/**
retention-days: 14
- name: Check for modified codegen
run: test -z "$(git status --porcelain)" || (git status && echo Error Working directory is not clean. Forget to commit generated files? && false)
- name: Coveralls
if: matrix.jre == 8 # Upload once, instead of for each job in the matrix
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
run: ./gradlew :grpc-all:coveralls -PskipAndroid=true -x compileJava
run: ./gradlew :grpc-all:coveralls -x compileJava
- name: Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
bazel:
runs-on: ubuntu-latest
strategy:
matrix:
bzlmod: [true, false]
env:
USE_BAZEL_VERSION: 7.0.0
steps:
- uses: actions/checkout@v4
- name: Check versions match in MODULE.bazel and repositories.bzl
run: |
diff -u <(sed -n '/GRPC_DEPS_START/,/GRPC_DEPS_END/ {/GRPC_DEPS_/! p}' MODULE.bazel) \
<(sed -n '/GRPC_DEPS_START/,/GRPC_DEPS_END/ {/GRPC_DEPS_/! p}' repositories.bzl)
- name: Bazel cache
uses: actions/cache@v4
with:
path: |
~/.cache/bazel/*/cache
~/.cache/bazelisk/downloads
key: ${{ runner.os }}-bazel-${{ env.USE_BAZEL_VERSION }}-${{ hashFiles('WORKSPACE', 'repositories.bzl') }}
- name: Run bazel build
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }}
- name: Run bazel test
run: bazelisk test //... --enable_bzlmod=${{ matrix.bzlmod }}
- name: Run example bazel build
run: bazelisk build //... --enable_bzlmod=${{ matrix.bzlmod }}
working-directory: ./examples
uses: codecov/codecov-action@v3

1
.gitignore vendored
View File

@ -15,7 +15,6 @@ bazel-genfiles
bazel-grpc-java
bazel-out
bazel-testlogs
MODULE.bazel.lock
# IntelliJ IDEA
.idea

View File

@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
load("@rules_jvm_external//:defs.bzl", "artifact")
load(":java_grpc_library.bzl", "java_grpc_library")
java_proto_library(
@ -33,9 +32,10 @@ java_library(
"//api",
"//protobuf",
"//stub",
"//stub:javax_annotation",
"@com_google_code_findbugs_jsr305//jar",
"@com_google_guava_guava//jar",
"@com_google_protobuf//:protobuf_java",
artifact("com.google.code.findbugs:jsr305"),
artifact("com.google.guava:guava"),
],
)
@ -46,8 +46,9 @@ java_library(
"//api",
"//protobuf-lite",
"//stub",
artifact("com.google.code.findbugs:jsr305"),
artifact("com.google.guava:guava"),
"//stub:javax_annotation",
"@com_google_code_findbugs_jsr305//jar",
"@com_google_guava_guava//jar",
],
)
@ -55,7 +56,7 @@ java_plugin(
name = "auto_value",
generates_api = 1,
processor_class = "com.google.auto.value.processor.AutoValueProcessor",
deps = [artifact("com.google.auto.value:auto-value")],
deps = ["@com_google_auto_value_auto_value//jar"],
)
java_library(
@ -64,6 +65,7 @@ java_library(
neverlink = 1,
visibility = ["//:__subpackages__"],
exports = [
artifact("com.google.auto.value:auto-value-annotations"),
"@com_google_auto_value_auto_value_annotations//jar",
"@org_apache_tomcat_annotations_api//jar", # @Generated for Java 9+
],
)

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
@ -68,7 +68,7 @@ For Visual C++, please refer to the [Protobuf README](https://github.com/google/
for how to compile Protobuf. gRPC-java assumes a Release build.
#### Mac
Some versions of Mac OS X (e.g., 10.10) don't have ``/usr/local`` in the
Some versions of Mac OS X (e.g., 10.10) doesn't have ``/usr/local`` in the
default search paths for header files and libraries. It will fail the build of
the codegen. To work around this, you will need to set environment variables:
```

View File

@ -30,36 +30,56 @@ style configurations are commonly useful. For IntelliJ 14, copy the style to
`~/.IdeaIC14/config/codestyles/`, start IntelliJ, go to File > Settings > Code
Style, and set the Scheme to `GoogleStyle`.
## Maintaining clean commit history
We have few conventions for keeping history clean and making code reviews easier
for reviewers:
* First line of commit messages should be in format of
`package-name: summary of change`
where the summary finishes the sentence: `This commit improves gRPC to ____________.`
for example:
`core,netty,interop-testing: add capacitive duractance to turbo encabulators`
* Every time you receive a feedback on your pull request, push changes that
address it as a separate one or multiple commits with a descriptive commit
message (try avoid using vauge `addressed pr feedback` type of messages).
Project maintainers are obligated to squash those commits into one when
merging.
## Running tests
### Jetty ALPN setup for IntelliJ
The tests in interop-testing project require jetty-alpn agent running in the background
otherwise they'll fail. Here are instructions on how to setup IntellJ IDEA to enable running
those tests in IDE:
* Settings -> Build Tools -> Gradle -> Runner -> select Gradle Test Runner
* View -> Tool Windows -> Gradle -> Edit Run Configuration -> Defaults -> JUnit -> Before lauch -> + -> Run Gradle task, enter the task in the build.gradle that sets the javaagent.
Step 1 must be taken, otherwise by the default JUnit Test Runner running a single test in IDE will trigger all the tests.
## Guidelines for Pull Requests
How to get your contributions merged smoothly and quickly.
- Create **small PRs** that are narrowly focused on **addressing a single concern**. We often times receive PRs that are trying to fix several things at a time, but only one fix is considered acceptable, nothing gets merged and both author's & review's time is wasted. Create more PRs to address different concerns and everyone will be happy.
- For speculative changes, consider opening an issue and discussing it to avoid
wasting time on an inappropriate approach. If you are suggesting a behavioral
or API change, consider starting with a [gRFC
proposal](https://github.com/grpc/proposal).
- Follow [typical Git commit message](https://cbea.ms/git-commit/#seven-rules)
structure. Have a good **commit description** as a record of **what** and
**why** the change is being made. Link to a GitHub issue if it exists. The
commit description makes a good PR description and is auto-copied by GitHub if
you have a single commit when creating the PR.
If your change is mostly for a single module (e.g., other module changes are
trivial), prefix your commit summary with the module name changed. Instead of
"Add HTTP/2 faster-than-light support to gRPC Netty" it is more terse as
"netty: Add faster-than-light support".
- Don't fix code style and formatting unless you are already changing that line
to address an issue. If you do want to fix formatting or style, do that in a
separate PR.
- Unless your PR is trivial, you should expect there will be reviewer comments
that you'll need to address before merging. Address comments with additional
commits so the reviewer can review just the changes; do not squash reviewed
commits unless the reviewer agrees. PRs are squashed when merging.
- For speculative changes, consider opening an issue and discussing it first. If you are suggesting a behavioral or API change, consider starting with a [gRFC proposal](https://github.com/grpc/proposal).
- Provide a good **PR description** as a record of **what** change is being made and **why** it was made. Link to a github issue if it exists.
- Don't fix code style and formatting unless you are already changing that line to address an issue. PRs with irrelevant changes won't be merged. If you do want to fix formatting or style, do that in a separate PR.
- Unless your PR is trivial, you should expect there will be reviewer comments that you'll need to address before merging. We expect you to be reasonably responsive to those comments, otherwise the PR will be closed after 2-3 weeks of inactivity.
- Maintain **clean commit history** and use **meaningful commit messages**. See [maintaining clean commit history](#maintaining-clean-commit-history) for details.
- Keep your PR up to date with upstream/master (if there are merge conflicts, we can't really merge your change).
- **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on. Also, `./gradlew build` (`gradlew build` on Windows) **must not introduce any new warnings**.

View File

@ -10,26 +10,25 @@ for general contribution guidelines.
## Maintainers (in alphabetical order)
- [ejona86](https://github.com/ejona86), Google LLC
- [jdcormie](https://github.com/jdcormie), Google LLC
- [kannanjgithub](https://github.com/kannanjgithub), Google LLC
- [larry-safran](https://github.com/larry-safran), Google LLC
- [markb74](https://github.com/markb74), Google LLC
- [ran-su](https://github.com/ran-su), Google LLC
- [sanjaypujare](https://github.com/sanjaypujare), Google LLC
- [sergiitk](https://github.com/sergiitk), Google LLC
- [temawi](https://github.com/temawi), Google LLC
- [YifeiZhuang](https://github.com/YifeiZhuang), Google LLC
- [zhangkun83](https://github.com/zhangkun83), Google LLC
## Emeritus Maintainers (in alphabetical order)
- [carl-mastrangelo](https://github.com/carl-mastrangelo)
- [creamsoup](https://github.com/creamsoup)
- [dapengzhang0](https://github.com/dapengzhang0)
- [ericgribkoff](https://github.com/ericgribkoff)
- [jiangtaoli2016](https://github.com/jiangtaoli2016)
- [jtattermusch](https://github.com/jtattermusch)
- [larry-safran](https://github.com/larry-safran)
- [louiscryan](https://github.com/louiscryan)
- [markb74](https://github.com/markb74)
- [nicolasnoble](https://github.com/nicolasnoble)
- [nmittler](https://github.com/nmittler)
- [sanjaypujare](https://github.com/sanjaypujare)
- [srini100](https://github.com/srini100)
- [voidzcy](https://github.com/voidzcy)
- [zpencer](https://github.com/zpencer)
- [carl-mastrangelo](https://github.com/carl-mastrangelo), Google LLC
- [creamsoup](https://github.com/creamsoup), Google LLC
- [dapengzhang0](https://github.com/dapengzhang0), Google LLC
- [ericgribkoff](https://github.com/ericgribkoff), Google LLC
- [jiangtaoli2016](https://github.com/jiangtaoli2016), Google LLC
- [jtattermusch](https://github.com/jtattermusch), Google LLC
- [louiscryan](https://github.com/louiscryan), Google LLC
- [nicolasnoble](https://github.com/nicolasnoble), Google LLC
- [nmittler](https://github.com/nmittler), Google LLC
- [srini100](https://github.com/srini100), Google LLC
- [voidzcy](https://github.com/voidzcy), Google LLC
- [zpencer](https://github.com/zpencer), Google LLC

View File

@ -1,185 +0,0 @@
module(
name = "grpc-java",
compatibility_level = 0,
repo_name = "io_grpc_grpc_java",
version = "1.76.0-SNAPSHOT", # CURRENT_GRPC_VERSION
)
# GRPC_DEPS_START
IO_GRPC_GRPC_JAVA_ARTIFACTS = [
"com.google.android:annotations:4.1.1.4",
"com.google.api.grpc:proto-google-common-protos:2.59.2",
"com.google.auth:google-auth-library-credentials:1.24.1",
"com.google.auth:google-auth-library-oauth2-http:1.24.1",
"com.google.auto.value:auto-value-annotations:1.11.0",
"com.google.auto.value:auto-value:1.11.0",
"com.google.code.findbugs:jsr305:3.0.2",
"com.google.code.gson:gson:2.11.0",
"com.google.errorprone:error_prone_annotations:2.30.0",
"com.google.guava:failureaccess:1.0.1",
"com.google.guava:guava:33.3.1-android",
"com.google.re2j:re2j:1.8",
"com.google.s2a.proto.v2:s2a-proto:0.1.2",
"com.google.truth:truth:1.4.2",
"com.squareup.okhttp:okhttp:2.7.5",
"com.squareup.okio:okio:2.10.0", # 3.0+ needs swapping to -jvm; need work to avoid flag-day
"io.netty:netty-buffer:4.1.124.Final",
"io.netty:netty-codec-http2:4.1.124.Final",
"io.netty:netty-codec-http:4.1.124.Final",
"io.netty:netty-codec-socks:4.1.124.Final",
"io.netty:netty-codec:4.1.124.Final",
"io.netty:netty-common:4.1.124.Final",
"io.netty:netty-handler-proxy:4.1.124.Final",
"io.netty:netty-handler:4.1.124.Final",
"io.netty:netty-resolver:4.1.124.Final",
"io.netty:netty-tcnative-boringssl-static:2.0.70.Final",
"io.netty:netty-tcnative-classes:2.0.70.Final",
"io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.124.Final",
"io.netty:netty-transport-native-unix-common:4.1.124.Final",
"io.netty:netty-transport:4.1.124.Final",
"io.opencensus:opencensus-api:0.31.0",
"io.opencensus:opencensus-contrib-grpc-metrics:0.31.0",
"io.perfmark:perfmark-api:0.27.0",
"junit:junit:4.13.2",
"org.checkerframework:checker-qual:3.12.0",
"org.codehaus.mojo:animal-sniffer-annotations:1.24",
]
# GRPC_DEPS_END
bazel_dep(name = "bazel_jar_jar", version = "0.1.7")
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "googleapis", repo_name = "com_google_googleapis", version = "0.0.0-20240326-1c8d509c5")
bazel_dep(name = "grpc-proto", repo_name = "io_grpc_grpc_proto", version = "0.0.0-20240627-ec30f58")
# Protobuf 25.5+ is incompatible with Bazel 7 with bzlmod
bazel_dep(name = "protobuf", repo_name = "com_google_protobuf", version = "24.4")
bazel_dep(name = "rules_cc", version = "0.0.9")
bazel_dep(name = "rules_java", version = "5.3.5")
bazel_dep(name = "rules_jvm_external", version = "6.0")
bazel_dep(name = "rules_proto", version = "5.3.0-21.7")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
artifacts = IO_GRPC_GRPC_JAVA_ARTIFACTS,
repositories = [
"https://repo.maven.apache.org/maven2/",
],
strict_visibility = True,
)
use_repo(maven, "maven")
maven.override(
coordinates = "com.google.protobuf:protobuf-java",
target = "@com_google_protobuf//:protobuf_java",
)
maven.override(
coordinates = "com.google.protobuf:protobuf-java-util",
target = "@com_google_protobuf//:protobuf_java_util",
)
maven.override(
coordinates = "com.google.protobuf:protobuf-javalite",
target = "@com_google_protobuf//:protobuf_javalite",
)
maven.override(
coordinates = "io.grpc:grpc-alts",
target = "@io_grpc_grpc_java//alts",
)
maven.override(
coordinates = "io.grpc:grpc-api",
target = "@io_grpc_grpc_java//api",
)
maven.override(
coordinates = "io.grpc:grpc-auth",
target = "@io_grpc_grpc_java//auth",
)
maven.override(
coordinates = "io.grpc:grpc-census",
target = "@io_grpc_grpc_java//census",
)
maven.override(
coordinates = "io.grpc:grpc-context",
target = "@io_grpc_grpc_java//context",
)
maven.override(
coordinates = "io.grpc:grpc-core",
target = "@io_grpc_grpc_java//core:core_maven",
)
maven.override(
coordinates = "io.grpc:grpc-googleapis",
target = "@io_grpc_grpc_java//googleapis",
)
maven.override(
coordinates = "io.grpc:grpc-grpclb",
target = "@io_grpc_grpc_java//grpclb",
)
maven.override(
coordinates = "io.grpc:grpc-inprocess",
target = "@io_grpc_grpc_java//inprocess",
)
maven.override(
coordinates = "io.grpc:grpc-netty",
target = "@io_grpc_grpc_java//netty",
)
maven.override(
coordinates = "io.grpc:grpc-netty-shaded",
target = "@io_grpc_grpc_java//netty:shaded_maven",
)
maven.override(
coordinates = "io.grpc:grpc-okhttp",
target = "@io_grpc_grpc_java//okhttp",
)
maven.override(
coordinates = "io.grpc:grpc-protobuf",
target = "@io_grpc_grpc_java//protobuf",
)
maven.override(
coordinates = "io.grpc:grpc-protobuf-lite",
target = "@io_grpc_grpc_java//protobuf-lite",
)
maven.override(
coordinates = "io.grpc:grpc-rls",
target = "@io_grpc_grpc_java//rls",
)
maven.override(
coordinates = "io.grpc:grpc-services",
target = "@io_grpc_grpc_java//services:services_maven",
)
maven.override(
coordinates = "io.grpc:grpc-stub",
target = "@io_grpc_grpc_java//stub",
)
maven.override(
coordinates = "io.grpc:grpc-testing",
target = "@io_grpc_grpc_java//testing",
)
maven.override(
coordinates = "io.grpc:grpc-xds",
target = "@io_grpc_grpc_java//xds:xds_maven",
)
maven.override(
coordinates = "io.grpc:grpc-util",
target = "@io_grpc_grpc_java//util",
)

View File

@ -13,14 +13,14 @@ gRPC-Java - An RPC library and framework
</table>
[![Join the chat at https://gitter.im/grpc/grpc](https://badges.gitter.im/grpc/grpc.svg)](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![GitHub Actions Linux Testing](https://github.com/grpc/grpc-java/actions/workflows/testing.yml/badge.svg?branch=master)](https://github.com/grpc/grpc-java/actions/workflows/testing.yml?branch=master)
[![Build Status](https://travis-ci.org/grpc/grpc-java.svg?branch=master)](https://travis-ci.org/grpc/grpc-java)
[![Line Coverage Status](https://coveralls.io/repos/grpc/grpc-java/badge.svg?branch=master&service=github)](https://coveralls.io/github/grpc/grpc-java?branch=master)
[![Branch-adjusted Line Coverage Status](https://codecov.io/gh/grpc/grpc-java/branch/master/graph/badge.svg)](https://codecov.io/gh/grpc/grpc-java)
Supported Platforms
-------------------
gRPC-Java supports Java 8 and later. Android minSdkVersion 21 (Lollipop) and
gRPC-Java supports Java 8 and later. Android minSdkVersion 19 (KitKat) and
later are supported with [Java 8 language desugaring][android-java-8].
TLS usage on Android typically requires Play Services Dynamic Security Provider.
@ -44,8 +44,8 @@ For a guided tour, take a look at the [quick start
guide](https://grpc.io/docs/languages/java/quickstart) or the more explanatory [gRPC
basics](https://grpc.io/docs/languages/java/basics).
The [examples](https://github.com/grpc/grpc-java/tree/v1.75.0/examples) and the
[Android example](https://github.com/grpc/grpc-java/tree/v1.75.0/examples/android)
The [examples](https://github.com/grpc/grpc-java/tree/v1.54.1/examples) and the
[Android example](https://github.com/grpc/grpc-java/tree/v1.54.1/examples/android)
are standalone projects that showcase the usage of gRPC.
Download
@ -56,18 +56,18 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty-shaded</artifactId>
<version>1.75.0</version>
<version>1.54.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-protobuf</artifactId>
<version>1.75.0</version>
<version>1.54.1</version>
</dependency>
<dependency>
<groupId>io.grpc</groupId>
<artifactId>grpc-stub</artifactId>
<version>1.75.0</version>
<version>1.54.1</version>
</dependency>
<dependency> <!-- necessary for Java 9+ -->
<groupId>org.apache.tomcat</groupId>
@ -79,30 +79,26 @@ Download [the JARs][]. Or for Maven with non-Android, add to your `pom.xml`:
Or for Gradle with non-Android, add to your dependencies:
```gradle
runtimeOnly 'io.grpc:grpc-netty-shaded:1.75.0'
implementation 'io.grpc:grpc-protobuf:1.75.0'
implementation 'io.grpc:grpc-stub:1.75.0'
runtimeOnly 'io.grpc:grpc-netty-shaded:1.54.1'
implementation 'io.grpc:grpc-protobuf:1.54.1'
implementation 'io.grpc:grpc-stub:1.54.1'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
```
For Android client, use `grpc-okhttp` instead of `grpc-netty-shaded` and
`grpc-protobuf-lite` instead of `grpc-protobuf`:
```gradle
implementation 'io.grpc:grpc-okhttp:1.75.0'
implementation 'io.grpc:grpc-protobuf-lite:1.75.0'
implementation 'io.grpc:grpc-stub:1.75.0'
implementation 'io.grpc:grpc-okhttp:1.54.1'
implementation 'io.grpc:grpc-protobuf-lite:1.54.1'
implementation 'io.grpc:grpc-stub:1.54.1'
compileOnly 'org.apache.tomcat:annotations-api:6.0.53' // necessary for Java 9+
```
For [Bazel](https://bazel.build), you can either
[use Maven](https://github.com/bazelbuild/rules_jvm_external)
(with the GAVs from above), or use `@io_grpc_grpc_java//api` et al (see below).
[the JARs]:
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.75.0
https://search.maven.org/search?q=g:io.grpc%20AND%20v:1.54.1
Development snapshots are available in [Sonatypes's snapshot
repository](https://central.sonatype.com/repository/maven-snapshots/).
repository](https://oss.sonatype.org/content/repositories/snapshots/).
Generated Code
--------------
@ -129,9 +125,9 @@ For protobuf-based codegen integrated with the Maven build system, you can use
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.6.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.25.5:exe:${os.detected.classifier}</protocArtifact>
<protocArtifact>com.google.protobuf:protoc:3.21.7:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.75.0:exe:${os.detected.classifier}</pluginArtifact>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.54.1:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
@ -152,16 +148,16 @@ For non-Android protobuf-based codegen integrated with the Gradle build system,
you can use [protobuf-gradle-plugin][]:
```gradle
plugins {
id 'com.google.protobuf' version '0.9.5'
id 'com.google.protobuf' version '0.9.1'
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.25.5"
artifact = "com.google.protobuf:protoc:3.21.7"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
artifact = 'io.grpc:protoc-gen-grpc-java:1.54.1'
}
}
generateProtoTasks {
@ -185,16 +181,16 @@ use protobuf-gradle-plugin but specify the 'lite' options:
```gradle
plugins {
id 'com.google.protobuf' version '0.9.5'
id 'com.google.protobuf' version '0.9.1'
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:3.25.5"
artifact = "com.google.protobuf:protoc:3.21.7"
}
plugins {
grpc {
artifact = 'io.grpc:protoc-gen-grpc-java:1.75.0'
artifact = 'io.grpc:protoc-gen-grpc-java:1.54.1'
}
}
generateProtoTasks {
@ -211,11 +207,6 @@ protobuf {
```
For [Bazel](https://bazel.build), use the [`proto_library`](https://github.com/bazelbuild/rules_proto)
and the [`java_proto_library`](https://bazel.build/reference/be/java#java_proto_library) (no `load()` required)
and `load("@io_grpc_grpc_java//:java_grpc_library.bzl", "java_grpc_library")` (from this project), as in
[this example `BUILD.bazel`](https://github.com/grpc/grpc-java/blob/master/examples/BUILD.bazel).
API Stability
-------------
@ -269,9 +260,6 @@ gRPC comes with multiple Transport implementations:
1. The Netty-based HTTP/2 transport is the main transport implementation based
on [Netty](https://netty.io). It is not officially supported on Android.
There is a "grpc-netty-shaded" version of this transport. It is generally
preferred over using the Netty-based transport directly as it requires less
dependency management and is easier to upgrade within many applications.
2. The OkHttp-based HTTP/2 transport is a lightweight transport based on
[Okio](https://square.github.io/okio/) and forked low-level parts of
[OkHttp](https://square.github.io/okhttp/). It is mainly for use on Android.

View File

@ -16,12 +16,10 @@ Many of the following commands expect release-specific variables to be set. Set
them before continuing, and set them again when resuming.
```bash
MAJOR=1 MINOR=7 PATCH=0 # Set appropriately for new release
VERSION_FILES=(
MODULE.bazel
$ MAJOR=1 MINOR=7 PATCH=0 # Set appropriately for new release
$ VERSION_FILES=(
build.gradle
core/src/main/java/io/grpc/internal/GrpcUtil.java
examples/MODULE.bazel
examples/build.gradle
examples/pom.xml
examples/android/clientcache/app/build.gradle
@ -50,26 +48,25 @@ would be used to create all `v1.7` tags (e.g. `v1.7.0`, `v1.7.1`).
``1.8.0-SNAPSHOT``).
```bash
git checkout -b bump-version master
$ git checkout -b bump-version master
# Change version to next minor (and keep -SNAPSHOT)
sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$((MINOR+1)).0'\1/' \
$ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$((MINOR+1)).0'\1/' \
"${VERSION_FILES[@]}"
sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$((MINOR+1)).0/ \
$ sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$((MINOR+1)).0/ \
compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt
./gradlew build
git commit -a -m "Start $MAJOR.$((MINOR+1)).0 development cycle"
$ ./gradlew build
$ git commit -a -m "Start $MAJOR.$((MINOR+1)).0 development cycle"
```
3. Go through PR review and submit.
4. Create the release branch starting just before your commit and push it to GitHub:
```bash
git fetch upstream
git checkout -b v$MAJOR.$MINOR.x \
$(git log --pretty=format:%H --grep "^Start $MAJOR.$((MINOR+1)).0 development cycle" upstream/master)^
git push upstream v$MAJOR.$MINOR.x
$ git fetch upstream
$ git checkout -b v$MAJOR.$MINOR.x \
$(git log --pretty=format:%H --grep "^Start $MAJOR.$((MINOR+1)).0 development cycle$" upstream/master)^
$ git push upstream v$MAJOR.$MINOR.x
```
5. Continue with Google-internal steps at go/grpc-java/releasing, but stop
before `Auto releasing using kokoro`.
5. Continue with Google-internal steps at go/grpc/java/releasing.
6. Create a milestone for the next release.
7. Move items out of the release milestone that didn't make the cut. Issues that
may be backported should stay in the release milestone. Treat issues with the
@ -77,8 +74,8 @@ would be used to create all `v1.7` tags (e.g. `v1.7.0`, `v1.7.1`).
8. Begin compiling release notes. This produces a starting point:
```bash
echo "## gRPC Java $MAJOR.$MINOR.0 Release Notes" && echo && \
git shortlog -e --format='%s (%h)' "$(git merge-base upstream/v$MAJOR.$((MINOR-1)).x upstream/v$MAJOR.$MINOR.x)"..upstream/v$MAJOR.$MINOR.x | cat && \
$ echo "## gRPC Java $MAJOR.$MINOR.0 Release Notes" && echo && \
git shortlog "$(git merge-base upstream/v$MAJOR.$((MINOR-1)).x upstream/v$MAJOR.$MINOR.x)"..upstream/v$MAJOR.$MINOR.x | cat && \
echo && echo && echo "Backported commits in previous release:" && \
git log --oneline "$(git merge-base v$MAJOR.$((MINOR-1)).0 upstream/v$MAJOR.$MINOR.x)"..v$MAJOR.$((MINOR-1)).0^
```
@ -93,160 +90,132 @@ Tagging the Release
either be deferred or resolved and the fix backported. Verify there are no
[TODO:release blocker][] nor [TODO:backport][] issues (open or closed), or
that they are tracking an issue for a different branch.
2. Ensure that the Google-internal steps
at go/grpc-java/releasing#before-tagging-a-release are completed.
2. Ensure that Google-internal steps completed at go/grpc/java/releasing#before-tagging-a-release.
3. For vMajor.Minor.x branch, change `README.md` to refer to the next release
version. _Also_ update the version numbers for protoc if the protobuf library
version was updated since the last release.
```bash
git checkout v$MAJOR.$MINOR.x
git pull upstream v$MAJOR.$MINOR.x
git checkout -b release-v$MAJOR.$MINOR.$PATCH
$ git checkout v$MAJOR.$MINOR.x
$ git pull upstream v$MAJOR.$MINOR.x
$ git checkout -b release
# Bump documented gRPC versions.
# Also update protoc version to match protobuf version in gradle/libs.versions.toml.
${EDITOR:-nano -w} README.md
git commit -a -m "Update README etc to reference $MAJOR.$MINOR.$PATCH"
$ ${EDITOR:-nano -w} README.md
$ ${EDITOR:-nano -w} documentation/android-channel-builder.md
$ ${EDITOR:-nano -w} cronet/README.md
$ git commit -a -m "Update README etc to reference $MAJOR.$MINOR.$PATCH"
```
4. Change root build files to remove "-SNAPSHOT" for the next release version
(e.g. `0.7.0`). Commit the result and make a tag:
```bash
# Change version to remove -SNAPSHOT
sed -i 's/-SNAPSHOT\(.*CURRENT_GRPC_VERSION\)/\1/' "${VERSION_FILES[@]}"
sed -i s/-SNAPSHOT// compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt
./gradlew build
git commit -a -m "Bump version to $MAJOR.$MINOR.$PATCH"
git tag -a v$MAJOR.$MINOR.$PATCH -m "Version $MAJOR.$MINOR.$PATCH"
$ sed -i 's/-SNAPSHOT\(.*CURRENT_GRPC_VERSION\)/\1/' "${VERSION_FILES[@]}"
$ sed -i s/-SNAPSHOT// compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt
$ ./gradlew build
$ git commit -a -m "Bump version to $MAJOR.$MINOR.$PATCH"
$ git tag -a v$MAJOR.$MINOR.$PATCH -m "Version $MAJOR.$MINOR.$PATCH"
```
5. Change root build files to the next snapshot version (e.g. `0.7.1-SNAPSHOT`).
Commit the result:
```bash
# Change version to next patch and add -SNAPSHOT
sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT'\1/' \
$ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT'\1/' \
"${VERSION_FILES[@]}"
sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT/ \
$ sed -i s/$MAJOR.$MINOR.$PATCH/$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT/ \
compiler/src/test{,Lite}/golden/Test{,Deprecated}Service.java.txt
./gradlew build
git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT"
git push -u origin release-v$MAJOR.$MINOR.$PATCH
$ ./gradlew build
$ git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT"
```
Raise a PR and set the base branch of the PR to v$MAJOR.$MINOR.x of the upstream grpc-java repo.
6. Go through PR review and push the release tag and updated release branch to
GitHub (DO NOT click the merge button on the GitHub page):
```bash
git checkout v$MAJOR.$MINOR.x
git merge --ff-only release-v$MAJOR.$MINOR.$PATCH
git push upstream v$MAJOR.$MINOR.x
git push upstream v$MAJOR.$MINOR.$PATCH
$ git checkout v$MAJOR.$MINOR.x
$ git merge --ff-only release
$ git push upstream v$MAJOR.$MINOR.x
$ git push upstream v$MAJOR.$MINOR.$PATCH
```
7. Close the release milestone.
8. Trigger build as described in "Auto releasing using kokoro" at
go/grpc-java/releasing.
Build Artifacts
---------------
It runs three jobs on Kokoro, one on each platform. See their scripts:
`linux_artifacts.sh`, `windows.bat`, and `macos.sh`. The mvn-artifacts/
outputs of each script is combined into a single folder and then processed
by `upload_artifacts.sh`, which signs the files and uploads to Sonatype.
Trigger build as described in "Auto releasing using kokoro" at
go/grpc/java/releasing.
9. Once all of the artifacts have been pushed to the staging repository, the
repository should have been closed by `upload_artifacts.sh`. Closing triggers
several sanity checks on the repository. If this completes successfully, the
repository can then be `released`, which will begin the process of pushing
the new artifacts to Maven Central (the staging repository will be destroyed
in the process). You can see the complete process for releasing to Maven
Central on the [OSSRH site](https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/#deploying).
It runs three jobs on Kokoro, one on each platform. See their scripts:
`linux_artifacts.sh`, `windows.bat`, and `unix.sh` (called directly for OS X;
called within the Docker environment on Linux). The mvn-artifacts/ outputs of
each script is combined into a single folder and then processed by
`upload_artifacts.sh`, which signs the files and uploads to Sonatype.
10. We have containers for each release to detect compatibility regressions with
old releases. Generate one for the new release by following the [GCR image
generation instructions][gcr-image]. Summary:
```bash
# If you haven't previously configured docker:
gcloud auth configure-docker us-docker.pkg.dev
Releasing on Maven Central
--------------------------
# In main grpc repo, add the new version to matrix
${EDITOR:-nano -w} tools/interop_matrix/client_matrix.py
tools/interop_matrix/create_matrix_images.py --git_checkout --release=v$MAJOR.$MINOR.$PATCH \
--upload_images --language java
docker pull us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH
docker_image=us-docker.pkg.dev/grpc-testing/testing-images-public/grpc_interop_java:v$MAJOR.$MINOR.$PATCH \
tools/interop_matrix/testcases/java__master
Once all of the artifacts have been pushed to the staging repository, the
repository should have been closed by `upload_artifacts.sh`. Closing triggers
several sanity checks on the repository. If this completes successfully, the
repository can then be `released`, which will begin the process of pushing the
new artifacts to Maven Central (the staging repository will be destroyed in the
process). You can see the complete process for releasing to Maven Central on the
[OSSRH site](https://central.sonatype.org/pages/releasing-the-deployment.html).
# Commit the changes
git commit --all -m "[interop] Add grpc-java $MAJOR.$MINOR.$PATCH to client_matrix.py"
Build interop container image
-----------------------------
# Create a PR with the `release notes: no` label and run ad-hoc test against your PR
```
[gcr-image]: https://github.com/grpc/grpc/blob/master/tools/interop_matrix/README.md#step-by-step-instructions-for-adding-a-gcr-image-for-a-new-release-for-compatibility-test
We have containers for each release to detect compatibility regressions with old
releases. Generate one for the new release by following the
[GCR image generation instructions](https://github.com/grpc/grpc/blob/master/tools/interop_matrix/README.md#step-by-step-instructions-for-adding-a-gcr-image-for-a-new-release-for-compatibility-test).
11. Update gh-pages with the new Javadoc. Generally the file is on repo1
15 minutes after publishing:
Update README.md
----------------
After waiting ~1 day and verifying that the release appears on [Maven
Central](https://search.maven.org/search?q=g:io.grpc), cherry-pick the commit
that updated the README into the master branch and go through review process.
```bash
git checkout gh-pages
git pull --ff-only upstream gh-pages
rm -r javadoc/
wget -O grpc-all-javadoc.jar "https://repo1.maven.org/maven2/io/grpc/grpc-all/$MAJOR.$MINOR.$PATCH/grpc-all-$MAJOR.$MINOR.$PATCH-javadoc.jar"
unzip -d javadoc grpc-all-javadoc.jar
patch -p1 < ga.patch
rm grpc-all-javadoc.jar
rm -r javadoc/META-INF/
git add -A javadoc
git commit -m "Javadoc for $MAJOR.$MINOR.$PATCH"
git push upstream gh-pages
```
Verify the current version is [live on grpc.io](https://grpc.io/grpc-java/javadoc/).
12. Add [Release Notes](https://github.com/grpc/grpc-java/releases) for the new tag.
*Make sure that any backports are reflected in the release notes.*
13. Notify the Community. Post a release announcement to
[grpc-io](https://groups.google.com/forum/#!forum/grpc-io)
(`grpc-io@googlegroups.com`) with the title `gRPC-Java v$MAJOR.$MINOR.$PATCH
Released`. The email content should link to the GitHub release notes and
include a copy of them.
14. Update README.md. Cherry-pick the commit that updated the README.md into the
master branch.
```bash
git checkout -b bump-readme master
git cherry-pick v$MAJOR.$MINOR.$PATCH^
git push --set-upstream origin bump-readme
```
Create a PR and go through the review process
15. Update version referenced by tutorials. Update `params.grpc_vers.java` in
[config.yaml](https://github.com/grpc/grpc.io/blob/master/config.yaml) of
the grpc.io repository. Create a PR and go through the review process.
Post-release upgrades
---------------------
Upgrade dependencies after the release so they can be well-tested before the
next release.
Upgrade the Gradle plugins in `settings.gradle` and the Gradle version in
`gradle/wrapper/gradle-wrapper.properties`. Make sure to read the release notes
for each dependency upgraded. Test by doing a regular build.
Upgrade the regular dependencies in `gradle/libs.versions.toml`, except for
Netty and netty-tcnative. To find available upgrades:
```bash
./gradlew checkForUpdates
```
$ git checkout -b bump-readme master
$ git cherry-pick v$MAJOR.$MINOR.$PATCH^
```
Test by doing a regular build. For each step, if a dependency cannot be
upgraded, add a comment. Create issues in other projects for breakages, and in
gRPC for things that will need a migration effort.
Update version referenced by tutorials
--------------------------------------
When happy with the dependency upgrades, update the versions in `MODULE.bazel`,
`repositories.bzl`, and the various `pom.xml` and `build.gradle` files in
`examples/`.
Update `params.grpc_vers.java` in
[config.yaml](https://github.com/grpc/grpc.io/blob/master/config.yaml)
of the grpc.io repository.
Notify the Community
--------------------
Finally, document and publicize the release.
1. Add [Release Notes](https://github.com/grpc/grpc-java/releases) for the new tag.
The description should include any major fixes or features since the last release.
You may choose to add links to bugs, PRs, or commits if appropriate.
2. Post a release announcement to [grpc-io](https://groups.google.com/forum/#!forum/grpc-io)
(`grpc-io@googlegroups.com`). The title should be something that clearly identifies
the release (e.g.`GRPC-Java <tag> Released`).
Update Hosted Javadoc
---------------------
Now we need to update gh-pages with the new Javadoc:
```bash
git checkout gh-pages
git pull --ff-only upstream gh-pages
rm -r javadoc/
wget -O grpc-all-javadoc.jar "http://search.maven.org/remotecontent?filepath=io/grpc/grpc-all/$MAJOR.$MINOR.$PATCH/grpc-all-$MAJOR.$MINOR.$PATCH-javadoc.jar"
unzip -d javadoc grpc-all-javadoc.jar
patch -p1 < ga.patch
rm grpc-all-javadoc.jar
rm -r javadoc/META-INF/
git add -A javadoc
git commit -m "Javadoc for $MAJOR.$MINOR.$PATCH"
```
Push gh-pages to the main repository and verify the current version is [live
on grpc.io](https://grpc.io/grpc-java/javadoc/).

View File

@ -1,16 +1,10 @@
# Security Policy
For information on gRPC Security Policy and reporting potentional security
issues, please see [gRPC CVE Process][].
[gRPC CVE Process]: https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md
For information on gRPC Security Policy and reporting potentional security issues, please see [gRPC CVE Process](https://github.com/grpc/proposal/blob/master/P4-grpc-cve-process.md).
# Authentication
gRPC supports a number of different mechanisms for asserting identity between an
client and server. This document provides code samples demonstrating how to
provide SSL/TLS encryption support and identity assertions in Java, as well as
passing OAuth2 tokens to services that support it.
gRPC supports a number of different mechanisms for asserting identity between an client and server. This document provides code samples demonstrating how to provide SSL/TLS encryption support and identity assertions in Java, as well as passing OAuth2 tokens to services that support it.
# Transport Security (TLS)
@ -25,28 +19,25 @@ BoringSSL](#tls-with-netty-tcnative-on-boringssl).
## TLS on Android
On Android we recommend the use of the [Play Services Dynamic Security
Provider][] to ensure your application has an up-to-date OpenSSL library with
the necessary cipher-suites and a reliable ALPN implementation. This requires
[updating the security provider at runtime][config-psdsp].
Provider](https://www.appfoundry.be/blog/2014/11/18/Google-Play-Services-Dynamic-Security-Provider/)
to ensure your application has an up-to-date OpenSSL library with the necessary
cipher-suites and a reliable ALPN implementation. This requires [updating the
security provider at
runtime](https://developer.android.com/training/articles/security-gms-provider.html).
Although ALPN mostly works on newer Android releases (especially since 5.0),
there are bugs and discovered security vulnerabilities that are only fixed by
upgrading the security provider. Thus, we recommend using the Play Service
Dynamic Security Provider for all Android versions.
*Note: The Dynamic Security Provider must be installed **before** creating a
gRPC OkHttp channel. gRPC statically initializes the security protocol(s)
available, which means that changes to the security provider after the first
channel is created will not be noticed by gRPC.*
[Play Services Dynamic Security Provider]: https://www.appfoundry.be/blog/2014/11/18/Google-Play-Services-Dynamic-Security-Provider/
[config-psdsp]: https://developer.android.com/training/articles/security-gms-provider.html
*Note: The Dynamic Security Provider must be installed **before** creating a gRPC OkHttp channel. gRPC's OkHttpProtocolNegotiator statically initializes the security protocol(s) available to gRPC, which means that changes to the security provider after the first channel is created will not be picked up by gRPC.*
### Bundling Conscrypt
If depending on Play Services is not an option for your app, then you may bundle
[Conscrypt](https://conscrypt.org) with your application. Binaries are available
on [Maven Central][conscrypt-maven].
on [Maven
Central](https://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.conscrypt%20a%3Aconscrypt-android).
Like the Play Services Dynamic Security Provider, you must still "install"
Conscrypt before use.
@ -59,12 +50,10 @@ import java.security.Security;
Security.insertProviderAt(Conscrypt.newProvider(), 1);
```
[conscrypt-maven]: https://search.maven.org/#search%7Cga%7C1%7Cg%3Aorg.conscrypt%20a%3Aconscrypt-android
## TLS on non-Android
OpenJDK versions prior to Java 8u252 do not support ALPN. Java 8 has 10% the
performance of OpenSSL.
JDK versions prior to Java 9 do not support ALPN and are either missing AES GCM
support or have 2% the performance of OpenSSL.
We recommend most users use grpc-netty-shaded, which includes netty-tcnative on
BoringSSL. It includes pre-built libraries for 64 bit Windows, OS X, and 64 bit
@ -84,7 +73,7 @@ with OpenSSL](#tls-with-netty-tcnative-on-openssl) are other valid options.
[Apache Tomcat's tcnative](https://tomcat.apache.org/native-doc/) and is a JNI
wrapper around OpenSSL/BoringSSL/LibreSSL.
We recommend BoringSSL for its simplicity and low occurrence of security
We recommend BoringSSL for its simplicitly and low occurrence of security
vulnerabilities relative to OpenSSL. BoringSSL is used by Conscrypt as well.
### TLS with netty-tcnative on BoringSSL
@ -254,6 +243,37 @@ import java.security.Security;
Security.insertProviderAt(Conscrypt.newProvider(), 1);
```
### TLS with Jetty ALPN
**Please do not use Jetty ALPN**
gRPC historically supported Jetty ALPN for ALPN on Java 8. While functional, it
suffers from poor performance and breakages when the JRE is upgraded.
When mis-matched to the JRE version, it can also produce unpredictable errors
that are hard to diagnose. When using it, it became common practice that any
time we saw a TLS failure that made no sense we would blame a Jetty ALPN/JRE
version mismatch and we were overwhelmingly correct. The Jetty ALPN agent makes
it much easier to use, but we still strongly discourage Jetty ALPN's use.
When using Jetty ALPN with Java 8, realize that performance will be 2-10% that
of the other options due to a slow AES GCM implementation in Java.
#### Configuring Jetty ALPN in Web Containers
Some web containers, such as [Jetty](https://www.eclipse.org/jetty/documentation/current/jetty-classloading.html) restrict access to server classes for web applications. A gRPC client running within such a container must be properly configured to allow access to the ALPN classes. In Jetty, this is done by including a `WEB-INF/jetty-env.xml` file containing the following:
```xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<!-- Must be done in jetty-env.xml, since jetty-web.xml is loaded too late. -->
<!-- Removing ALPN from the blacklisted server classes (using "-" to remove). -->
<!-- Must prepend to the blacklist since order matters. -->
<Call name="prependServerClass">
<Arg>-org.eclipse.jetty.alpn.</Arg>
</Call>
</Configure>
```
## Enabling TLS on a server
To use TLS on the server, a certificate chain and private key need to be
@ -261,36 +281,35 @@ specified in PEM format. The standard TLS port is 443, but we use 8443 below to
avoid needing extra permissions from the OS.
```java
ServerCredentials creds = TlsServerCredentials.create(certChainFile, privateKeyFile);
Server server = Grpc.newServerBuilderForPort(8443, creds)
Server server = ServerBuilder.forPort(8443)
// Enable TLS
.useTransportSecurity(certChainFile, privateKeyFile)
.addService(serviceImplementation)
.build()
.start();
.build();
server.start();
```
If the issuing certificate authority is not known to the client then a properly
configured trust manager should be provided to TlsChannelCredentials and used to
construct the channel.
configured SslContext or SSLSocketFactory should be provided to the
NettyChannelBuilder or OkHttpChannelBuilder, respectively.
## Mutual TLS
[Mutual authentication][] (or "client-side authentication") configuration is similar to the server by providing truststores, a client certificate and private key to the client channel. The server must also be configured to request a certificate from clients, as well as truststores for which client certificates it should allow.
```java
ServerCredentials creds = TlsServerCredentials.newBuilder()
.keyManager(certChainFile, privateKeyFile)
.trustManager(clientCAsFile)
.clientAuth(TlsServerCredentials.ClientAuth.REQUIRE)
.build();
Server server = NettyServerBuilder.forPort(8443)
.sslContext(GrpcSslContexts.forServer(certChainFile, privateKeyFile)
.trustManager(clientCAsFile)
.clientAuth(ClientAuth.REQUIRE)
.build());
```
Negotiated client certificates are available in the SSLSession, which is found
in the `Grpc.TRANSPORT_ATTR_SSL_SESSION` attribute of the call. A server
interceptor can provide details in the current Context.
Negotiated client certificates are available in the SSLSession, which is found in the `TRANSPORT_ATTR_SSL_SESSION` attribute of <a href="https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/Grpc.java">Grpc</a>. A server interceptor can provide details in the current Context.
```java
// The application uses this in its handlers.
public static final Context.Key<MySecurityInfo> SECURITY_INFO = Context.key("my.security.Info");
// The application uses this in its handlers
public final static Context.Key<SSLSession> SSL_SESSION_CONTEXT = Context.key("SSLSession");
@Override
public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, RespT> call,
@ -299,12 +318,8 @@ public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(ServerCall<ReqT, Re
if (sslSession == null) {
return next.startCall(call, headers);
}
// This interceptor can provide a centralized policy to process the client's
// certificate. Avoid exposing low-level details (like SSLSession) and
// instead provide a higher-level concept like "authenticated user."
MySecurityInfo info = process(sslSession);
return Contexts.interceptCall(
Context.current().withValue(SECURITY_INFO, info), call, headers, next);
Context.current().withValue(SSL_SESSION_CONTEXT, sslSession), call, headers, next);
}
```
@ -343,6 +358,10 @@ If on Fedora 30 or later and you see "libcrypt.so.1: cannot open shared object
file: No such file or directory". Run `dnf -y install libxcrypt-compat` to
install the necessary dependency.
If you are running inside of an embedded Tomcat runtime (e.g., Spring Boot),
then some versions of `netty-tcnative-boringssl-static` will have conflicts and
won't work. You must use gRPC 1.4.0 or later.
Most dependency versioning problems can be solved by using
`io.grpc:grpc-netty-shaded` instead of `io.grpc:grpc-netty`, although this also
limits your usage of the Netty-specific APIs. `io.grpc:grpc-netty-shaded`
@ -394,24 +413,24 @@ grpc-netty version | netty-handler version | netty-tcnative-boringssl-static ver
1.44.x-1.47.x | 4.1.72.Final | 2.0.46.Final
1.48.x-1.49.x | 4.1.77.Final | 2.0.53.Final
1.50.x-1.53.x | 4.1.79.Final | 2.0.54.Final
1.54.x-1.55.x | 4.1.87.Final | 2.0.56.Final
1.56.x | 4.1.87.Final | 2.0.61.Final
1.57.x-1.58.x | 4.1.93.Final | 2.0.61.Final
1.59.x | 4.1.97.Final | 2.0.61.Final
1.60.x-1.66.x | 4.1.100.Final | 2.0.61.Final
1.67.x-1.70.x | 4.1.110.Final | 2.0.65.Final
1.71.x-1.74.x | 4.1.110.Final | 2.0.70.Final
1.75.x- | 4.1.124.Final | 2.0.72.Final
1.54.x- | 4.1.87.Final | 2.0.56.Final
_(grpc-netty-shaded avoids issues with keeping these versions in sync.)_
### OkHttp
If you are using gRPC on Android devices, you are most likely using
`grpc-okhttp` transport.
If you are using gRPC on Android devices, you are most likely using `grpc-okhttp` transport.
Find the dependency tree (e.g., `mvn dependency:tree`), and look for
`io.grpc:grpc-okhttp`. If you don't have `grpc-okhttp`, you should add it as a
dependency.
Find the dependency tree (e.g., `mvn dependency:tree`), and look for versions of:
- `io.grpc:grpc-okhttp`
- `com.squareup.okhttp:okhttp`
If you don't have `grpc-okhttp`, you should add it as a dependency.
If you have both `io.grpc:grpc-netty` and `io.grpc:grpc-okhttp`, you may also have issues. Remove `grpc-netty` if you are on Android.
If you have `okhttp` version below 2.5.0, then it may not work with gRPC.
It is OK to have both `okhttp` 2.x and 3.x since they have different group name and under different packages.
# gRPC over plaintext
@ -422,12 +441,17 @@ An option is provided to use gRPC over plaintext without TLS. While this is conv
The following code snippet shows how you can call the Google Cloud PubSub API using gRPC with a service account. The credentials are loaded from a key stored in a well-known location or by detecting that the application is running in an environment that can provide one automatically, e.g. Google Compute Engine. While this example is specific to Google and it's services, similar patterns can be followed for other service providers.
```java
// Use the default credentials from the environment
ChannelCredentials creds = GoogleDefaultChannelCredentials.create();
// Create a channel to the service
ManagedChannel channel = Grpc.newChannelBuilder("dns:///pubsub.googleapis.com", creds)
// Create a channel to the test service.
ManagedChannel channel = ManagedChannelBuilder.forTarget("dns:///pubsub.googleapis.com")
.build();
// Create a stub and send an RPC
PublisherGrpc.PublisherBlockingStub publisherStub = PublisherGrpc.newBlockingStub(channel);
// Get the default credentials from the environment
GoogleCredentials creds = GoogleCredentials.getApplicationDefault();
// Down-scope the credential to just the scopes required by the service
creds = creds.createScoped(Arrays.asList("https://www.googleapis.com/auth/pubsub"));
// Create an instance of {@link io.grpc.CallCredentials}
CallCredentials callCreds = MoreCallCredentials.from(creds);
// Create a stub with credential
PublisherGrpc.PublisherBlockingStub publisherStub =
PublisherGrpc.newBlockingStub(channel).withCallCredentials(callCreds);
publisherStub.publish(someMessage);
```

View File

@ -2,17 +2,11 @@ workspace(name = "io_grpc_grpc_java")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_java",
url = "https://github.com/bazelbuild/rules_java/releases/download/5.3.5/rules_java-5.3.5.tar.gz",
sha256 = "c73336802d0b4882e40770666ad055212df4ea62cfa6edf9cb0f9d29828a0934",
)
http_archive(
name = "rules_jvm_external",
sha256 = "d31e369b854322ca5098ea12c69d7175ded971435e55c18dd9dd5f29cc5249ac",
strip_prefix = "rules_jvm_external-5.3",
url = "https://github.com/bazelbuild/rules_jvm_external/releases/download/5.3/rules_jvm_external-5.3.tar.gz",
sha256 = "c21ce8b8c4ccac87c809c317def87644cdc3a9dd650c74f41698d761c95175f3",
strip_prefix = "rules_jvm_external-1498ac6ccd3ea9cdb84afed65aa257c57abf3e0a",
url = "https://github.com/bazelbuild/rules_jvm_external/archive/1498ac6ccd3ea9cdb84afed65aa257c57abf3e0a.zip",
)
load("@rules_jvm_external//:defs.bzl", "maven_install")
@ -22,26 +16,32 @@ load("//:repositories.bzl", "grpc_java_repositories")
grpc_java_repositories()
load("@bazel_jar_jar//:jar_jar.bzl", "jar_jar_repositories")
jar_jar_repositories()
load("@com_google_protobuf//:protobuf_deps.bzl", "PROTOBUF_MAVEN_ARTIFACTS")
load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps")
protobuf_deps()
load("@envoy_api//bazel:repositories.bzl", "api_dependencies")
api_dependencies()
load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_language")
switched_rules_by_language(
name = "com_google_googleapis_imports",
java = True,
)
maven_install(
artifacts = IO_GRPC_GRPC_JAVA_ARTIFACTS + PROTOBUF_MAVEN_ARTIFACTS,
generate_compat_repositories = True,
override_targets = IO_GRPC_GRPC_JAVA_OVERRIDE_TARGETS,
repositories = [
"https://repo.maven.apache.org/maven2/",
],
strict_visibility = True,
)
load("@maven//:compat.bzl", "compat_repositories")
compat_repositories()

View File

@ -1 +0,0 @@
# When using bzlmod this makes sure nothing from the legacy WORKSPACE is loaded

View File

@ -10,13 +10,11 @@ description = "gRPC: All"
def subprojects = [
project(':grpc-api'),
project(':grpc-auth'),
project(':grpc-context'),
project(':grpc-core'),
project(':grpc-grpclb'),
project(':grpc-gcp-csm-observability'),
project(':grpc-inprocess'),
project(':grpc-netty'),
project(':grpc-okhttp'),
project(':grpc-opentelemetry'),
project(':grpc-protobuf'),
project(':grpc-protobuf-lite'),
project(':grpc-rls'),
@ -25,7 +23,6 @@ def subprojects = [
project(':grpc-servlet-jakarta'),
project(':grpc-stub'),
project(':grpc-testing'),
project(':grpc-util'),
project(':grpc-xds'),
]
@ -39,7 +36,6 @@ evaluationDependsOn(':grpc-interop-testing')
dependencies {
api subprojects.minus([project(':grpc-protobuf-lite')])
implementation libraries.guava.jre // JRE required by transitive protobuf-java-util
}
tasks.named("javadoc").configure {
@ -51,15 +47,23 @@ tasks.named("javadoc").configure {
continue;
}
source subproject.javadoc.source
options.linksOffline.addAll subproject.javadoc.options.linksOffline
options.links subproject.javadoc.options.links.toArray(new String[0])
}
}
tasks.named("jacocoTestReport").configure {
tasks.register("jacocoMerge", JacocoMerge) {
dependsOn(subprojects.jacocoTestReport.dependsOn)
dependsOn(project(':grpc-interop-testing').jacocoTestReport.dependsOn)
mustRunAfter(subprojects.jacocoTestReport.mustRunAfter)
mustRunAfter(project(':grpc-interop-testing').jacocoTestReport.mustRunAfter)
executionData.from files(subprojects.jacocoTestReport.executionData)
destinationFile = file("${buildDir}/jacoco/test.exec")
executionData = files(subprojects.jacocoTestReport.executionData)
.plus(project(':grpc-interop-testing').jacocoTestReport.executionData)
.filter { f -> f.exists() }
}
tasks.named("jacocoTestReport").configure {
dependsOn(jacocoMerge)
reports {
xml.required = true
html.required = true

View File

@ -1,4 +1,3 @@
load("@rules_jvm_external//:defs.bzl", "artifact")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("//:java_grpc_library.bzl", "java_grpc_library")
@ -15,16 +14,16 @@ java_library(
"//grpclb",
"//netty",
"//stub",
"@com_google_code_findbugs_jsr305//jar",
"@com_google_guava_guava//jar",
"@com_google_j2objc_j2objc_annotations//jar",
"@com_google_protobuf//:protobuf_java",
"@com_google_protobuf//:protobuf_java_util",
artifact("com.google.code.findbugs:jsr305"),
artifact("com.google.errorprone:error_prone_annotations"),
artifact("com.google.guava:guava"),
artifact("io.netty:netty-buffer"),
artifact("io.netty:netty-codec"),
artifact("io.netty:netty-common"),
artifact("io.netty:netty-handler"),
artifact("io.netty:netty-transport"),
"@io_netty_netty_buffer//jar",
"@io_netty_netty_codec//jar",
"@io_netty_netty_common//jar",
"@io_netty_netty_handler//jar",
"@io_netty_netty_transport//jar",
],
)
@ -36,18 +35,19 @@ java_library(
visibility = ["//visibility:public"],
deps = [
":alts_internal",
":handshaker_java_grpc",
":handshaker_java_proto",
":handshaker_java_grpc",
"//api",
"//auth",
"//core:internal",
"//netty",
artifact("com.google.auth:google-auth-library-oauth2-http"),
artifact("com.google.code.findbugs:jsr305"),
artifact("com.google.guava:guava"),
artifact("io.netty:netty-common"),
artifact("io.netty:netty-handler"),
artifact("io.netty:netty-transport"),
"@com_google_auth_google_auth_library_oauth2_http//jar",
"@com_google_code_findbugs_jsr305//jar",
"@com_google_guava_guava//jar",
"@com_google_j2objc_j2objc_annotations//jar",
"@io_netty_netty_common//jar",
"@io_netty_netty_handler//jar",
"@io_netty_netty_transport//jar",
],
)

View File

@ -2,24 +2,24 @@ plugins {
id "java-library"
id "maven-publish"
id "com.github.johnrengelman.shadow"
id "com.google.protobuf"
id "com.gradleup.shadow"
id "ru.vyarus.animalsniffer"
}
description = "gRPC: ALTS"
evaluationDependsOn(project(':grpc-core').path)
dependencies {
api project(':grpc-api')
api project(':grpc-core')
implementation project(':grpc-auth'),
project(':grpc-core'),
project(":grpc-context"), // Override google-auth dependency with our newer version
project(':grpc-grpclb'),
project(':grpc-protobuf'),
project(':grpc-stub'),
libraries.protobuf.java,
libraries.conscrypt,
libraries.guava.jre, // JRE required by protobuf-java-util from grpclb
libraries.guava,
libraries.google.auth.oauth2Http
def nettyDependency = implementation project(':grpc-netty')
compileOnly libraries.javax.annotation
@ -28,15 +28,16 @@ dependencies {
shadow project(path: ':grpc-netty-shaded', configuration: 'shadow')
testImplementation project(':grpc-testing'),
testFixtures(project(':grpc-core')),
project(':grpc-inprocess'),
project(':grpc-core').sourceSets.test.output,
project(':grpc-testing-proto'),
libraries.guava,
libraries.junit,
libraries.mockito.core,
libraries.truth
testImplementation libraries.guava.testlib
testImplementation (libraries.guava.testlib) {
exclude group: 'junit', module: 'junit'
}
testRuntimeOnly libraries.netty.tcnative,
libraries.netty.tcnative.classes
testRuntimeOnly (libraries.netty.transport.epoll) {
@ -44,11 +45,7 @@ dependencies {
classifier = "linux-x86_64"
}
}
signature (libraries.signature.java) {
artifact {
extension = "signature"
}
}
signature libraries.signature.java
}
configureProtoCompilation()
@ -56,6 +53,10 @@ configureProtoCompilation()
import net.ltgt.gradle.errorprone.CheckSeverity
[tasks.named("compileJava"), tasks.named("compileTestJava")]*.configure {
// protobuf calls valueof. Will be fixed in next release (google/protobuf#4046)
options.compilerArgs += [
"-Xlint:-deprecation"
]
// ALTS returns a lot of futures that we mostly don't care about.
options.errorprone.check("FutureReturnValueIgnored", CheckSeverity.OFF)
}
@ -68,9 +69,6 @@ tasks.named("javadoc").configure {
tasks.named("jar").configure {
// Must use a different archiveClassifier to avoid conflicting with shadowJar
archiveClassifier = 'original'
manifest {
attributes('Automatic-Module-Name': 'io.grpc.alts')
}
}
// We want to use grpc-netty-shaded instead of grpc-netty. But we also want our
@ -97,7 +95,8 @@ publishing {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', dep.group)
dependencyNode.appendNode('artifactId', dep.name)
dependencyNode.appendNode('version', dep.version)
def version = (dep.name == 'grpc-netty-shaded') ? '[' + dep.version + ']' : dep.version
dependencyNode.appendNode('version', version)
dependencyNode.appendNode('scope', 'compile')
}
asNode().dependencies[0].replaceNode(dependenciesNode)

View File

@ -4,12 +4,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
/**
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/gcp/handshaker.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class HandshakerServiceGrpc {
private HandshakerServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.gcp.HandshakerService";
public static final String SERVICE_NAME = "grpc.gcp.HandshakerService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.alts.internal.HandshakerReq,
@ -57,21 +60,6 @@ public final class HandshakerServiceGrpc {
return HandshakerServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static HandshakerServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<HandshakerServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<HandshakerServiceBlockingV2Stub>() {
@java.lang.Override
public HandshakerServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new HandshakerServiceBlockingV2Stub(channel, callOptions);
}
};
return HandshakerServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -169,40 +157,6 @@ public final class HandshakerServiceGrpc {
/**
* A stub to allow clients to do synchronous rpc calls to service HandshakerService.
*/
public static final class HandshakerServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<HandshakerServiceBlockingV2Stub> {
private HandshakerServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected HandshakerServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new HandshakerServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Handshaker service accepts a stream of handshaker request, returning a
* stream of handshaker response. Client is expected to send exactly one
* message with either client_start or server_start followed by one or more
* messages with next. Each time client sends a request, the handshaker
* service expects to respond. Client does not have to wait for service's
* response before sending next request.
* </pre>
*/
@io.grpc.ExperimentalApi("https://github.com/grpc/grpc-java/issues/10918")
public io.grpc.stub.BlockingClientCall<io.grpc.alts.internal.HandshakerReq, io.grpc.alts.internal.HandshakerResp>
doHandshake() {
return io.grpc.stub.ClientCalls.blockingBidiStreamingCall(
getChannel(), getDoHandshakeMethod(), getCallOptions());
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service HandshakerService.
*/
public static final class HandshakerServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<HandshakerServiceBlockingStub> {
private HandshakerServiceBlockingStub(
@ -307,9 +261,9 @@ public final class HandshakerServiceGrpc {
private static final class HandshakerServiceMethodDescriptorSupplier
extends HandshakerServiceBaseDescriptorSupplier
implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
private final java.lang.String methodName;
private final String methodName;
HandshakerServiceMethodDescriptorSupplier(java.lang.String methodName) {
HandshakerServiceMethodDescriptorSupplier(String methodName) {
this.methodName = methodName;
}

View File

@ -18,7 +18,7 @@ package io.grpc.alts;
import com.google.common.annotations.VisibleForTesting;
import io.grpc.ExperimentalApi;
import io.grpc.ForwardingChannelBuilder2;
import io.grpc.ForwardingChannelBuilder;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.internal.GrpcUtil;
@ -29,16 +29,16 @@ import javax.annotation.Nullable;
/**
* ALTS version of {@code ManagedChannelBuilder}. This class sets up a secure and authenticated
* communication between two cloud VMs using ALTS.
* commmunication between two cloud VMs using ALTS.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151")
public final class AltsChannelBuilder extends ForwardingChannelBuilder2<AltsChannelBuilder> {
public final class AltsChannelBuilder extends ForwardingChannelBuilder<AltsChannelBuilder> {
private final NettyChannelBuilder delegate;
private final AltsChannelCredentials.Builder credentialsBuilder =
new AltsChannelCredentials.Builder();
/** "Overrides" the static method in {@link ManagedChannelBuilder}. */
public static AltsChannelBuilder forTarget(String target) {
public static final AltsChannelBuilder forTarget(String target) {
return new AltsChannelBuilder(target);
}

View File

@ -36,7 +36,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Provides secure and authenticated communication between two cloud VMs using ALTS.
* Provides secure and authenticated commmunication between two cloud VMs using ALTS.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/4151")
public final class AltsChannelCredentials {

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

@ -35,7 +35,7 @@ public final class ComputeEngineChannelBuilder
}
/** "Overrides" the static method in {@link ManagedChannelBuilder}. */
public static ComputeEngineChannelBuilder forTarget(String target) {
public static final ComputeEngineChannelBuilder forTarget(String target) {
return new ComputeEngineChannelBuilder(target);
}
@ -45,7 +45,6 @@ public final class ComputeEngineChannelBuilder
}
@Override
@SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI.
protected NettyChannelBuilder delegate() {
return delegate;
}

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

@ -38,4 +38,7 @@ final class FailingCallCredentials extends CallCredentials {
CallCredentials.MetadataApplier applier) {
applier.fail(status);
}
@Override
public void thisUsesUnstableApi() {}
}

View File

@ -35,7 +35,7 @@ public final class GoogleDefaultChannelBuilder
}
/** "Overrides" the static method in {@link ManagedChannelBuilder}. */
public static GoogleDefaultChannelBuilder forTarget(String target) {
public static final GoogleDefaultChannelBuilder forTarget(String target) {
return new GoogleDefaultChannelBuilder(target);
}
@ -45,7 +45,6 @@ public final class GoogleDefaultChannelBuilder
}
@Override
@SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI.
protected NettyChannelBuilder delegate() {
return delegate;
}

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

View File

@ -33,7 +33,7 @@ class AltsHandshakerStub {
private final HandshakerServiceStub serviceStub;
private final ArrayBlockingQueue<Optional<HandshakerResp>> responseQueue =
new ArrayBlockingQueue<>(1);
private final AtomicReference<ThrowableInfo> exceptionMessage = new AtomicReference<>();
private final AtomicReference<String> exceptionMessage = new AtomicReference<>();
private static final long HANDSHAKE_RPC_DEADLINE_SECS = 20;
@ -72,7 +72,7 @@ class AltsHandshakerStub {
}
if (exceptionMessage.get() != null) {
throw new IOException(exceptionMessage.get().info, exceptionMessage.get().throwable);
throw new IOException(exceptionMessage.get());
} else {
throw new IOException("No handshaker response received");
}
@ -89,7 +89,7 @@ class AltsHandshakerStub {
/** Throw exception if there is an outstanding exception. */
private void maybeThrowIoException() throws IOException {
if (exceptionMessage.get() != null) {
throw new IOException(exceptionMessage.get().info, exceptionMessage.get().throwable);
throw new IOException(exceptionMessage.get());
}
}
@ -108,7 +108,7 @@ class AltsHandshakerStub {
AltsHandshakerStub.this.responseQueue.add(Optional.of(resp));
} catch (IllegalStateException e) {
AltsHandshakerStub.this.exceptionMessage.compareAndSet(
null, new ThrowableInfo(e, "Received an unexpected response."));
null, "Received an unexpected response.");
AltsHandshakerStub.this.close();
}
}
@ -117,7 +117,7 @@ class AltsHandshakerStub {
@Override
public void onError(Throwable t) {
AltsHandshakerStub.this.exceptionMessage.compareAndSet(
null, new ThrowableInfo(t, "Received a terminating error."));
null, "Received a terminating error: " + t.toString());
// Trigger the release of any blocked send.
Optional<HandshakerResp> result = Optional.absent();
AltsHandshakerStub.this.responseQueue.offer(result);
@ -126,22 +126,10 @@ class AltsHandshakerStub {
/** Receive the closing message from the server. */
@Override
public void onCompleted() {
AltsHandshakerStub.this.exceptionMessage.compareAndSet(
null, new ThrowableInfo(null, "Response stream closed."));
AltsHandshakerStub.this.exceptionMessage.compareAndSet(null, "Response stream closed.");
// Trigger the release of any blocked send.
Optional<HandshakerResp> result = Optional.absent();
AltsHandshakerStub.this.responseQueue.offer(result);
}
}
private static class ThrowableInfo {
private final Throwable throwable;
private final String info;
private ThrowableInfo(Throwable throwable, String info) {
this.throwable = throwable;
this.info = info;
}
}
}

View File

@ -54,12 +54,10 @@ import javax.annotation.Nullable;
// TODO(carl-mastrangelo): rename this AltsProtocolNegotiators.
public final class AltsProtocolNegotiator {
private static final Logger logger = Logger.getLogger(AltsProtocolNegotiator.class.getName());
static final String ALTS_MAX_CONCURRENT_HANDSHAKES_ENV_VARIABLE =
"GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES";
@VisibleForTesting static final int DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES = 32;
private static final AsyncSemaphore handshakeSemaphore =
new AsyncSemaphore(getAltsMaxConcurrentHandshakes());
// Avoid performing too many handshakes in parallel, as it may cause queuing in the handshake
// server and cause unbounded blocking on the event loop (b/168808426). This is a workaround until
// there is an async TSI handshaking API to avoid the blocking.
private static final AsyncSemaphore handshakeSemaphore = new AsyncSemaphore(32);
@Grpc.TransportAttr
public static final Attributes.Key<TsiPeer> TSI_PEER_KEY =
@ -426,30 +424,5 @@ public final class AltsProtocolNegotiator {
}
}
@VisibleForTesting
static int getAltsMaxConcurrentHandshakes(String altsMaxConcurrentHandshakes) {
if (altsMaxConcurrentHandshakes == null) {
return DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES;
}
try {
int effectiveMaxConcurrentHandshakes = Integer.parseInt(altsMaxConcurrentHandshakes);
if (effectiveMaxConcurrentHandshakes < 0) {
logger.warning(
"GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES environment variable set to invalid value.");
return DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES;
}
return effectiveMaxConcurrentHandshakes;
} catch (NumberFormatException e) {
logger.warning(
"GRPC_ALTS_MAX_CONCURRENT_HANDSHAKES environment variable set to invalid value.");
return DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES;
}
}
private static int getAltsMaxConcurrentHandshakes() {
return getAltsMaxConcurrentHandshakes(
System.getenv(ALTS_MAX_CONCURRENT_HANDSHAKES_ENV_VARIABLE));
}
private AltsProtocolNegotiator() {}
}

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

@ -78,7 +78,7 @@ public final class ProtectedPromise extends DefaultChannelPromise {
if (!doneAllocating) {
doneAllocating = true;
if (successfulCount == expectedCount) {
trySuccessInternal();
trySuccessInternal(null);
return super.setSuccess(null);
}
}
@ -117,18 +117,18 @@ public final class ProtectedPromise extends DefaultChannelPromise {
}
@Override
public ChannelPromise setSuccess(Void unused) {
trySuccess(null);
public ChannelPromise setSuccess(Void result) {
trySuccess(result);
return this;
}
@Override
public boolean trySuccess(Void unused) {
public boolean trySuccess(Void result) {
if (awaitingPromises()) {
++successfulCount;
if (successfulCount == expectedCount && doneAllocating) {
trySuccessInternal();
return super.trySuccess(null);
trySuccessInternal(result);
return super.trySuccess(result);
}
// TODO: We break the interface a bit here.
// Multiple success events can be processed without issue because this is an aggregation.
@ -137,9 +137,9 @@ public final class ProtectedPromise extends DefaultChannelPromise {
return false;
}
private void trySuccessInternal() {
private void trySuccessInternal(Void result) {
for (int i = 0; i < unprotectedPromises.size(); ++i) {
unprotectedPromises.get(i).trySuccess(null);
unprotectedPromises.get(i).trySuccess(result);
}
}

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

@ -32,7 +32,7 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class AltsHandshakerStubTest {
/** Mock status of handshaker service. */
private enum Status {
private static enum Status {
OK,
ERROR,
COMPLETE
@ -68,7 +68,6 @@ public class AltsHandshakerStubTest {
fail("Exception expected");
} catch (IOException ex) {
assertThat(ex).hasMessageThat().contains("Received a terminating error");
assertThat(ex.getCause()).hasMessageThat().contains("Root cause message");
}
}
@ -153,7 +152,7 @@ public class AltsHandshakerStubTest {
reader.onNext(resp.setOutFrames(req.getNext().getInBytes()).build());
break;
case ERROR:
reader.onError(new RuntimeException("Root cause message"));
reader.onError(new RuntimeException());
break;
case COMPLETE:
reader.onCompleted();

View File

@ -354,29 +354,6 @@ public class AltsProtocolNegotiatorTest {
.isEqualTo(SecurityLevel.PRIVACY_AND_INTEGRITY);
}
@Test
public void getAltsMaxConcurrentHandshakes_success() throws Exception {
assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes("10")).isEqualTo(10);
}
@Test
public void getAltsMaxConcurrentHandshakes_envVariableNotSet() throws Exception {
assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes(null))
.isEqualTo(AltsProtocolNegotiator.DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES);
}
@Test
public void getAltsMaxConcurrentHandshakes_envVariableNotANumber() throws Exception {
assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes("not-a-number"))
.isEqualTo(AltsProtocolNegotiator.DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES);
}
@Test
public void getAltsMaxConcurrentHandshakes_envVariableNegative() throws Exception {
assertThat(AltsProtocolNegotiator.getAltsMaxConcurrentHandshakes("-10"))
.isEqualTo(AltsProtocolNegotiator.DEFAULT_ALTS_MAX_CONCURRENT_HANDSHAKES);
}
private void doHandshake() throws Exception {
// Capture the client frame and add to the server.
assertEquals(1, channel.outboundMessages().size());

View File

@ -68,7 +68,6 @@ public class FakeTsiHandshaker implements TsiHandshaker {
SERVER_FINISHED;
// Returns the next State. In order to advance to sendState=N, receiveState must be N-1.
@SuppressWarnings("EnumOrdinal")
public State next() {
if (ordinal() + 1 < values().length) {
return values()[ordinal() + 1];
@ -148,7 +147,7 @@ public class FakeTsiHandshaker implements TsiHandshaker {
return;
}
// Prepare the next message, if needed.
// Prepare the next message, if neeeded.
if (sendBuffer == null) {
if (sendState.next() != receiveState) {
// We're still waiting for bytes from the peer, so bail.

View File

@ -36,7 +36,7 @@ import javax.crypto.AEADBadTagException;
/** Utility class that provides tests for implementations of {@link TsiHandshaker}. */
public final class TsiTest {
private static final String DECRYPTION_FAILURE_RE = "Tag mismatch|BAD_DECRYPT";
private static final String DECRYPTION_FAILURE_RE = "Tag mismatch!|BAD_DECRYPT";
private TsiTest() {}

View File

@ -7,10 +7,10 @@ description = 'gRPC: Android Integration Testing'
repositories {
google()
mavenCentral()
}
android {
namespace = 'io.grpc.android.integrationtest'
sourceSets {
main {
java {
@ -29,19 +29,16 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
compileSdkVersion 34
compileSdkVersion 29
defaultConfig {
applicationId "io.grpc.android.integrationtest"
// Held back to 20 as Gradle fails to build at the 21 level. This is
// presumably a Gradle bug that can be revisited later.
// Maybe this issue: https://github.com/gradle/gradle/issues/20778
minSdkVersion 20
targetSdkVersion 33
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled = true
multiDexEnabled true
}
buildTypes {
debug { minifyEnabled false }
@ -51,13 +48,9 @@ android {
}
}
lintOptions {
disable 'InvalidPackage', 'HardcodedText', 'UsingOnClickInXml',
disable 'InvalidPackage', 'HardcodedText',
'MissingClass' // https://github.com/grpc/grpc-java/issues/8799
}
packagingOptions {
exclude 'META-INF/INDEX.LIST'
exclude 'META-INF/io.netty.versions.properties'
}
}
dependencies {
@ -66,21 +59,23 @@ dependencies {
implementation libraries.androidx.annotation
implementation 'com.google.android.gms:play-services-base:18.0.1'
implementation project(':grpc-android'),
project(':grpc-core'),
implementation project(':grpc-auth'),
project(':grpc-census'),
project(':grpc-okhttp'),
project(':grpc-protobuf-lite'),
project(':grpc-stub'),
project(':grpc-testing'),
libraries.hdrhistogram,
libraries.junit,
libraries.truth,
libraries.androidx.test.rules,
libraries.opencensus.contrib.grpc.metrics
implementation (libraries.google.auth.oauth2Http) {
exclude group: 'org.apache.httpcomponents'
}
implementation (project(':grpc-services')) {
exclude group: 'com.google.protobuf'
exclude group: 'com.google.guava'
}
compileOnly libraries.javax.annotation
@ -108,7 +103,7 @@ import net.ltgt.gradle.errorprone.CheckSeverity
tasks.withType(JavaCompile).configureEach {
options.compilerArgs += [
"-Xlint:-cast",
"-Xlint:-cast"
]
appendToProperty(it.options.errorprone.excludedPaths, ".*/R.java", "|")
appendToProperty(
@ -117,16 +112,4 @@ tasks.withType(JavaCompile).configureEach {
"|")
}
afterEvaluate {
// Hack to workaround "Task ':grpc-android-interop-testing:extractIncludeDebugProto' uses this
// output of task ':grpc-context:jar' without declaring an explicit or implicit dependency." The
// issue started when grpc-context became empty.
tasks.named('extractIncludeDebugProto').configure {
dependsOn project(':grpc-context').tasks.named('jar')
}
tasks.named('extractIncludeReleaseProto').configure {
dependsOn project(':grpc-context').tasks.named('jar')
}
}
configureProtoCompilation()

View File

@ -21,7 +21,3 @@
# Ignores: can't find referenced method from grpc-testing's compileOnly dependency on Truth
-dontwarn io.grpc.testing.DeadlineSubject
-keepclassmembers class io.grpc.testing.integration.Messages$* {
*;
}

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.grpc.android.integrationtest.test" >
<instrumentation
android:name="androidx.test.runner.AndroidJUnitRunner"

View File

@ -25,12 +25,10 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.security.ProviderInstaller;
import com.google.common.util.concurrent.SettableFuture;
import io.grpc.android.integrationtest.InteropTask.Listener;
import java.io.InputStream;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -46,7 +44,6 @@ public class InteropInstrumentationTest {
private String serverHostOverride;
private boolean useTestCa;
private String testCase;
private ExecutorService executor = Executors.newSingleThreadExecutor();
@Before
public void setUp() throws Exception {
@ -104,22 +101,26 @@ public class InteropInstrumentationTest {
}
private void runTest(String testCase) throws Exception {
final SettableFuture<String> resultFuture = SettableFuture.create();
InteropTask.Listener listener =
new Listener() {
@Override
public void onComplete(String result) {
resultFuture.set(result);
}
};
InputStream testCa;
if (useTestCa) {
testCa = ApplicationProvider.getApplicationContext().getResources().openRawResource(R.raw.ca);
} else {
testCa = null;
}
String result = null;
try {
result = executor.submit(new TestCallable(
TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, useTls, testCa),
testCase)).get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
} catch (ExecutionException | InterruptedException | TimeoutException e) {
Log.e(LOG_TAG, "Error while executing test case " + testCase, e);
result = e.getMessage();
}
assertEquals(testCase + " failed", TestCallable.SUCCESS_MESSAGE, result);
new InteropTask(
listener,
TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, useTls, testCa),
testCase)
.execute();
String result = resultFuture.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
assertEquals(testCase + " failed", InteropTask.SUCCESS_MESSAGE, result);
}
}

View File

@ -1,129 +0,0 @@
/*
* Copyright 2021 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.android.integrationtest;
import static org.junit.Assert.assertEquals;
import android.net.LocalSocketAddress.Namespace;
import androidx.test.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.rule.ActivityTestRule;
import io.grpc.Grpc;
import io.grpc.InsecureServerCredentials;
import io.grpc.Server;
import io.grpc.android.UdsChannelBuilder;
import io.grpc.testing.integration.TestServiceImpl;
import java.io.IOException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Tests for channels created with {@link UdsChannelBuilder}. The UDS Channel is only meant to talk
* to Unix Domain Socket endpoints on servers that are on-device, so a {@link LocalTestServer} is
* set up to expose a UDS endpoint.
*/
@RunWith(AndroidJUnit4.class)
public class UdsChannelInteropTest {
private static final int TIMEOUT_SECONDS = 150;
private static final String UDS_PATH = "udspath";
private String testCase;
private Server server;
private UdsTcpEndpointConnector endpointConnector;
private ScheduledExecutorService serverExecutor = Executors.newScheduledThreadPool(2);
private ExecutorService testExecutor = Executors.newSingleThreadExecutor();
// Ensures Looper is initialized for tests running on API level 15. Otherwise instantiating an
// AsyncTask throws an exception.
@Rule
public ActivityTestRule<TesterActivity> activityRule =
new ActivityTestRule<TesterActivity>(TesterActivity.class);
@Before
public void setUp() throws IOException {
testCase = InstrumentationRegistry.getArguments().getString("test_case", "all");
// Start local server.
server =
Grpc.newServerBuilderForPort(0, InsecureServerCredentials.create())
.maxInboundMessageSize(16 * 1024 * 1024)
.addService(new TestServiceImpl(serverExecutor))
.build();
server.start();
// Connect uds endpoint to server's endpoint.
endpointConnector = new UdsTcpEndpointConnector(UDS_PATH, "0.0.0.0", server.getPort());
endpointConnector.start();
}
@After
public void teardown() {
server.shutdownNow();
endpointConnector.shutDown();
}
@Test
public void interopTests() throws Exception {
if (testCase.equals("all")) {
runTest("empty_unary");
runTest("large_unary");
runTest("client_streaming");
runTest("server_streaming");
runTest("ping_pong");
runTest("empty_stream");
runTest("cancel_after_begin");
runTest("cancel_after_first_response");
runTest("full_duplex_call_should_succeed");
runTest("half_duplex_call_should_succeed");
runTest("server_streaming_should_be_flow_controlled");
runTest("very_large_request");
runTest("very_large_response");
runTest("deadline_not_exceeded");
runTest("deadline_exceeded");
runTest("deadline_exceeded_server_streaming");
runTest("unimplemented_method");
runTest("timeout_on_sleeping_server");
runTest("graceful_shutdown");
} else {
runTest(testCase);
}
}
private void runTest(String testCase) throws Exception {
String result = null;
try {
result = testExecutor.submit(new TestCallable(
UdsChannelBuilder.forPath(UDS_PATH, Namespace.ABSTRACT)
.maxInboundMessageSize(16 * 1024 * 1024)
.build(),
testCase)).get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
assertEquals(testCase + " failed", TestCallable.SUCCESS_MESSAGE, result);
} catch (ExecutionException | InterruptedException e) {
result = e.getMessage();
}
}
}

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class LoadBalancerStatsServiceGrpc {
private LoadBalancerStatsServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
public static final String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.LoadBalancerStatsRequest,
@ -89,21 +92,6 @@ public final class LoadBalancerStatsServiceGrpc {
return LoadBalancerStatsServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static LoadBalancerStatsServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub>() {
@java.lang.Override
public LoadBalancerStatsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
};
return LoadBalancerStatsServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -224,46 +212,6 @@ public final class LoadBalancerStatsServiceGrpc {
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingV2Stub> {
private LoadBalancerStatsServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected LoadBalancerStatsServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Gets the backend distribution for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientStatsMethod(), getCallOptions(), request);
}
/**
* <pre>
* Gets the accumulated stats for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service LoadBalancerStatsService.
* <pre>
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingStub> {
private LoadBalancerStatsServiceBlockingStub(

View File

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

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service used to control reconnect server.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class ReconnectServiceGrpc {
private ReconnectServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.ReconnectService";
public static final String SERVICE_NAME = "grpc.testing.ReconnectService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ReconnectParams,
@ -89,21 +92,6 @@ public final class ReconnectServiceGrpc {
return ReconnectServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static ReconnectServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub>() {
@java.lang.Override
public ReconnectServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
};
return ReconnectServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class ReconnectServiceGrpc {
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingV2Stub> {
private ReconnectServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected ReconnectServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStartMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStopMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service ReconnectService.
* <pre>
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingStub> {
private ReconnectServiceBlockingStub(

View File

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

View File

@ -8,12 +8,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* that case.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class UnimplementedServiceGrpc {
private UnimplementedServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.UnimplementedService";
public static final String SERVICE_NAME = "grpc.testing.UnimplementedService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
@ -60,21 +63,6 @@ public final class UnimplementedServiceGrpc {
return UnimplementedServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static UnimplementedServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub>() {
@java.lang.Override
public UnimplementedServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
};
return UnimplementedServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -178,37 +166,6 @@ public final class UnimplementedServiceGrpc {
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingV2Stub> {
private UnimplementedServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected UnimplementedServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* A call that no server should implement
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnimplementedCallMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service UnimplementedService.
* <pre>
* A simple service NOT implemented at servers so clients can test for
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingStub> {
private UnimplementedServiceBlockingStub(

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class XdsUpdateClientConfigureServiceGrpc {
private XdsUpdateClientConfigureServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ClientConfigureRequest,
@ -59,21 +62,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
return XdsUpdateClientConfigureServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateClientConfigureServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateClientConfigureServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateClientConfigureServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -173,36 +161,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingV2Stub> {
private XdsUpdateClientConfigureServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateClientConfigureServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Update the tes client's configuration.
* </pre>
*/
public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getConfigureMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateClientConfigureService.
* <pre>
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingStub> {
private XdsUpdateClientConfigureServiceBlockingStub(

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service to remotely control health status of an xDS test server.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class XdsUpdateHealthServiceGrpc {
private XdsUpdateHealthServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
@ -89,21 +92,6 @@ public final class XdsUpdateHealthServiceGrpc {
return XdsUpdateHealthServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateHealthServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateHealthServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateHealthServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class XdsUpdateHealthServiceGrpc {
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingV2Stub> {
private XdsUpdateHealthServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateHealthServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetServingMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetNotServingMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateHealthService.
* <pre>
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingStub> {
private XdsUpdateHealthServiceBlockingStub(

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class LoadBalancerStatsServiceGrpc {
private LoadBalancerStatsServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
public static final String SERVICE_NAME = "grpc.testing.LoadBalancerStatsService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.LoadBalancerStatsRequest,
@ -89,21 +92,6 @@ public final class LoadBalancerStatsServiceGrpc {
return LoadBalancerStatsServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static LoadBalancerStatsServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<LoadBalancerStatsServiceBlockingV2Stub>() {
@java.lang.Override
public LoadBalancerStatsServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
};
return LoadBalancerStatsServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -224,46 +212,6 @@ public final class LoadBalancerStatsServiceGrpc {
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingV2Stub> {
private LoadBalancerStatsServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected LoadBalancerStatsServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new LoadBalancerStatsServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Gets the backend distribution for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerStatsResponse getClientStats(io.grpc.testing.integration.Messages.LoadBalancerStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientStatsMethod(), getCallOptions(), request);
}
/**
* <pre>
* Gets the accumulated stats for RPCs sent by a test client.
* </pre>
*/
public io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsResponse getClientAccumulatedStats(io.grpc.testing.integration.Messages.LoadBalancerAccumulatedStatsRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getGetClientAccumulatedStatsMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service LoadBalancerStatsService.
* <pre>
* A service used to obtain stats for verifying LB behavior.
* </pre>
*/
public static final class LoadBalancerStatsServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<LoadBalancerStatsServiceBlockingStub> {
private LoadBalancerStatsServiceBlockingStub(

View File

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

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service used to control reconnect server.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class ReconnectServiceGrpc {
private ReconnectServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.ReconnectService";
public static final String SERVICE_NAME = "grpc.testing.ReconnectService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ReconnectParams,
@ -89,21 +92,6 @@ public final class ReconnectServiceGrpc {
return ReconnectServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static ReconnectServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<ReconnectServiceBlockingV2Stub>() {
@java.lang.Override
public ReconnectServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
};
return ReconnectServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class ReconnectServiceGrpc {
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingV2Stub> {
private ReconnectServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected ReconnectServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new ReconnectServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty start(io.grpc.testing.integration.Messages.ReconnectParams request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStartMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.Messages.ReconnectInfo stop(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getStopMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service ReconnectService.
* <pre>
* A service used to control reconnect server.
* </pre>
*/
public static final class ReconnectServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<ReconnectServiceBlockingStub> {
private ReconnectServiceBlockingStub(

View File

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

View File

@ -8,12 +8,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* that case.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class UnimplementedServiceGrpc {
private UnimplementedServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.UnimplementedService";
public static final String SERVICE_NAME = "grpc.testing.UnimplementedService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
@ -60,21 +63,6 @@ public final class UnimplementedServiceGrpc {
return UnimplementedServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static UnimplementedServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<UnimplementedServiceBlockingV2Stub>() {
@java.lang.Override
public UnimplementedServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
};
return UnimplementedServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -178,37 +166,6 @@ public final class UnimplementedServiceGrpc {
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingV2Stub> {
private UnimplementedServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected UnimplementedServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new UnimplementedServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* A call that no server should implement
* </pre>
*/
public io.grpc.testing.integration.EmptyProtos.Empty unimplementedCall(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getUnimplementedCallMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service UnimplementedService.
* <pre>
* A simple service NOT implemented at servers so clients can test for
* that case.
* </pre>
*/
public static final class UnimplementedServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<UnimplementedServiceBlockingStub> {
private UnimplementedServiceBlockingStub(

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class XdsUpdateClientConfigureServiceGrpc {
private XdsUpdateClientConfigureServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateClientConfigureService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.Messages.ClientConfigureRequest,
@ -59,21 +62,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
return XdsUpdateClientConfigureServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateClientConfigureServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateClientConfigureServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateClientConfigureServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateClientConfigureServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -173,36 +161,6 @@ public final class XdsUpdateClientConfigureServiceGrpc {
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingV2Stub> {
private XdsUpdateClientConfigureServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateClientConfigureServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateClientConfigureServiceBlockingV2Stub(channel, callOptions);
}
/**
* <pre>
* Update the tes client's configuration.
* </pre>
*/
public io.grpc.testing.integration.Messages.ClientConfigureResponse configure(io.grpc.testing.integration.Messages.ClientConfigureRequest request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getConfigureMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateClientConfigureService.
* <pre>
* A service to dynamically update the configuration of an xDS test client.
* </pre>
*/
public static final class XdsUpdateClientConfigureServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateClientConfigureServiceBlockingStub> {
private XdsUpdateClientConfigureServiceBlockingStub(

View File

@ -7,12 +7,15 @@ import static io.grpc.MethodDescriptor.generateFullMethodName;
* A service to remotely control health status of an xDS test server.
* </pre>
*/
@javax.annotation.Generated(
value = "by gRPC proto compiler",
comments = "Source: grpc/testing/test.proto")
@io.grpc.stub.annotations.GrpcGenerated
public final class XdsUpdateHealthServiceGrpc {
private XdsUpdateHealthServiceGrpc() {}
public static final java.lang.String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
public static final String SERVICE_NAME = "grpc.testing.XdsUpdateHealthService";
// Static method descriptors that strictly reflect the proto.
private static volatile io.grpc.MethodDescriptor<io.grpc.testing.integration.EmptyProtos.Empty,
@ -89,21 +92,6 @@ public final class XdsUpdateHealthServiceGrpc {
return XdsUpdateHealthServiceStub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports all types of calls on the service
*/
public static XdsUpdateHealthServiceBlockingV2Stub newBlockingV2Stub(
io.grpc.Channel channel) {
io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub> factory =
new io.grpc.stub.AbstractStub.StubFactory<XdsUpdateHealthServiceBlockingV2Stub>() {
@java.lang.Override
public XdsUpdateHealthServiceBlockingV2Stub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
};
return XdsUpdateHealthServiceBlockingV2Stub.newStub(factory, channel);
}
/**
* Creates a new blocking-style stub that supports unary and streaming output calls on the service
*/
@ -212,40 +200,6 @@ public final class XdsUpdateHealthServiceGrpc {
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingV2Stub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingV2Stub> {
private XdsUpdateHealthServiceBlockingV2Stub(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
super(channel, callOptions);
}
@java.lang.Override
protected XdsUpdateHealthServiceBlockingV2Stub build(
io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
return new XdsUpdateHealthServiceBlockingV2Stub(channel, callOptions);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetServingMethod(), getCallOptions(), request);
}
/**
*/
public io.grpc.testing.integration.EmptyProtos.Empty setNotServing(io.grpc.testing.integration.EmptyProtos.Empty request) throws io.grpc.StatusException {
return io.grpc.stub.ClientCalls.blockingV2UnaryCall(
getChannel(), getSetNotServingMethod(), getCallOptions(), request);
}
}
/**
* A stub to allow clients to do limited synchronous rpc calls to service XdsUpdateHealthService.
* <pre>
* A service to remotely control health status of an xDS test server.
* </pre>
*/
public static final class XdsUpdateHealthServiceBlockingStub
extends io.grpc.stub.AbstractBlockingStub<XdsUpdateHealthServiceBlockingStub> {
private XdsUpdateHealthServiceBlockingStub(

View File

@ -1,22 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
package="io.grpc.android.integrationtest" >
<uses-permission android:name="android.permission.INTERNET" />
<!-- For UDS -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk tools:overrideLibrary="io.grpc.android"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Base.V7.Theme.AppCompat.Light"
android:name="androidx.multidex.MultiDexApplication">
android:name="androidx.multidex.MultiDexApplication" >
<activity
android:name=".TesterActivity"
android:exported="true"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View File

@ -1,5 +1,5 @@
/*
* Copyright 2023 The gRPC Authors
* Copyright 2018 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,36 +16,49 @@
package io.grpc.android.integrationtest;
import android.os.AsyncTask;
import android.util.Log;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.testing.integration.AbstractInteropTest;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.Callable;
import java.lang.ref.WeakReference;
import org.junit.AssumptionViolatedException;
/**
* Used to run a single test case against a channel in a separate thread.
*/
public class TestCallable implements Callable<String> {
private final ManagedChannel channel;
private final String testCase;
/** AsyncTask for interop test cases. */
final class InteropTask extends AsyncTask<Void, Void, String> {
private static final String LOG_TAG = "GrpcInteropTask";
interface Listener {
void onComplete(String result);
}
static final String SUCCESS_MESSAGE = "Success!";
public TestCallable(ManagedChannel channel, String testCase) {
this.channel = channel;
private final WeakReference<Listener> listenerReference;
private final String testCase;
private final Tester tester;
InteropTask(
Listener listener,
ManagedChannel channel,
String testCase) {
this.listenerReference = new WeakReference<Listener>(listener);
this.testCase = testCase;
this.tester = new Tester(channel);
}
@Override
public String call() {
Tester tester = new Tester(channel);
protected void onPreExecute() {
tester.setUp();
}
@SuppressWarnings("Finally")
@Override
protected String doInBackground(Void... ignored) {
try {
runTest(tester, testCase);
runTest(testCase);
return SUCCESS_MESSAGE;
} catch (Throwable t) {
// Print the stack trace to logcat.
@ -65,7 +78,7 @@ public class TestCallable implements Callable<String> {
}
}
private void runTest(Tester tester, String testCase) throws Exception {
private void runTest(String testCase) throws Exception {
Log.i(LOG_TAG, "Running test case: " + testCase);
if ("empty_unary".equals(testCase)) {
tester.emptyUnary();
@ -125,6 +138,14 @@ public class TestCallable implements Callable<String> {
}
}
@Override
protected void onPostExecute(String result) {
Listener listener = listenerReference.get();
if (listener != null) {
listener.onComplete(result);
}
}
private static class Tester extends AbstractInteropTest {
private Tester(ManagedChannel channel) {

View File

@ -18,7 +18,6 @@ package io.grpc.android.integrationtest;
import android.content.Context;
import android.content.Intent;
import android.net.LocalSocketAddress.Namespace;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@ -31,31 +30,20 @@ import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.security.ProviderInstaller;
import io.grpc.ManagedChannel;
import io.grpc.android.UdsChannelBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TesterActivity extends AppCompatActivity
implements ProviderInstaller.ProviderInstallListener {
implements ProviderInstaller.ProviderInstallListener, InteropTask.Listener {
private static final String LOG_TAG = "GrpcTesterActivity";
private List<Button> buttons;
private EditText hostEdit;
private EditText portEdit;
private CheckBox useUdsCheckBox;
private EditText udsEdit;
private TextView resultText;
private CheckBox testCertCheckBox;
private UdsTcpEndpointConnector endpointConnector;
private ExecutorService executor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -69,26 +57,12 @@ public class TesterActivity extends AppCompatActivity
hostEdit = (EditText) findViewById(R.id.host_edit_text);
portEdit = (EditText) findViewById(R.id.port_edit_text);
useUdsCheckBox = (CheckBox) findViewById(R.id.use_uds_checkbox);
udsEdit = (EditText) findViewById(R.id.uds_proxy_edit_text);
resultText = (TextView) findViewById(R.id.grpc_response_text);
testCertCheckBox = (CheckBox) findViewById(R.id.test_cert_checkbox);
ProviderInstaller.installIfNeededAsync(this, this);
// Disable buttons until the security provider installing finishes.
enableButtons(false);
executor = Executors.newSingleThreadExecutor();
}
/** Click handler for unix domain socket. */
public void enableUds(View view) {
boolean enabled = ((CheckBox) view).isChecked();
udsEdit.setEnabled(enabled);
testCertCheckBox.setEnabled(!enabled);
if (enabled) {
testCertCheckBox.setChecked(false);
}
}
public void startEmptyUnary(View view) {
@ -117,6 +91,12 @@ public class TesterActivity extends AppCompatActivity
}
}
@Override
public void onComplete(String result) {
resultText.setText(result);
enableButtons(true);
}
private void startTest(String testCase) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
hostEdit.getWindowToken(), 0);
@ -126,9 +106,6 @@ public class TesterActivity extends AppCompatActivity
String host = hostEdit.getText().toString();
String portStr = portEdit.getText().toString();
int port = TextUtils.isEmpty(portStr) ? 8080 : Integer.valueOf(portStr);
boolean udsEnabled = useUdsCheckBox.isChecked();
String udsPath =
TextUtils.isEmpty(udsEdit.getText()) ? "default" : udsEdit.getText().toString();
String serverHostOverride;
InputStream testCert;
@ -139,39 +116,10 @@ public class TesterActivity extends AppCompatActivity
serverHostOverride = null;
testCert = null;
}
ManagedChannel channel =
TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, true, testCert);
// Create Channel
ManagedChannel channel;
if (udsEnabled) {
channel = UdsChannelBuilder.forPath(udsPath, Namespace.ABSTRACT).build();
} else {
channel = TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, true, testCert);
}
// Port-forward uds local port to server exposing tcp endpoint.
if (udsEnabled) {
endpointConnector = new UdsTcpEndpointConnector(udsPath, host, port);
try {
endpointConnector.start();
} catch (IOException e) {
Log.e(LOG_TAG, "Failed to start UDS-TCP Endpoint Connector.");
}
}
// Start Test.
String result = null;
try {
result = executor.submit(new TestCallable(channel, testCase)).get();
} catch (ExecutionException | InterruptedException e) {
result = e.getMessage();
} finally {
if (endpointConnector != null) {
endpointConnector.shutDown();
endpointConnector = null;
}
resultText.setText(result);
enableButtons(true);
}
new InteropTask(this, channel, testCase).execute();
}
@Override

View File

@ -1,198 +0,0 @@
/*
* Copyright 2021 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.android.integrationtest;
import static java.util.concurrent.TimeUnit.SECONDS;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
import android.util.Log;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Funnels traffic between a given UDS endpoint and a local TCP endpoint. A client binds to the UDS
* endpoint, but effectively communicates with the TCP endpoint.
*/
public class UdsTcpEndpointConnector {
private static final String LOG_TAG = "EndpointConnector";
// Discard-policy, to allow dropping tasks that were received immediately after shutDown()
private final ThreadPoolExecutor executor =
new ThreadPoolExecutor(
5,
10,
1,
SECONDS,
new LinkedBlockingQueue<>(),
new ThreadPoolExecutor.DiscardOldestPolicy());
private final String udsPath;
private final String host;
private final int port;
private InetSocketAddress socketAddress;
private LocalServerSocket clientAcceptor;
private volatile boolean shutDownRequested = false;
private volatile boolean shutDownComplete = false;
/** Listen on udsPath and forward connections to host:port. */
public UdsTcpEndpointConnector(String udsPath, String host, int port) {
this.udsPath = udsPath;
this.host = host;
this.port = port;
}
/** Start listening and accept connections. */
public void start() throws IOException {
clientAcceptor = new LocalServerSocket(udsPath);
executor.execute(
new Runnable() {
@Override
public void run() {
Log.i(LOG_TAG, "Starting connection from " + udsPath + " to " + socketAddress);
socketAddress = new InetSocketAddress(host, port);
while (!shutDownRequested) {
try {
LocalSocket clientSocket = clientAcceptor.accept();
if (shutDownRequested) {
// Check if shut down during blocking accept().
clientSocket.close();
shutDownComplete = true;
break;
}
Socket serverSocket = new Socket();
serverSocket.connect(socketAddress);
startWorkers(clientSocket, serverSocket);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
});
}
/** Stop listening and release resources. */
public void shutDown() {
Log.i(LOG_TAG, "Shutting down connection from " + udsPath + " to " + socketAddress);
shutDownRequested = true;
try {
// Upon clientAcceptor.close(), clientAcceptor.accept() continues to block.
// Thus, once shutDownRequested=true, must send a connection request to unblock accept().
LocalSocket localSocket = new LocalSocket();
localSocket.connect(clientAcceptor.getLocalSocketAddress());
localSocket.close();
clientAcceptor.close();
} catch (IOException e) {
Log.w(LOG_TAG, "Failed to close LocalServerSocket", e);
}
executor.shutdownNow();
}
public boolean isShutdown() {
return shutDownComplete && executor.isShutdown();
}
private void startWorkers(LocalSocket clientSocket, Socket serverSocket) throws IOException {
DataInputStream clientIn = new DataInputStream(clientSocket.getInputStream());
DataOutputStream clientOut = new DataOutputStream(serverSocket.getOutputStream());
DataInputStream serverIn = new DataInputStream(serverSocket.getInputStream());
DataOutputStream serverOut = new DataOutputStream(clientSocket.getOutputStream());
AtomicInteger completionCount = new AtomicInteger(0);
StreamConnector.Listener cleanupListener =
new StreamConnector.Listener() {
@Override
public void onFinished() {
if (completionCount.incrementAndGet() == 2) {
try {
serverSocket.close();
clientSocket.close();
} catch (IOException e) {
Log.e(LOG_TAG, "Failed to clean up connected sockets.", e);
}
}
}
};
executor.execute(new StreamConnector(clientIn, clientOut).addListener(cleanupListener));
executor.execute(new StreamConnector(serverIn, serverOut).addListener(cleanupListener));
}
/**
* Funnels everything that comes in to a DataInputStream into an DataOutputStream, until the
* DataInputStream is closed. (detected by IOException).
*/
private static final class StreamConnector implements Runnable {
interface Listener {
void onFinished();
}
private static final int BUFFER_SIZE = 1000;
private final DataInputStream in;
private final DataOutputStream out;
private final byte[] buffer = new byte[BUFFER_SIZE];
private boolean finished = false;
private final Collection<Listener> listeners = new ArrayList<>();
StreamConnector(DataInputStream in, DataOutputStream out) {
this.in = in;
this.out = out;
}
StreamConnector addListener(Listener listener) {
listeners.add(listener);
return this;
}
@Override
public void run() {
while (!finished) {
int bytesRead;
try {
bytesRead = in.read(buffer);
if (bytesRead == -1) {
finished = true;
out.close();
continue;
}
out.write(buffer, 0, bytesRead);
} catch (IOException e) {
finished = true;
}
}
for (StreamConnector.Listener listener : listeners) {
listener.onFinished();
}
}
}
}

View File

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#AAA" android:state_focused="false"/>
<item android:color="#000" android:state_focused="true"/>
</selector>

View File

@ -28,28 +28,6 @@
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox android:id="@+id/use_uds_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="enableUds"
android:textColor="@color/focus"
android:text="Use UDS (SSL not supported)"
tools:ignore="OnClick"
/>
<EditText
android:id="@+id/uds_proxy_edit_text"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:enabled="false"
android:inputType="text"
android:hint="Enter Unix Domain Socket Abstract Namespace Address"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -58,7 +36,6 @@
<CheckBox android:id="@+id/test_cert_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/focus"
android:text="Use Test Cert"
/>
</LinearLayout>

View File

@ -2,45 +2,43 @@ plugins {
id "maven-publish"
id "com.android.library"
id "digital.wup.android-maven-publish"
}
description = 'gRPC: Android'
android {
namespace = 'io.grpc.android'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
compileSdkVersion 34
compileSdkVersion 29
defaultConfig {
minSdkVersion 22
targetSdkVersion 33
consumerProguardFiles "proguard-rules.txt"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions { abortOnError = true }
publishing {
singleVariant('release') {
withSourcesJar()
withJavadocJar()
}
}
lintOptions { abortOnError true }
}
repositories {
google()
mavenCentral()
}
dependencies {
api project(':grpc-api')
implementation project(':grpc-core')
api project(':grpc-core')
implementation libraries.guava
testImplementation project('::grpc-okhttp')
testImplementation libraries.androidx.test.core
testImplementation libraries.junit
testImplementation libraries.robolectric
testImplementation (libraries.robolectric) {
// Unreleased change: https://github.com/robolectric/robolectric/pull/5432
exclude group: 'com.google.auto.service', module: 'auto-service'
}
testImplementation libraries.truth
}
@ -74,9 +72,10 @@ tasks.register("sourcesJar", Jar) {
publishing {
publications {
maven {
afterEvaluate {
from components.release
}
from components.android
artifact javadocJar
artifact sourcesJar
}
}
}

View File

@ -0,0 +1,6 @@
-keepclassmembers class io.grpc.okhttp.OkHttpChannelBuilder {
io.grpc.okhttp.OkHttpChannelBuilder forTarget(java.lang.String);
io.grpc.okhttp.OkHttpChannelBuilder scheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
io.grpc.okhttp.OkHttpChannelBuilder sslSocketFactory(javax.net.ssl.SSLSocketFactory);
io.grpc.okhttp.OkHttpChannelBuilder transportExecutor(java.util.concurrent.Executor);
}

View File

@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" >
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.grpc.android">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

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
@ -156,7 +156,6 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
}
@Override
@SuppressWarnings("deprecation") // Not extending ForwardingChannelBuilder2 to preserve ABI.
protected ManagedChannelBuilder<?> delegate() {
return delegateBuilder;
}
@ -217,6 +216,7 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
connectivityManager.registerDefaultNetworkCallback(defaultNetworkCallback);
unregisterRunnable =
new Runnable() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void run() {
connectivityManager.unregisterNetworkCallback(defaultNetworkCallback);
@ -230,6 +230,7 @@ public final class AndroidChannelBuilder extends ForwardingChannelBuilder<Androi
context.registerReceiver(networkReceiver, networkIntentFilter);
unregisterRunnable =
new Runnable() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void run() {
context.unregisterReceiver(networkReceiver);

View File

@ -1,95 +0,0 @@
/*
* Copyright 2021 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.android;
import android.net.LocalSocketAddress.Namespace;
import io.grpc.ChannelCredentials;
import io.grpc.ExperimentalApi;
import io.grpc.InsecureChannelCredentials;
import io.grpc.ManagedChannelBuilder;
import java.lang.reflect.InvocationTargetException;
import javax.annotation.Nullable;
import javax.net.SocketFactory;
/**
* Creates a UDS channel by passing in a specialized SocketFactory into an OkHttpChannelBuilder. The
* UdsSockets produced by this factory communicate over Android's LocalSockets.
*
* <p>Example Usage <code>
* Channel channel = UdsChannelBuilder.forPath("/data/data/my.app/app.socket",
* Namespace.FILESYSTEM).build();
* stub = MyService.newStub(channel);
* </code>
*
* <p>This class uses a safe-for-production hack to workaround NameResolver's inability to safely
* return non-IP SocketAddress types. The hack simply ignores the name resolver results and connects
* to the UDS name provided during construction instead. This class is expected to be replaced with
* a `unix:` name resolver when possible.
*/
@ExperimentalApi("A stopgap. Not intended to be stabilized")
public final class UdsChannelBuilder {
@Nullable
@SuppressWarnings("rawtypes")
private static final Class<? extends ManagedChannelBuilder> OKHTTP_CHANNEL_BUILDER_CLASS =
findOkHttp();
@SuppressWarnings("rawtypes")
private static Class<? extends ManagedChannelBuilder> findOkHttp() {
try {
return Class.forName("io.grpc.okhttp.OkHttpChannelBuilder")
.asSubclass(ManagedChannelBuilder.class);
} catch (ClassNotFoundException e) {
return null;
}
}
/**
* Returns a channel to the UDS endpoint specified by the file-path.
*
* @param path unix file system path to use for Unix Domain Socket.
* @param namespace the type of the namespace that the path belongs to.
*/
public static ManagedChannelBuilder<?> forPath(String path, Namespace namespace) {
if (OKHTTP_CHANNEL_BUILDER_CLASS == null) {
throw new UnsupportedOperationException("OkHttpChannelBuilder not found on the classpath");
}
try {
// Target 'dns:///127.0.0.1' is unused, but necessary as an argument for OkHttpChannelBuilder.
// An IP address is used instead of localhost to avoid a DNS lookup (see #11442). This should
// work even if IPv4 is unavailable, as the DNS resolver doesn't need working IPv4 to parse an
// IPv4 address. Unavailable IPv4 fails when we connect(), not at resolution time.
// TLS is unsupported because Conscrypt assumes the platform Socket implementation to improve
// performance by using the file descriptor directly.
Object o = OKHTTP_CHANNEL_BUILDER_CLASS
.getMethod("forTarget", String.class, ChannelCredentials.class)
.invoke(null, "dns:///127.0.0.1", InsecureChannelCredentials.create());
ManagedChannelBuilder<?> builder = OKHTTP_CHANNEL_BUILDER_CLASS.cast(o);
OKHTTP_CHANNEL_BUILDER_CLASS
.getMethod("socketFactory", SocketFactory.class)
.invoke(builder, new UdsSocketFactory(path, namespace));
return builder;
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to create OkHttpChannelBuilder", e);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Failed to create OkHttpChannelBuilder", e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Failed to create OkHttpChannelBuilder", e);
}
}
private UdsChannelBuilder() {}
}

View File

@ -1,312 +0,0 @@
/*
* Copyright 2021 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.android;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import java.io.FilterInputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.channels.SocketChannel;
/**
* Adapter from Android's LocalSocket to Socket. This class is only needed by grpc-okhttp, so the
* adapter only has to support the things that grcp-okhttp uses. It is fine to support trivial
* things unused by the transport, to be less likely to break as the transport usage changes, but it
* is also unnecessary. It's okay to stretch the truth or lie when necessary. For example, little
* hurts with {@link #setTcpNoDelay(boolean)} being a noop since unix domain sockets don't have such
* unnecessary delays.
*/
@SuppressWarnings("UnsynchronizedOverridesSynchronized") // Rely on LocalSocket's synchronization
class UdsSocket extends Socket {
private final LocalSocket localSocket;
private final LocalSocketAddress localSocketAddress;
@GuardedBy("this")
private boolean closed = false;
@GuardedBy("this")
private boolean inputShutdown = false;
@GuardedBy("this")
private boolean outputShutdown = false;
public UdsSocket(LocalSocketAddress localSocketAddress) {
this.localSocketAddress = localSocketAddress;
localSocket = new LocalSocket();
}
@Override
public void bind(SocketAddress bindpoint) {
// no-op
}
@Override
public synchronized void close() throws IOException {
if (closed) {
return;
}
if (!inputShutdown) {
shutdownInput();
}
if (!outputShutdown) {
shutdownOutput();
}
localSocket.close();
closed = true;
}
@Override
public void connect(SocketAddress endpoint) throws IOException {
localSocket.connect(localSocketAddress);
}
@Override
public void connect(SocketAddress endpoint, int timeout) throws IOException {
localSocket.connect(localSocketAddress, timeout);
}
@Override
public SocketChannel getChannel() {
throw new UnsupportedOperationException("getChannel() not supported");
}
@Override
public InetAddress getInetAddress() {
throw new UnsupportedOperationException("getInetAddress() not supported");
}
@Override
public InputStream getInputStream() throws IOException {
return new FilterInputStream(localSocket.getInputStream()) {
@Override
public void close() throws IOException {
UdsSocket.this.close();
}
};
}
@Override
public boolean getKeepAlive() {
throw new UnsupportedOperationException("Unsupported operation getKeepAlive()");
}
@Override
public InetAddress getLocalAddress() {
throw new UnsupportedOperationException("Unsupported operation getLocalAddress()");
}
@Override
public int getLocalPort() {
throw new UnsupportedOperationException("Unsupported operation getLocalPort()");
}
@Override
public SocketAddress getLocalSocketAddress() {
return new SocketAddress() {};
}
@Override
public boolean getOOBInline() {
throw new UnsupportedOperationException("Unsupported operation getOOBInline()");
}
@Override
public OutputStream getOutputStream() throws IOException {
return new FilterOutputStream(localSocket.getOutputStream()) {
@Override
public void close() throws IOException {
UdsSocket.this.close();
}
};
}
@Override
public int getPort() {
throw new UnsupportedOperationException("Unsupported operation getPort()");
}
@Override
public int getReceiveBufferSize() throws SocketException {
try {
return localSocket.getReceiveBufferSize();
} catch (IOException e) {
throw toSocketException(e);
}
}
@Override
public SocketAddress getRemoteSocketAddress() {
return new SocketAddress() {};
}
@Override
public boolean getReuseAddress() {
throw new UnsupportedOperationException("Unsupported operation getReuseAddress()");
}
@Override
public int getSendBufferSize() throws SocketException {
try {
return localSocket.getSendBufferSize();
} catch (IOException e) {
throw toSocketException(e);
}
}
@Override
public int getSoLinger() {
return -1; // unsupported
}
@Override
public int getSoTimeout() throws SocketException {
try {
return localSocket.getSoTimeout();
} catch (IOException e) {
throw toSocketException(e);
}
}
@Override
public boolean getTcpNoDelay() {
return true;
}
@Override
public int getTrafficClass() {
throw new UnsupportedOperationException("Unsupported operation getTrafficClass()");
}
@Override
public boolean isBound() {
return localSocket.isBound();
}
@Override
public synchronized boolean isClosed() {
return closed;
}
@Override
public boolean isConnected() {
return localSocket.isConnected();
}
@Override
public synchronized boolean isInputShutdown() {
return inputShutdown;
}
@Override
public synchronized boolean isOutputShutdown() {
return outputShutdown;
}
@Override
public void sendUrgentData(int data) {
throw new UnsupportedOperationException("Unsupported operation sendUrgentData()");
}
@Override
public void setKeepAlive(boolean on) {
throw new UnsupportedOperationException("Unsupported operation setKeepAlive()");
}
@Override
public void setOOBInline(boolean on) {
throw new UnsupportedOperationException("Unsupported operation setOOBInline()");
}
@Override
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
throw new UnsupportedOperationException("Unsupported operation setPerformancePreferences()");
}
@Override
public void setReceiveBufferSize(int size) throws SocketException {
try {
localSocket.setReceiveBufferSize(size);
} catch (IOException e) {
throw toSocketException(e);
}
}
@Override
public void setReuseAddress(boolean on) {
throw new UnsupportedOperationException("Unsupported operation setReuseAddress()");
}
@Override
public void setSendBufferSize(int size) throws SocketException {
try {
localSocket.setSendBufferSize(size);
} catch (IOException e) {
throw toSocketException(e);
}
}
@Override
public void setSoLinger(boolean on, int linger) {
throw new UnsupportedOperationException("Unsupported operation setSoLinger()");
}
@Override
public void setSoTimeout(int timeout) throws SocketException {
try {
localSocket.setSoTimeout(timeout);
} catch (IOException e) {
throw toSocketException(e);
}
}
@Override
public void setTcpNoDelay(boolean on) {
// no-op
}
@Override
public void setTrafficClass(int tc) {
throw new UnsupportedOperationException("Unsupported operation setTrafficClass()");
}
@Override
public synchronized void shutdownInput() throws IOException {
localSocket.shutdownInput();
inputShutdown = true;
}
@Override
public synchronized void shutdownOutput() throws IOException {
localSocket.shutdownOutput();
outputShutdown = true;
}
private static SocketException toSocketException(Throwable e) {
SocketException se = new SocketException();
se.initCause(e);
return se;
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright 2021 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc.android;
import android.net.LocalSocketAddress;
import android.net.LocalSocketAddress.Namespace;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import javax.net.SocketFactory;
/**
* A SocketFactory that produces {@link UdsSocket} instances. This is used to provide support for
* gRPC channels with an underlying Unix Domain Socket transport.
*/
class UdsSocketFactory extends SocketFactory {
private final LocalSocketAddress localSocketAddress;
public UdsSocketFactory(String path, Namespace namespace) {
localSocketAddress = new LocalSocketAddress(path, namespace);
}
@Override
public Socket createSocket() throws IOException {
return create();
}
@Override
public Socket createSocket(String host, int port) throws IOException {
return createAndConnect();
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
throws IOException {
return createAndConnect();
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return createAndConnect();
}
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort)
throws IOException {
return createAndConnect();
}
private Socket create() {
return new UdsSocket(localSocketAddress);
}
private Socket createAndConnect() throws IOException {
Socket socket = create();
SocketAddress unusedAddress = new InetSocketAddress(0);
socket.connect(unusedAddress);
return socket;
}
}

View File

@ -1,16 +1,16 @@
load("@rules_jvm_external//:defs.bzl", "artifact")
java_library(
name = "api",
srcs = glob([
"src/main/java/**/*.java",
"src/context/java/**/*.java",
]),
javacopts = ["-Xep:DoNotCall:OFF"], # Remove once requiring Bazel 3.4.0+; allows non-final
visibility = ["//visibility:public"],
deps = [
artifact("com.google.code.findbugs:jsr305"),
artifact("com.google.errorprone:error_prone_annotations"),
artifact("com.google.guava:failureaccess"), # future transitive dep of Guava. See #5214
artifact("com.google.guava:guava"),
"//context",
"@com_google_code_findbugs_jsr305//jar",
"@com_google_errorprone_error_prone_annotations//jar",
"@com_google_guava_failureaccess//jar", # future transitive dep of Guava. See #5214
"@com_google_guava_guava//jar",
"@com_google_j2objc_j2objc_annotations//jar",
],
)

View File

@ -1,6 +1,5 @@
plugins {
id "java-library"
id "java-test-fixtures"
id "maven-publish"
id "me.champeau.jmh"
@ -9,75 +8,27 @@ plugins {
description = 'gRPC: API'
sourceSets {
context
main {
output.classesDirs.from(sourceSets.context.output.classesDirs)
}
}
tasks.named("compileContextJava").configure {
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_20)) {
println("!!! Javac does not support generating Java 7 bytecode. Do not use for release builds !!!")
} else if (JavaVersion.current().isJava9Compatible()) {
options.release = 7
} else {
sourceCompatibility = JavaVersion.VERSION_1_7
targetCompatibility = JavaVersion.VERSION_1_7
}
}
tasks.named("jar").configure {
manifest {
attributes('Automatic-Module-Name': 'io.grpc')
}
}
evaluationDependsOn(project(':grpc-context').path)
dependencies {
compileOnly sourceSets.context.output
api libraries.jsr305,
api project(':grpc-context'),
libraries.jsr305,
libraries.errorprone.annotations
implementation libraries.guava
testFixturesApi libraries.truth
testFixturesImplementation libraries.jsr305
testFixturesImplementation libraries.guava,
libraries.junit,
libraries.mockito.core
testImplementation project(':grpc-core')
testImplementation project(':grpc-testing')
testImplementation libraries.guava.testlib
testImplementation libraries.truth
signature (libraries.signature.java) {
artifact {
extension = "signature"
}
testImplementation project(':grpc-context').sourceSets.test.output,
project(':grpc-testing'),
project(':grpc-grpclb')
testImplementation (libraries.guava.testlib) {
exclude group: 'junit', module: 'junit'
}
signature (libraries.signature.android) {
artifact {
extension = "signature"
}
}
}
jmh project(':grpc-core')
animalsniffer {
annotation = 'io.grpc.IgnoreJRERequirement'
signature libraries.signature.java
signature libraries.signature.android
}
tasks.named("javadoc").configure {
source sourceSets.context.allSource
// We want io.grpc.Internal, but not io.grpc.Internal*
exclude 'io/grpc/*MetricInstrument.java'
exclude 'io/grpc/*MetricInstrumentRegistry.java'
exclude 'io/grpc/Internal?*.java'
exclude 'io/grpc/MetricRecorder.java'
exclude 'io/grpc/MetricSink.java'
}
tasks.named("sourcesJar").configure {
from sourceSets.context.allSource
}
components.java.withVariantsFromConfiguration(configurations.testFixturesApiElements) { skip() }
components.java.withVariantsFromConfiguration(configurations.testFixturesRuntimeElements) { skip() }

View File

@ -236,12 +236,13 @@ public final class Attributes {
}
/**
* Removes the key and associated value from the attributes.
* Removes the key and associated value from the attribtues.
*
* @since 1.22.0
* @param key The key to remove
* @return this
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/5777")
public <T> Builder discard(Key<T> key) {
if (base.data.containsKey(key)) {
IdentityHashMap<Key<?>, Object> newBaseData = new IdentityHashMap<>(base.data);

View File

@ -43,7 +43,7 @@ public abstract class CallCredentials {
* <p>It is called for each individual RPC, within the {@link Context} of the call, before the
* stream is about to be created on a transport. Implementations should not block in this
* method. If metadata is not immediately available, e.g., needs to be fetched from network, the
* implementation may give the {@code appExecutor} an asynchronous task which will eventually call
* implementation may give the {@code applier} to an asynchronous task which will eventually call
* the {@code applier}. The RPC proceeds only after the {@code applier} is called.
*
* @param requestInfo request-related information
@ -56,20 +56,18 @@ public abstract class CallCredentials {
RequestInfo requestInfo, Executor appExecutor, CallCredentials.MetadataApplier applier);
/**
* With this class now being stable this method moves from an abstract one to a normal one with
* a no-op implementation. This method is marked deprecated to allow extenders time to remove the
* method before it is removed here.
* Should be a noop but never called; tries to make it clearer to implementors that they may break
* in the future.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
@Deprecated
public void thisUsesUnstableApi() {
}
public abstract void thisUsesUnstableApi();
/**
* The outlet of the produced headers. Not thread-safe.
*
* <p>Exactly one of its methods must be called to make the RPC proceed.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
public abstract static class MetadataApplier {
/**
* Called when headers are successfully generated. They will be merged into the original
@ -86,6 +84,7 @@ public abstract class CallCredentials {
/**
* The request-related information passed to {@code CallCredentials.applyRequestMetadata()}.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1914")
public abstract static class RequestInfo {
/**
* The method descriptor of this RPC.

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;
@ -81,8 +79,6 @@ public final class CallOptions {
private final Integer maxInboundMessageSize;
@Nullable
private final Integer maxOutboundMessageSize;
@Nullable
private final Integer onReadyThreshold;
private CallOptions(Builder builder) {
this.deadline = builder.deadline;
@ -95,7 +91,6 @@ public final class CallOptions {
this.waitForReady = builder.waitForReady;
this.maxInboundMessageSize = builder.maxInboundMessageSize;
this.maxOutboundMessageSize = builder.maxOutboundMessageSize;
this.onReadyThreshold = builder.onReadyThreshold;
}
static class Builder {
@ -110,7 +105,6 @@ public final class CallOptions {
Boolean waitForReady;
Integer maxInboundMessageSize;
Integer maxOutboundMessageSize;
Integer onReadyThreshold;
private CallOptions build() {
return new CallOptions(this);
@ -144,12 +138,13 @@ public final class CallOptions {
/**
* Sets the compression to use for the call. The compressor must be a valid name known in the
* {@link CompressorRegistry}. By default, the "gzip" compressor will be available.
* {@link CompressorRegistry}.
*
* <p>It is only safe to call this if the server supports the compression format chosen. There is
* no negotiation performed; if the server does not support the compression chosen, the call will
* fail.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704")
public CallOptions withCompression(@Nullable String compressorName) {
Builder builder = toBuilder(this);
builder.compressorName = compressorName;
@ -178,11 +173,6 @@ public final class CallOptions {
return withDeadline(Deadline.after(duration, unit));
}
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11657")
public CallOptions withDeadlineAfter(Duration duration) {
return withDeadlineAfter(convertToNanos(duration), TimeUnit.NANOSECONDS);
}
/**
* Returns the deadline or {@code null} if the deadline is not set.
*/
@ -214,49 +204,10 @@ public final class CallOptions {
return builder.build();
}
/**
* Specifies how many bytes must be queued before the call is
* considered not ready to send more messages.
*
* @param numBytes The number of bytes that must be queued. Must be a
* positive integer.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11021")
public CallOptions withOnReadyThreshold(int numBytes) {
checkArgument(numBytes > 0, "numBytes must be positive: %s", numBytes);
Builder builder = toBuilder(this);
builder.onReadyThreshold = numBytes;
return builder.build();
}
/**
* Resets to the default number of bytes that must be queued before the
* call will leave the <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">
* 'wait for ready'</a> state.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11021")
public CallOptions clearOnReadyThreshold() {
Builder builder = toBuilder(this);
builder.onReadyThreshold = null;
return builder.build();
}
/**
* Returns to the default number of bytes that must be queued before the
* call will leave the <a href="https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md">
* 'wait for ready'</a> state.
*
* @return null if the default threshold is used.
*/
@Nullable
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/11021")
public Integer getOnReadyThreshold() {
return onReadyThreshold;
}
/**
* Returns the compressor's name.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1704")
@Nullable
public String getCompressor() {
return compressorName;
@ -519,7 +470,6 @@ public final class CallOptions {
builder.waitForReady = other.waitForReady;
builder.maxInboundMessageSize = other.maxInboundMessageSize;
builder.maxOutboundMessageSize = other.maxOutboundMessageSize;
builder.onReadyThreshold = other.onReadyThreshold;
return builder;
}
@ -535,7 +485,6 @@ public final class CallOptions {
.add("waitForReady", isWaitForReady())
.add("maxInboundMessageSize", maxInboundMessageSize)
.add("maxOutboundMessageSize", maxOutboundMessageSize)
.add("onReadyThreshold", onReadyThreshold)
.add("streamTracerFactories", streamTracerFactories)
.toString();
}

View File

@ -1,23 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
/**
* Tagging interface for MetricInstruments that can be used with batch callbacks.
*/
@Internal
public interface CallbackMetricInstrument extends MetricInstrument {}

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
@ -270,6 +270,7 @@ public abstract class ClientCall<ReqT, RespT> {
* encoding has been negotiated, this is a no-op. By default per-message compression is enabled,
* but may not have any effect if compression is not enabled on the call.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/1703")
public void setMessageCompression(boolean enabled) {
// noop
}

View File

@ -236,11 +236,7 @@ public class ClientInterceptors {
// to a NO-OP one to prevent the IllegalStateException. The user will finally get notified
// about the error through the listener.
delegate = (ClientCall<ReqT, RespT>) NOOP_CALL;
Metadata trailers = Status.trailersFromThrowable(e);
responseListener.onClose(
Status.fromThrowable(e),
trailers != null ? trailers : new Metadata()
);
responseListener.onClose(Status.fromThrowable(e), new Metadata());
}
}
}

View File

@ -27,12 +27,6 @@ import javax.annotation.concurrent.ThreadSafe;
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/2861")
@ThreadSafe
public abstract class ClientStreamTracer extends StreamTracer {
/**
* Indicates how long the call was delayed, in nanoseconds, due to waiting for name resolution
* result. If the call option is not set, the call did not experience name resolution delay.
*/
public static final CallOptions.Key<Long> NAME_RESOLUTION_DELAYED =
CallOptions.Key.create("io.grpc.ClientStreamTracer.NAME_RESOLUTION_DELAYED");
/**
* The stream is being created on a ready transport.
@ -45,18 +39,6 @@ public abstract class ClientStreamTracer extends StreamTracer {
public void streamCreated(@Grpc.TransportAttr Attributes transportAttrs, Metadata headers) {
}
/**
* Name resolution is completed and the connection starts getting established. This method is only
* invoked on the streams that encounter such delay.
*
* </p>gRPC buffers the client call if the remote address and configurations, e.g. timeouts and
* retry policy, are not ready. Asynchronously gRPC internally does the name resolution to get
* this information. The streams that are processed immediately on ready transports by the time
* the RPC comes do not go through the pending process, thus this callback will not be invoked.
*/
public void createPendingStream() {
}
/**
* Headers has been sent to the socket.
*/
@ -70,35 +52,15 @@ public abstract class ClientStreamTracer extends StreamTracer {
}
/**
* Headers has been received from the server. This method does not pass ownership to {@code
* headers}, so implementations must not access the metadata after returning. Modifications to the
* metadata within this method will be seen by interceptors and the application.
* Trailing metadata has been received from the server.
*
* @param headers the received header metadata
*/
public void inboundHeaders(Metadata headers) {
inboundHeaders();
}
/**
* Trailing metadata has been received from the server. This method does not pass ownership to
* {@code trailers}, so implementations must not access the metadata after returning.
* Modifications to the metadata within this method will be seen by interceptors and the
* application.
*
* @param trailers the received trailing metadata
* @param trailers the mutable trailing metadata. Modifications to it will be seen by
* interceptors and the application.
* @since 1.17.0
*/
public void inboundTrailers(Metadata trailers) {
}
/**
* Information providing context to the call became available.
*/
@Internal
public void addOptionalLabel(String key, String value) {
}
/**
* Factory class for {@link ClientStreamTracer}.
*/

View File

@ -1,51 +0,0 @@
/*
* Copyright 2023 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
/**
* Listens on the client transport life-cycle events. These filters do not have the capability
* to modify the channels or transport life-cycle event behavior, but they can be useful hooks
* for transport observability. Multiple filters may be registered to the client.
*
* @since 1.62.0
*/
@ExperimentalApi("https://gitub.com/grpc/grpc-java/issues/10652")
public abstract class ClientTransportFilter {
/**
* Called when a transport is ready to accept traffic (when a connection has been established).
* The default implementation is a no-op.
*
* @param transportAttrs current transport attributes
*
* @return new transport attributes. Default implementation returns the passed-in attributes
* intact.
*/
public Attributes transportReady(Attributes transportAttrs) {
return transportAttrs;
}
/**
* Called when a transport completed shutting down. All resources have been released.
* All streams have either been closed or transferred off this transport.
* Default implementation is a no-op
*
* @param transportAttrs the effective transport attributes, which is what is returned by {@link
* #transportReady} of the last executed filter.
*/
public void transportTerminated(Attributes transportAttrs) {
}
}

View File

@ -40,6 +40,9 @@ public final class CompositeCallCredentials extends CallCredentials {
new WrappingMetadataApplier(requestInfo, appExecutor, applier, Context.current()));
}
@Override
public void thisUsesUnstableApi() {}
private final class WrappingMetadataApplier extends MetadataApplier {
private final RequestInfo requestInfo;
private final Executor appExecutor;

View File

@ -1,36 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
/**
* Provides hooks for modifying gRPC channels and servers during their construction.
*/
interface Configurator {
/**
* Allows implementations to modify the channel builder.
*
* @param channelBuilder the channel builder being constructed
*/
default void configureChannelBuilder(ManagedChannelBuilder<?> channelBuilder) {}
/**
* Allows implementations to modify the server builder.
*
* @param serverBuilder the server builder being constructed
*/
default void configureServerBuilder(ServerBuilder<?> serverBuilder) {}
}

View File

@ -1,87 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A registry for {@link Configurator} instances.
*
* <p>This class is responsible for maintaining a list of configurators and providing access to
* them. The default registry can be obtained using {@link #getDefaultRegistry()}.
*/
final class ConfiguratorRegistry {
private static ConfiguratorRegistry instance;
@GuardedBy("this")
private boolean wasConfiguratorsSet;
@GuardedBy("this")
private List<Configurator> configurators = Collections.emptyList();
@GuardedBy("this")
private int configuratorsCallCountBeforeSet = 0;
ConfiguratorRegistry() {}
/**
* Returns the default global instance of the configurator registry.
*/
public static synchronized ConfiguratorRegistry getDefaultRegistry() {
if (instance == null) {
instance = new ConfiguratorRegistry();
}
return instance;
}
/**
* Sets the configurators in this registry. This method can only be called once.
*
* @param configurators the configurators to set
* @throws IllegalStateException if this method is called more than once
*/
public synchronized void setConfigurators(List<? extends Configurator> configurators) {
if (wasConfiguratorsSet) {
throw new IllegalStateException("Configurators are already set");
}
this.configurators = Collections.unmodifiableList(new ArrayList<>(configurators));
wasConfiguratorsSet = true;
}
/**
* Returns a list of the configurators in this registry.
*/
public synchronized List<Configurator> getConfigurators() {
if (!wasConfiguratorsSet) {
configuratorsCallCountBeforeSet++;
}
return configurators;
}
/**
* Returns the number of times getConfigurators() was called before
* setConfigurators() was successfully invoked.
*/
public synchronized int getConfiguratorsCallCountBeforeSet() {
return configuratorsCallCountBeforeSet;
}
public synchronized boolean wasSetConfiguratorsCalled() {
return wasConfiguratorsSet;
}
}

View File

@ -32,6 +32,7 @@ import java.io.InputStream;
* with {@link HasByteBuffer}, a custom {@link io.grpc.MethodDescriptor.Marshaller} can take
* over the ownership of buffers containing inbound data and perform delayed deserialization.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7387")
public interface Detachable {
/**

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.util.List;
/**
* Represents a double-valued counter metric instrument.
*/
@Internal
public final class DoubleCounterMetricInstrument extends PartialMetricInstrument {
public DoubleCounterMetricInstrument(int index, String name, String description, String unit,
List<String> requiredLabelKeys, List<String> optionalLabelKeys, boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
}
}

View File

@ -1,38 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import java.util.List;
/**
* Represents a double-valued histogram metric instrument.
*/
@Internal
public final class DoubleHistogramMetricInstrument extends PartialMetricInstrument {
private final List<Double> bucketBoundaries;
public DoubleHistogramMetricInstrument(int index, String name, String description, String unit,
List<Double> bucketBoundaries, List<String> requiredLabelKeys, List<String> optionalLabelKeys,
boolean enableByDefault) {
super(index, name, description, unit, requiredLabelKeys, optionalLabelKeys, enableByDefault);
this.bucketBoundaries = bucketBoundaries;
}
public List<Double> getBucketBoundaries() {
return bucketBoundaries;
}
}

View File

@ -128,9 +128,6 @@ public final class EquivalentAddressGroup {
*/
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof EquivalentAddressGroup)) {
return false;
}

View File

@ -16,6 +16,8 @@
package io.grpc;
import com.google.common.base.MoreObjects;
import com.google.errorprone.annotations.DoNotCall;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
@ -26,39 +28,38 @@ import javax.annotation.Nullable;
* A {@link ManagedChannelBuilder} that delegates all its builder methods to another builder by
* default.
*
* <p>DEPRECATED: Use {@link ForwardingChannelBuilder2} instead!
*
* <p>This class mistakenly used {@code <T extends ForwardingChannelBuilder<T>>} which causes
* return types to be {@link ForwardingChannelBuilder} instead of {@link ManagedChannelBuilder}.
* This pollutes the ABI of its subclasses with undesired method signatures.
* {@link ForwardingChannelBuilder2} generates correct return types; use it instead.
*
* @param <T> The type of the subclass extending this abstract class.
*
* @since 1.7.0
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/3363")
public abstract class ForwardingChannelBuilder<T extends ForwardingChannelBuilder<T>>
extends ForwardingChannelBuilder2<T> {
extends ManagedChannelBuilder<T> {
/**
* The default constructor.
*/
protected ForwardingChannelBuilder() {
protected ForwardingChannelBuilder() {}
/**
* This method serves to force sub classes to "hide" this static factory.
*/
@DoNotCall("Unsupported")
public static ManagedChannelBuilder<?> forAddress(String name, int port) {
throw new UnsupportedOperationException("Subclass failed to hide static factory");
}
/**
* This method serves to force sub classes to "hide" this static factory.
*/
@DoNotCall("Unsupported")
public static ManagedChannelBuilder<?> forTarget(String target) {
throw new UnsupportedOperationException("Subclass failed to hide static factory");
}
/**
* Returns the delegated {@code ManagedChannelBuilder}.
*
* <p>NOTE: this method is marked deprecated instead the class itself, so that classes extending
* {@link ForwardingChannelBuilder2} won't need class-level
* {@code @SuppressWarnings("deprecation")} annotation. Such annotation would suppress all
* deprecation warnings in all methods, inadvertently hiding any real deprecation warnings needing
* to be addressed. However, each child class is expected to implement {@code delegate()}.
* Therefore, the {@code @Deprecated} annotation is added to this method, and not to the class.
*
* @deprecated As of 1.60.0, use {@link ForwardingChannelBuilder2} instead.
*/
@Override
@Deprecated
protected abstract ManagedChannelBuilder<?> delegate();
@Override
@ -128,6 +129,12 @@ public abstract class ForwardingChannelBuilder<T extends ForwardingChannelBuilde
return thisT();
}
@Override
public T enableFullStreamDecompression() {
delegate().enableFullStreamDecompression();
return thisT();
}
@Override
public T decompressorRegistry(DecompressorRegistry registry) {
delegate().decompressorRegistry(registry);
@ -242,10 +249,24 @@ public abstract class ForwardingChannelBuilder<T extends ForwardingChannelBuilde
return thisT();
}
/**
* Returns the {@link ManagedChannel} built by the delegate by default. Overriding method can
* return different value.
*/
@Override
public ManagedChannel build() {
return delegate().build();
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("delegate", delegate()).toString();
}
/**
* Returns the correctly typed version of the builder.
*/
private T thisT() {
protected final T thisT() {
@SuppressWarnings("unchecked")
T thisT = (T) this;
return thisT;

View File

@ -30,6 +30,7 @@ import javax.annotation.Nullable;
* @param <T> The type of the subclass extending this abstract class.
* @since 1.34.0
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7393")
public abstract class ForwardingServerBuilder<T extends ServerBuilder<T>> extends ServerBuilder<T> {
/** The default constructor. */

View File

@ -0,0 +1,93 @@
/*
* Copyright 2022 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/** The collection of global interceptors and global server stream tracers. */
@Internal
final class GlobalInterceptors {
private static List<ClientInterceptor> clientInterceptors = null;
private static List<ServerInterceptor> serverInterceptors = null;
private static List<ServerStreamTracer.Factory> serverStreamTracerFactories =
null;
private static boolean isGlobalInterceptorsTracersSet;
private static boolean isGlobalInterceptorsTracersGet;
// Prevent instantiation
private GlobalInterceptors() {}
/**
* Sets the list of global interceptors and global server stream tracers.
*
* <p>If {@code setInterceptorsTracers()} is called again, this method will throw {@link
* IllegalStateException}.
*
* <p>It is only safe to call early. This method throws {@link IllegalStateException} after any of
* the get calls [{@link #getClientInterceptors()}, {@link #getServerInterceptors()} or {@link
* #getServerStreamTracerFactories()}] has been called, in order to limit changes to the result of
* {@code setInterceptorsTracers()}.
*
* @param clientInterceptorList list of {@link ClientInterceptor} that make up global Client
* Interceptors.
* @param serverInterceptorList list of {@link ServerInterceptor} that make up global Server
* Interceptors.
* @param serverStreamTracerFactoryList list of {@link ServerStreamTracer.Factory} that make up
* global ServerStreamTracer factories.
*/
static synchronized void setInterceptorsTracers(
List<ClientInterceptor> clientInterceptorList,
List<ServerInterceptor> serverInterceptorList,
List<ServerStreamTracer.Factory> serverStreamTracerFactoryList) {
if (isGlobalInterceptorsTracersGet) {
throw new IllegalStateException("Set cannot be called after any get call");
}
if (isGlobalInterceptorsTracersSet) {
throw new IllegalStateException("Global interceptors and tracers are already set");
}
checkNotNull(clientInterceptorList);
checkNotNull(serverInterceptorList);
checkNotNull(serverStreamTracerFactoryList);
clientInterceptors = Collections.unmodifiableList(new ArrayList<>(clientInterceptorList));
serverInterceptors = Collections.unmodifiableList(new ArrayList<>(serverInterceptorList));
serverStreamTracerFactories =
Collections.unmodifiableList(new ArrayList<>(serverStreamTracerFactoryList));
isGlobalInterceptorsTracersSet = true;
}
/** Returns the list of global {@link ClientInterceptor}. If not set, this returns null. */
static synchronized List<ClientInterceptor> getClientInterceptors() {
isGlobalInterceptorsTracersGet = true;
return clientInterceptors;
}
/** Returns list of global {@link ServerInterceptor}. If not set, this returns null. */
static synchronized List<ServerInterceptor> getServerInterceptors() {
isGlobalInterceptorsTracersGet = true;
return serverInterceptors;
}
/** Returns list of global {@link ServerStreamTracer.Factory}. If not set, this returns null. */
static synchronized List<ServerStreamTracer.Factory> getServerStreamTracerFactories() {
isGlobalInterceptorsTracersGet = true;
return serverStreamTracerFactories;
}
}

View File

@ -28,6 +28,7 @@ import javax.annotation.Nullable;
* interface from an {@link java.io.InputStream} to {@link ByteBuffer}s, without copying the
* content to a byte array and read from it.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7387")
public interface HasByteBuffer {
/**

View File

@ -28,6 +28,7 @@ import javax.annotation.Nullable;
/**
* An {@link ProxiedSocketAddress} for making a connection to an endpoint via an HTTP CONNECT proxy.
*/
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/5279")
public final class HttpConnectProxiedSocketAddress extends ProxiedSocketAddress {
private static final long serialVersionUID = 0L;

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

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

View File

@ -1,55 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import java.util.List;
/**
* Access internal global configurators.
*/
@Internal
public final class InternalConfiguratorRegistry {
private InternalConfiguratorRegistry() {}
public static void setConfigurators(List<InternalConfigurator> configurators) {
ConfiguratorRegistry.getDefaultRegistry().setConfigurators(configurators);
}
public static List<?> getConfigurators() {
return ConfiguratorRegistry.getDefaultRegistry().getConfigurators();
}
public static void configureChannelBuilder(ManagedChannelBuilder<?> channelBuilder) {
for (Configurator configurator : ConfiguratorRegistry.getDefaultRegistry().getConfigurators()) {
configurator.configureChannelBuilder(channelBuilder);
}
}
public static void configureServerBuilder(ServerBuilder<?> serverBuilder) {
for (Configurator configurator : ConfiguratorRegistry.getDefaultRegistry().getConfigurators()) {
configurator.configureServerBuilder(serverBuilder);
}
}
public static boolean wasSetConfiguratorsCalled() {
return ConfiguratorRegistry.getDefaultRegistry().wasSetConfiguratorsCalled();
}
public static int getConfiguratorsCallCountBeforeSet() {
return ConfiguratorRegistry.getDefaultRegistry().getConfiguratorsCallCountBeforeSet();
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright 2022 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
import java.util.List;
/** Accessor to internal methods of {@link GlobalInterceptors}. */
@Internal
public final class InternalGlobalInterceptors {
public static void setInterceptorsTracers(
List<ClientInterceptor> clientInterceptorList,
List<ServerInterceptor> serverInterceptorList,
List<ServerStreamTracer.Factory> serverStreamTracerFactoryList) {
GlobalInterceptors.setInterceptorsTracers(
clientInterceptorList, serverInterceptorList, serverStreamTracerFactoryList);
}
public static List<ClientInterceptor> getClientInterceptors() {
return GlobalInterceptors.getClientInterceptors();
}
public static List<ServerInterceptor> getServerInterceptors() {
return GlobalInterceptors.getServerInterceptors();
}
public static List<ServerStreamTracer.Factory> getServerStreamTracerFactories() {
return GlobalInterceptors.getServerStreamTracerFactories();
}
private InternalGlobalInterceptors() {}
}

View File

@ -1,37 +0,0 @@
/*
* Copyright 2024 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.grpc;
/**
* Internal accessors for {@link ManagedChannelBuilder}.
*/
@Internal
public final class InternalManagedChannelBuilder {
private InternalManagedChannelBuilder() {}
public static <T extends ManagedChannelBuilder<T>> T interceptWithTarget(
ManagedChannelBuilder<T> builder, InternalInterceptorFactory factory) {
return builder.interceptWithTarget(factory);
}
public static <T extends ManagedChannelBuilder<T>> T addMetricSink(
ManagedChannelBuilder<T> builder, MetricSink metricSink) {
return builder.addMetricSink(metricSink);
}
public interface InternalInterceptorFactory extends ManagedChannelBuilder.InterceptorFactory {}
}

View File

@ -30,12 +30,10 @@ public final class InternalMethodDescriptor {
this.transport = checkNotNull(transport, "transport");
}
@SuppressWarnings("EnumOrdinal")
public Object geRawMethodName(MethodDescriptor<?, ?> descriptor) {
return descriptor.getRawMethodName(transport.ordinal());
}
@SuppressWarnings("EnumOrdinal")
public void setRawMethodName(MethodDescriptor<?, ?> descriptor, Object o) {
descriptor.setRawMethodName(transport.ordinal(), o);
}

Some files were not shown because too many files have changed in this diff Show More